Source Code
Latest 25 from a total of 114,682 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Transfer | 24551747 | 43 mins ago | IN | 0 ETH | 0.00004014 | ||||
| Transfer | 24551417 | 1 hr ago | IN | 0 ETH | 0.00000309 | ||||
| Transfer | 24551294 | 2 hrs ago | IN | 0 ETH | 0.00004528 | ||||
| Approve | 24551148 | 2 hrs ago | IN | 0 ETH | 0.00000386 | ||||
| Transfer | 24550965 | 3 hrs ago | IN | 0 ETH | 0.00000265 | ||||
| Transfer | 24550927 | 3 hrs ago | IN | 0 ETH | 0.00000272 | ||||
| Transfer | 24550867 | 3 hrs ago | IN | 0 ETH | 0.00007668 | ||||
| Transfer | 24550682 | 4 hrs ago | IN | 0 ETH | 0.00000156 | ||||
| Transfer | 24550662 | 4 hrs ago | IN | 0 ETH | 0.00000313 | ||||
| Approve | 24549871 | 6 hrs ago | IN | 0 ETH | 0.00000863 | ||||
| Transfer | 24549732 | 7 hrs ago | IN | 0 ETH | 0.00000778 | ||||
| Approve | 24549613 | 7 hrs ago | IN | 0 ETH | 0.000006 | ||||
| Approve | 24549612 | 7 hrs ago | IN | 0 ETH | 0.00000904 | ||||
| Approve | 24549256 | 9 hrs ago | IN | 0 ETH | 0.00000922 | ||||
| Transfer | 24549001 | 9 hrs ago | IN | 0 ETH | 0.00000646 | ||||
| Transfer | 24548969 | 10 hrs ago | IN | 0 ETH | 0.00001739 | ||||
| Approve | 24548735 | 10 hrs ago | IN | 0 ETH | 0.0000088 | ||||
| Approve | 24548665 | 11 hrs ago | IN | 0 ETH | 0.00001496 | ||||
| Transfer | 24548618 | 11 hrs ago | IN | 0 ETH | 0.00000585 | ||||
| Approve | 24548350 | 12 hrs ago | IN | 0 ETH | 0.00000964 | ||||
| Approve | 24548267 | 12 hrs ago | IN | 0 ETH | 0.00000699 | ||||
| Transfer | 24548253 | 12 hrs ago | IN | 0 ETH | 0.00001006 | ||||
| Approve | 24548201 | 12 hrs ago | IN | 0 ETH | 0.0000121 | ||||
| Transfer | 24547831 | 13 hrs ago | IN | 0 ETH | 0.0000041 | ||||
| Transfer | 24547636 | 14 hrs ago | IN | 0 ETH | 0.00000466 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
RaylsToken
Compiler Version
v0.8.26+commit.8a97fa7a
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2024-09-16
*/
// File: @openzeppelin/contracts/token/ERC20/IERC20.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) 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 a `value` amount of tokens 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 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @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);
}
// File: @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.20;
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Storage of the initializable contract.
*
* It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
* when using with upgradeable contracts.
*
* @custom:storage-location erc7201:openzeppelin.storage.Initializable
*/
struct InitializableStorage {
/**
* @dev Indicates that the contract has been initialized.
*/
uint64 _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool _initializing;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
/**
* @dev The contract is already initialized.
*/
error InvalidInitialization();
/**
* @dev The contract is not initializing.
*/
error NotInitializing();
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint64 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
* number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
* production.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
// Cache values to avoid duplicated sloads
bool isTopLevelCall = !$._initializing;
uint64 initialized = $._initialized;
// Allowed calls:
// - initialSetup: the contract is not in the initializing state and no previous version was
// initialized
// - construction: the contract is initialized at version 1 (no reininitialization) and the
// current contract is just being deployed
bool initialSetup = initialized == 0 && isTopLevelCall;
bool construction = initialized == 1 && address(this).code.length == 0;
if (!initialSetup && !construction) {
revert InvalidInitialization();
}
$._initialized = 1;
if (isTopLevelCall) {
$._initializing = true;
}
_;
if (isTopLevelCall) {
$._initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint64 version) {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing || $._initialized >= version) {
revert InvalidInitialization();
}
$._initialized = version;
$._initializing = true;
_;
$._initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
_checkInitializing();
_;
}
/**
* @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
*/
function _checkInitializing() internal view virtual {
if (!_isInitializing()) {
revert NotInitializing();
}
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing) {
revert InvalidInitialization();
}
if ($._initialized != type(uint64).max) {
$._initialized = type(uint64).max;
emit Initialized(type(uint64).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint64) {
return _getInitializableStorage()._initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _getInitializableStorage()._initializing;
}
/**
* @dev Returns a pointer to the storage namespace.
*/
// solhint-disable-next-line var-name-mixedcase
function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
assembly {
$.slot := INITIALIZABLE_STORAGE
}
}
}
// File: @openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
// File: @openzeppelin/contracts/interfaces/draft-IERC6093.sol
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard ERC20 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.
*/
interface IERC20Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC20InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC20InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC20InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/
error ERC20InvalidSpender(address spender);
}
/**
* @dev Standard ERC721 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.
*/
interface IERC721Errors {
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/
error ERC721InvalidOwner(address owner);
/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/
error ERC721NonexistentToken(uint256 tokenId);
/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC721InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC721InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC721InsufficientApproval(address operator, uint256 tokenId);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC721InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC721InvalidOperator(address operator);
}
/**
* @dev Standard ERC1155 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.
*/
interface IERC1155Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC1155InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC1155InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param owner Address of the current owner of a token.
*/
error ERC1155MissingApprovalForAll(address operator, address owner);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC1155InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC1155InvalidOperator(address operator);
/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}
// File: @openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.20;
/**
* @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}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*/
abstract contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20, IERC20Metadata, IERC20Errors {
/// @custom:storage-location erc7201:openzeppelin.storage.ERC20
struct ERC20Storage {
mapping(address account => uint256) _balances;
mapping(address account => mapping(address spender => uint256)) _allowances;
uint256 _totalSupply;
string _name;
string _symbol;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ERC20")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant ERC20StorageLocation = 0x52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00;
function _getERC20Storage() private pure returns (ERC20Storage storage $) {
assembly {
$.slot := ERC20StorageLocation
}
}
/**
* @dev Sets the values for {name} and {symbol}.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {
__ERC20_init_unchained(name_, symbol_);
}
function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {
ERC20Storage storage $ = _getERC20Storage();
$._name = name_;
$._symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual returns (string memory) {
ERC20Storage storage $ = _getERC20Storage();
return $._name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual returns (string memory) {
ERC20Storage storage $ = _getERC20Storage();
return $._symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual returns (uint256) {
ERC20Storage storage $ = _getERC20Storage();
return $._totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual returns (uint256) {
ERC20Storage storage $ = _getERC20Storage();
return $._balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `value`.
*/
function transfer(address to, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_transfer(owner, to, value);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual returns (uint256) {
ERC20Storage storage $ = _getERC20Storage();
return $._allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, value);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `value`.
* - the caller must have allowance for ``from``'s tokens of at least
* `value`.
*/
function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, value);
_transfer(from, to, value);
return true;
}
/**
* @dev Moves a `value` amount of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _transfer(address from, address to, uint256 value) internal {
if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}
if (to == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(from, to, value);
}
/**
* @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
* (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
* this function.
*
* Emits a {Transfer} event.
*/
function _update(address from, address to, uint256 value) internal virtual {
ERC20Storage storage $ = _getERC20Storage();
if (from == address(0)) {
// Overflow check required: The rest of the code assumes that totalSupply never overflows
$._totalSupply += value;
} else {
uint256 fromBalance = $._balances[from];
if (fromBalance < value) {
revert ERC20InsufficientBalance(from, fromBalance, value);
}
unchecked {
// Overflow not possible: value <= fromBalance <= totalSupply.
$._balances[from] = fromBalance - value;
}
}
if (to == address(0)) {
unchecked {
// Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
$._totalSupply -= value;
}
} else {
unchecked {
// Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
$._balances[to] += value;
}
}
emit Transfer(from, to, value);
}
/**
* @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
* Relies on the `_update` mechanism
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _mint(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(address(0), account, value);
}
/**
* @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
* Relies on the `_update` mechanism.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead
*/
function _burn(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidSender(address(0));
}
_update(account, address(0), value);
}
/**
* @dev Sets `value` 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.
*
* Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
*/
function _approve(address owner, address spender, uint256 value) internal {
_approve(owner, spender, value, true);
}
/**
* @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
*
* By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
* `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
* `Approval` event during `transferFrom` operations.
*
* Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
* true using the following override:
* ```
* function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
* super._approve(owner, spender, value, true);
* }
* ```
*
* Requirements are the same as {_approve}.
*/
function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
ERC20Storage storage $ = _getERC20Storage();
if (owner == address(0)) {
revert ERC20InvalidApprover(address(0));
}
if (spender == address(0)) {
revert ERC20InvalidSpender(address(0));
}
$._allowances[owner][spender] = value;
if (emitEvent) {
emit Approval(owner, spender, value);
}
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `value`.
*
* Does not update the allowance value in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Does not emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
if (currentAllowance < value) {
revert ERC20InsufficientAllowance(spender, currentAllowance, value);
}
unchecked {
_approve(owner, spender, currentAllowance - value, false);
}
}
}
}
// File: @openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Burnable.sol)
pragma solidity ^0.8.20;
/**
* @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 {
}
function __ERC20Burnable_init_unchained() internal onlyInitializing {
}
/**
* @dev Destroys a `value` amount of tokens from the caller.
*
* See {ERC20-_burn}.
*/
function burn(uint256 value) public virtual {
_burn(_msgSender(), value);
}
/**
* @dev Destroys a `value` amount of 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
* `value`.
*/
function burnFrom(address account, uint256 value) public virtual {
_spendAllowance(account, _msgSender(), value);
_burn(account, value);
}
}
// File: @openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol)
pragma solidity ^0.8.20;
/**
* @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 {
/// @custom:storage-location erc7201:openzeppelin.storage.Pausable
struct PausableStorage {
bool _paused;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Pausable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant PausableStorageLocation = 0xcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300;
function _getPausableStorage() private pure returns (PausableStorage storage $) {
assembly {
$.slot := PausableStorageLocation
}
}
/**
* @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);
/**
* @dev The operation failed because the contract is paused.
*/
error EnforcedPause();
/**
* @dev The operation failed because the contract is not paused.
*/
error ExpectedPause();
/**
* @dev Initializes the contract in unpaused state.
*/
function __Pausable_init() internal onlyInitializing {
__Pausable_init_unchained();
}
function __Pausable_init_unchained() internal onlyInitializing {
PausableStorage storage $ = _getPausableStorage();
$._paused = false;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
PausableStorage storage $ = _getPausableStorage();
return $._paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
if (paused()) {
revert EnforcedPause();
}
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
if (!paused()) {
revert ExpectedPause();
}
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
PausableStorage storage $ = _getPausableStorage();
$._paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
PausableStorage storage $ = _getPausableStorage();
$._paused = false;
emit Unpaused(_msgSender());
}
}
// File: @openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Pausable.sol)
pragma solidity ^0.8.20;
/**
* @dev ERC20 token with pausable token transfers, minting and burning.
*
* Useful for scenarios such as preventing trades until the end of an evaluation
* period, or having an emergency switch for freezing all token transfers in the
* event of a large bug.
*
* IMPORTANT: This contract does not include public pause and unpause functions. In
* addition to inheriting this contract, you must define both functions, invoking the
* {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate
* access control, e.g. using {AccessControl} or {Ownable}. Not doing so will
* make the contract pause mechanism of the contract unreachable, and thus unusable.
*/
abstract contract ERC20PausableUpgradeable is Initializable, ERC20Upgradeable, PausableUpgradeable {
function __ERC20Pausable_init() internal onlyInitializing {
__Pausable_init_unchained();
}
function __ERC20Pausable_init_unchained() internal onlyInitializing {
}
/**
* @dev See {ERC20-_update}.
*
* Requirements:
*
* - the contract must not be paused.
*/
function _update(address from, address to, uint256 value) internal virtual override whenNotPaused {
super._update(from, to, value);
}
}
// File: @openzeppelin/contracts/access/IAccessControl.sol
// OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol)
pragma solidity ^0.8.20;
/**
* @dev External interface of AccessControl declared to support ERC165 detection.
*/
interface IAccessControl {
/**
* @dev The `account` is missing a role.
*/
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
/**
* @dev The caller of a function is not the expected one.
*
* NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
*/
error AccessControlBadConfirmation();
/**
* @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.
*/
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 `callerConfirmation`.
*/
function renounceRole(bytes32 role, address callerConfirmation) external;
}
// File: @openzeppelin/contracts/utils/introspection/IERC165.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @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 IERC165 {
/**
* @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);
}
// File: @openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
/**
* @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);
* }
* ```
*/
abstract contract ERC165Upgradeable is Initializable, IERC165 {
function __ERC165_init() internal onlyInitializing {
}
function __ERC165_init_unchained() internal onlyInitializing {
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
// File: @openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)
pragma solidity ^0.8.20;
/**
* @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:
*
* ```solidity
* 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}:
*
* ```solidity
* 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. We recommend using {AccessControlDefaultAdminRules}
* to enforce additional security measures for this role.
*/
abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControl, ERC165Upgradeable {
struct RoleData {
mapping(address account => bool) hasRole;
bytes32 adminRole;
}
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/// @custom:storage-location erc7201:openzeppelin.storage.AccessControl
struct AccessControlStorage {
mapping(bytes32 role => RoleData) _roles;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.AccessControl")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant AccessControlStorageLocation = 0x02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800;
function _getAccessControlStorage() private pure returns (AccessControlStorage storage $) {
assembly {
$.slot := AccessControlStorageLocation
}
}
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with an {AccessControlUnauthorizedAccount} error including the required role.
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
function __AccessControl_init() internal onlyInitializing {
}
function __AccessControl_init_unchained() internal onlyInitializing {
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view virtual returns (bool) {
AccessControlStorage storage $ = _getAccessControlStorage();
return $._roles[role].hasRole[account];
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
* is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
* is missing `role`.
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert AccessControlUnauthorizedAccount(account, role);
}
}
/**
* @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 virtual returns (bytes32) {
AccessControlStorage storage $ = _getAccessControlStorage();
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.
*
* May emit a {RoleGranted} event.
*/
function grantRole(bytes32 role, address account) public virtual 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.
*
* May emit a {RoleRevoked} event.
*/
function revokeRole(bytes32 role, address account) public virtual 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 `callerConfirmation`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address callerConfirmation) public virtual {
if (callerConfirmation != _msgSender()) {
revert AccessControlBadConfirmation();
}
_revokeRole(role, callerConfirmation);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
AccessControlStorage storage $ = _getAccessControlStorage();
bytes32 previousAdminRole = getRoleAdmin(role);
$._roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
AccessControlStorage storage $ = _getAccessControlStorage();
if (!hasRole(role, account)) {
$._roles[role].hasRole[account] = true;
emit RoleGranted(role, account, _msgSender());
return true;
} else {
return false;
}
}
/**
* @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
AccessControlStorage storage $ = _getAccessControlStorage();
if (hasRole(role, account)) {
$._roles[role].hasRole[account] = false;
emit RoleRevoked(role, account, _msgSender());
return true;
} else {
return false;
}
}
}
// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
// File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol)
pragma solidity ^0.8.20;
/**
* @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 ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS
}
/**
* @dev The signature derives the `address(0)`.
*/
error ECDSAInvalidSignature();
/**
* @dev The signature has an invalid length.
*/
error ECDSAInvalidSignatureLength(uint256 length);
/**
* @dev The signature has an S value that is in the upper half order.
*/
error ECDSAInvalidSignatureS(bytes32 s);
/**
* @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not
* return address(0) without also returning an error description. Errors are documented using an enum (error type)
* and a bytes32 providing additional information about the error.
*
* If no error is returned, then the address can be used for verification purposes.
*
* The `ecrecover` EVM precompile 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 {MessageHashUtils-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]
*/
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
/// @solidity memory-safe-assembly
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else {
return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM precompile 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 {MessageHashUtils-toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);
_throwError(error, errorArg);
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]
*/
function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) {
unchecked {
bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
// We do not check for an overflow here since the shift operation results in 0 or 1.
uint8 v = uint8((uint256(vs) >> 255) + 27);
return tryRecover(hash, v, r, s);
}
}
/**
* @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
*/
function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address, RecoverError, bytes32) {
// 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, s);
}
// 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, bytes32(0));
}
return (signer, RecoverError.NoError, bytes32(0));
}
/**
* @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, bytes32 errorArg) = tryRecover(hash, v, r, s);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.
*/
function _throwError(RecoverError error, bytes32 errorArg) private pure {
if (error == RecoverError.NoError) {
return; // no error: do nothing
} else if (error == RecoverError.InvalidSignature) {
revert ECDSAInvalidSignature();
} else if (error == RecoverError.InvalidSignatureLength) {
revert ECDSAInvalidSignatureLength(uint256(errorArg));
} else if (error == RecoverError.InvalidSignatureS) {
revert ECDSAInvalidSignatureS(errorArg);
}
}
}
// File: @openzeppelin/contracts/utils/math/Math.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
/**
* @dev Muldiv operation overflow.
*/
error MathOverflowedMulDiv();
enum Rounding {
Floor, // Toward negative infinity
Ceil, // Toward positive infinity
Trunc, // Toward zero
Expand // Away from zero
}
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @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 towards infinity instead
* of rounding towards zero.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
if (b == 0) {
// Guarantee the same behavior as in a regular Solidity division.
return a / b;
}
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
* denominator == 0.
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by
* Uniswap Labs also under MIT license.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0 = x * y; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
if (denominator <= prod1) {
revert MathOverflowedMulDiv();
}
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator.
// Always >= 1. See https://cs.stackexchange.com/q/138556/92363.
uint256 twos = denominator & (0 - denominator);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
// works in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
* towards zero.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2 of a positive value rounded towards zero.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10 of a positive value rounded towards zero.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256 of a positive value rounded towards zero.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
}
}
/**
* @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
*/
function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
return uint8(rounding) % 2 == 1;
}
}
// File: @openzeppelin/contracts/utils/math/SignedMath.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard signed math utilities missing in the Solidity language.
*/
library SignedMath {
/**
* @dev Returns the largest of two signed numbers.
*/
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two signed numbers.
*/
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two signed numbers without overflow.
* The result is rounded towards zero.
*/
function average(int256 a, int256 b) internal pure returns (int256) {
// Formula from the book "Hacker's Delight"
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
/**
* @dev Returns the absolute unsigned value of a signed value.
*/
function abs(int256 n) internal pure returns (uint256) {
unchecked {
// must be unchecked in order to support `n = type(int256).min`
return uint256(n >= 0 ? n : -n);
}
}
}
// File: @openzeppelin/contracts/utils/Strings.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)
pragma solidity ^0.8.20;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant HEX_DIGITS = "0123456789abcdef";
uint8 private constant ADDRESS_LENGTH = 20;
/**
* @dev The `value` string doesn't fit in the specified `length`.
*/
error StringsInsufficientHexLength(uint256 value, uint256 length);
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `int256` to its ASCII `string` decimal representation.
*/
function toStringSigned(int256 value) internal pure returns (string memory) {
return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value)));
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
uint256 localValue = value;
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_DIGITS[localValue & 0xf];
localValue >>= 4;
}
if (localValue != 0) {
revert StringsInsufficientHexLength(value, length);
}
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal
* representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);
}
/**
* @dev Returns true if the two strings are equal.
*/
function equal(string memory a, string memory b) internal pure returns (bool) {
return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));
}
}
// File: @openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MessageHashUtils.sol)
pragma solidity ^0.8.20;
/**
* @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing.
*
* The library provides methods for generating a hash of a message that conforms to the
* https://eips.ethereum.org/EIPS/eip-191[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712]
* specifications.
*/
library MessageHashUtils {
/**
* @dev Returns the keccak256 digest of an EIP-191 signed data with version
* `0x45` (`personal_sign` messages).
*
* The digest is calculated by prefixing a bytes32 `messageHash` with
* `"\x19Ethereum Signed Message:\n32"` and hashing the result. It corresponds with the
* hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.
*
* NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with
* keccak256, although any bytes32 value can be safely used because the final digest will
* be re-hashed.
*
* See {ECDSA-recover}.
*/
function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, "\x19Ethereum Signed Message:\n32") // 32 is the bytes-length of messageHash
mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix
digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20)
}
}
/**
* @dev Returns the keccak256 digest of an EIP-191 signed data with version
* `0x45` (`personal_sign` messages).
*
* The digest is calculated by prefixing an arbitrary `message` with
* `"\x19Ethereum Signed Message:\n" + len(message)` and hashing the result. It corresponds with the
* hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.
*
* See {ECDSA-recover}.
*/
function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) {
return
keccak256(bytes.concat("\x19Ethereum Signed Message:\n", bytes(Strings.toString(message.length)), message));
}
/**
* @dev Returns the keccak256 digest of an EIP-191 signed data with version
* `0x00` (data with intended validator).
*
* The digest is calculated by prefixing an arbitrary `data` with `"\x19\x00"` and the intended
* `validator` address. Then hashing the result.
*
* See {ECDSA-recover}.
*/
function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(hex"19_00", validator, data));
}
/**
* @dev Returns the keccak256 digest of an EIP-712 typed data (EIP-191 version `0x01`).
*
* The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with
* `\x19\x01` and hashing the result. It corresponds to the hash signed by the
* https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712.
*
* See {ECDSA-recover}.
*/
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) {
/// @solidity memory-safe-assembly
assembly {
let ptr := mload(0x40)
mstore(ptr, hex"19_01")
mstore(add(ptr, 0x02), domainSeparator)
mstore(add(ptr, 0x22), structHash)
digest := keccak256(ptr, 0x42)
}
}
}
// File: @openzeppelin/contracts/interfaces/IERC5267.sol
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol)
pragma solidity ^0.8.20;
interface IERC5267 {
/**
* @dev MAY be emitted to signal that the domain could have changed.
*/
event EIP712DomainChanged();
/**
* @dev returns the fields and values that describe the domain separator used by this contract for EIP-712
* signature.
*/
function eip712Domain()
external
view
returns (
bytes1 fields,
string memory name,
string memory version,
uint256 chainId,
address verifyingContract,
bytes32 salt,
uint256[] memory extensions
);
}
// File: @openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/EIP712.sol)
pragma solidity ^0.8.20;
/**
* @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
*
* The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose
* encoding is very generic and therefore its 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 order to
* produce the hash of their typed data using a combination of `abi.encode` and `keccak256`.
*
* This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
* scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
* ({_hashTypedDataV4}).
*
* The implementation of the domain separator was designed to be as efficient as possible while still properly updating
* the chain id to protect against replay attacks on an eventual fork of the chain.
*
* NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
* https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
*
* NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain
* separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the
* separator from the immutable values, which is cheaper than accessing a cached version in cold storage.
*/
abstract contract EIP712Upgradeable is Initializable, IERC5267 {
bytes32 private constant TYPE_HASH =
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
/// @custom:storage-location erc7201:openzeppelin.storage.EIP712
struct EIP712Storage {
/// @custom:oz-renamed-from _HASHED_NAME
bytes32 _hashedName;
/// @custom:oz-renamed-from _HASHED_VERSION
bytes32 _hashedVersion;
string _name;
string _version;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.EIP712")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant EIP712StorageLocation = 0xa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100;
function _getEIP712Storage() private pure returns (EIP712Storage storage $) {
assembly {
$.slot := EIP712StorageLocation
}
}
/**
* @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 {
EIP712Storage storage $ = _getEIP712Storage();
$._name = name;
$._version = version;
// Reset prior values in storage if upgrading
$._hashedName = 0;
$._hashedVersion = 0;
}
/**
* @dev Returns the domain separator for the current chain.
*/
function _domainSeparatorV4() internal view returns (bytes32) {
return _buildDomainSeparator();
}
function _buildDomainSeparator() private view returns (bytes32) {
return keccak256(abi.encode(TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this)));
}
/**
* @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
* function returns the hash of the fully encoded EIP712 message for this domain.
*
* This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
*
* ```solidity
* bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
* keccak256("Mail(address to,string contents)"),
* mailTo,
* keccak256(bytes(mailContents))
* )));
* address signer = ECDSA.recover(digest, signature);
* ```
*/
function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
return MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash);
}
/**
* @dev See {IERC-5267}.
*/
function eip712Domain()
public
view
virtual
returns (
bytes1 fields,
string memory name,
string memory version,
uint256 chainId,
address verifyingContract,
bytes32 salt,
uint256[] memory extensions
)
{
EIP712Storage storage $ = _getEIP712Storage();
// If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized
// and the EIP712 domain is not reliable, as it will be missing name and version.
require($._hashedName == 0 && $._hashedVersion == 0, "EIP712: Uninitialized");
return (
hex"0f", // 01111
_EIP712Name(),
_EIP712Version(),
block.chainid,
address(this),
bytes32(0),
new uint256[](0)
);
}
/**
* @dev The name parameter for the EIP712 domain.
*
* NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs
* are a concern.
*/
function _EIP712Name() internal view virtual returns (string memory) {
EIP712Storage storage $ = _getEIP712Storage();
return $._name;
}
/**
* @dev The version parameter for the EIP712 domain.
*
* NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs
* are a concern.
*/
function _EIP712Version() internal view virtual returns (string memory) {
EIP712Storage storage $ = _getEIP712Storage();
return $._version;
}
/**
* @dev The hash of the name parameter for the EIP712 domain.
*
* NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.
*/
function _EIP712NameHash() internal view returns (bytes32) {
EIP712Storage storage $ = _getEIP712Storage();
string memory name = _EIP712Name();
if (bytes(name).length > 0) {
return keccak256(bytes(name));
} else {
// If the name is empty, the contract may have been upgraded without initializing the new storage.
// We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.
bytes32 hashedName = $._hashedName;
if (hashedName != 0) {
return hashedName;
} else {
return keccak256("");
}
}
}
/**
* @dev The hash of the version parameter for the EIP712 domain.
*
* NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.
*/
function _EIP712VersionHash() internal view returns (bytes32) {
EIP712Storage storage $ = _getEIP712Storage();
string memory version = _EIP712Version();
if (bytes(version).length > 0) {
return keccak256(bytes(version));
} else {
// If the version is empty, the contract may have been upgraded without initializing the new storage.
// We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.
bytes32 hashedVersion = $._hashedVersion;
if (hashedVersion != 0) {
return hashedVersion;
} else {
return keccak256("");
}
}
}
}
// File: @openzeppelin/contracts-upgradeable/utils/NoncesUpgradeable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Nonces.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides tracking nonces for addresses. Nonces will only increment.
*/
abstract contract NoncesUpgradeable is Initializable {
/**
* @dev The nonce used for an `account` is not the expected current nonce.
*/
error InvalidAccountNonce(address account, uint256 currentNonce);
/// @custom:storage-location erc7201:openzeppelin.storage.Nonces
struct NoncesStorage {
mapping(address account => uint256) _nonces;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Nonces")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant NoncesStorageLocation = 0x5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb00;
function _getNoncesStorage() private pure returns (NoncesStorage storage $) {
assembly {
$.slot := NoncesStorageLocation
}
}
function __Nonces_init() internal onlyInitializing {
}
function __Nonces_init_unchained() internal onlyInitializing {
}
/**
* @dev Returns the next unused nonce for an address.
*/
function nonces(address owner) public view virtual returns (uint256) {
NoncesStorage storage $ = _getNoncesStorage();
return $._nonces[owner];
}
/**
* @dev Consumes a nonce.
*
* Returns the current value and increments nonce.
*/
function _useNonce(address owner) internal virtual returns (uint256) {
NoncesStorage storage $ = _getNoncesStorage();
// For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be
// decremented or reset. This guarantees that the nonce never overflows.
unchecked {
// It is important to do x++ and not ++x here.
return $._nonces[owner]++;
}
}
/**
* @dev Same as {_useNonce} but checking that `nonce` is the next valid for `owner`.
*/
function _useCheckedNonce(address owner, uint256 nonce) internal virtual {
uint256 current = _useNonce(owner);
if (nonce != current) {
revert InvalidAccountNonce(owner, current);
}
}
}
// File: @openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Permit.sol)
pragma solidity ^0.8.20;
/**
* @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.
*/
abstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20Permit, EIP712Upgradeable, NoncesUpgradeable {
bytes32 private constant PERMIT_TYPEHASH =
keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
/**
* @dev Permit deadline has expired.
*/
error ERC2612ExpiredSignature(uint256 deadline);
/**
* @dev Mismatched signature.
*/
error ERC2612InvalidSigner(address signer, address owner);
/**
* @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
*
* It's a good idea to use the same `name` that is defined as the ERC20 token name.
*/
function __ERC20Permit_init(string memory name) internal onlyInitializing {
__EIP712_init_unchained(name, "1");
}
function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}
/**
* @inheritdoc IERC20Permit
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
if (block.timestamp > deadline) {
revert ERC2612ExpiredSignature(deadline);
}
bytes32 structHash = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));
bytes32 hash = _hashTypedDataV4(structHash);
address signer = ECDSA.recover(hash, v, r, s);
if (signer != owner) {
revert ERC2612InvalidSigner(signer, owner);
}
_approve(owner, spender, value);
}
/**
* @inheritdoc IERC20Permit
*/
function nonces(address owner) public view virtual override(IERC20Permit, NoncesUpgradeable) returns (uint256) {
return super.nonces(owner);
}
/**
* @inheritdoc IERC20Permit
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view virtual returns (bytes32) {
return _domainSeparatorV4();
}
}
// File: @openzeppelin/contracts/interfaces/draft-IERC1822.sol
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC1822.sol)
pragma solidity ^0.8.20;
/**
* @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
* proxy whose upgrades are fully controlled by the current implementation.
*/
interface IERC1822Proxiable {
/**
* @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
* address.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy.
*/
function proxiableUUID() external view returns (bytes32);
}
// File: @openzeppelin/contracts/proxy/beacon/IBeacon.sol
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)
pragma solidity ^0.8.20;
/**
* @dev This is the interface that {BeaconProxy} expects of its beacon.
*/
interface IBeacon {
/**
* @dev Must return an address that can be used as a delegate call target.
*
* {UpgradeableBeacon} will check that this address is a contract.
*/
function implementation() external view returns (address);
}
// File: @openzeppelin/contracts/utils/Address.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error AddressInsufficientBalance(address account);
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedInnerCall();
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
/**
* @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 or custom error, it is bubbled
* up by this function (like regular Solidity function calls). However, if
* the call reverted with no returned reason, this function reverts with a
* {FailedInnerCall} error.
*
* 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.
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
/**
* @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`.
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert AddressInsufficientBalance(address(this));
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
* was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
* unsuccessful call.
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
// only check if target is a contract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
/**
* @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
* revert reason or with a default {FailedInnerCall} error.
*/
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
/**
* @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
*/
function _revert(bytes memory returndata) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}
// File: @openzeppelin/contracts/utils/StorageSlot.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
pragma solidity ^0.8.20;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC1967 implementation slot:
* ```solidity
* contract ERC1967 {
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(newImplementation.code.length > 0);
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*/
library StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
struct StringSlot {
string value;
}
struct BytesSlot {
bytes value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` with member `value` located at `slot`.
*/
function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` representation of the string storage pointer `store`.
*/
function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
/**
* @dev Returns an `BytesSlot` with member `value` located at `slot`.
*/
function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
*/
function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
}
// File: @openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Utils.sol)
pragma solidity ^0.8.20;
/**
* @dev This abstract contract provides getters and event emitting update functions for
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
*/
library ERC1967Utils {
// We re-declare ERC-1967 events here because they can't be used directly from IERC1967.
// This will be fixed in Solidity 0.8.21. At that point we should remove these events.
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Emitted when the beacon is changed.
*/
event BeaconUpgraded(address indexed beacon);
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1.
*/
// solhint-disable-next-line private-vars-leading-underscore
bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev The `implementation` of the proxy is invalid.
*/
error ERC1967InvalidImplementation(address implementation);
/**
* @dev The `admin` of the proxy is invalid.
*/
error ERC1967InvalidAdmin(address admin);
/**
* @dev The `beacon` of the proxy is invalid.
*/
error ERC1967InvalidBeacon(address beacon);
/**
* @dev An upgrade function sees `msg.value > 0` that may be lost.
*/
error ERC1967NonPayable();
/**
* @dev Returns the current implementation address.
*/
function getImplementation() internal view returns (address) {
return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
if (newImplementation.code.length == 0) {
revert ERC1967InvalidImplementation(newImplementation);
}
StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;
}
/**
* @dev Performs implementation upgrade with additional setup call if data is nonempty.
* This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
* to avoid stuck value in the contract.
*
* Emits an {IERC1967-Upgraded} event.
*/
function upgradeToAndCall(address newImplementation, bytes memory data) internal {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
if (data.length > 0) {
Address.functionDelegateCall(newImplementation, data);
} else {
_checkNonPayable();
}
}
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1.
*/
// solhint-disable-next-line private-vars-leading-underscore
bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Returns the current admin.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using
* the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
*/
function getAdmin() internal view returns (address) {
return StorageSlot.getAddressSlot(ADMIN_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
if (newAdmin == address(0)) {
revert ERC1967InvalidAdmin(address(0));
}
StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {IERC1967-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 the keccak-256 hash of "eip1967.proxy.beacon" subtracted by 1.
*/
// solhint-disable-next-line private-vars-leading-underscore
bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
/**
* @dev Returns the current beacon.
*/
function getBeacon() internal view returns (address) {
return StorageSlot.getAddressSlot(BEACON_SLOT).value;
}
/**
* @dev Stores a new beacon in the EIP1967 beacon slot.
*/
function _setBeacon(address newBeacon) private {
if (newBeacon.code.length == 0) {
revert ERC1967InvalidBeacon(newBeacon);
}
StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;
address beaconImplementation = IBeacon(newBeacon).implementation();
if (beaconImplementation.code.length == 0) {
revert ERC1967InvalidImplementation(beaconImplementation);
}
}
/**
* @dev Change the beacon and trigger a setup call if data is nonempty.
* This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
* to avoid stuck value in the contract.
*
* Emits an {IERC1967-BeaconUpgraded} event.
*
* CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since
* it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for
* efficiency.
*/
function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {
_setBeacon(newBeacon);
emit BeaconUpgraded(newBeacon);
if (data.length > 0) {
Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
} else {
_checkNonPayable();
}
}
/**
* @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract
* if an upgrade doesn't perform an initialization call.
*/
function _checkNonPayable() private {
if (msg.value > 0) {
revert ERC1967NonPayable();
}
}
}
// File: @openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/UUPSUpgradeable.sol)
pragma solidity ^0.8.20;
/**
* @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.
*/
abstract contract UUPSUpgradeable is Initializable, IERC1822Proxiable {
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
address private immutable __self = address(this);
/**
* @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgradeTo(address)`
* and `upgradeToAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called,
* while `upgradeToAndCall` will invoke the `receive` function if the second argument is the empty byte string.
* If the getter returns `"5.0.0"`, only `upgradeToAndCall(address,bytes)` is present, and the second argument must
* be the empty byte string if no function should be called, making it impossible to invoke the `receive` function
* during an upgrade.
*/
string public constant UPGRADE_INTERFACE_VERSION = "5.0.0";
/**
* @dev The call is from an unauthorized context.
*/
error UUPSUnauthorizedCallContext();
/**
* @dev The storage `slot` is unsupported as a UUID.
*/
error UUPSUnsupportedProxiableUUID(bytes32 slot);
/**
* @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() {
_checkProxy();
_;
}
/**
* @dev Check that the execution is not being performed through a delegate call. This allows a function to be
* callable on the implementing contract but not through proxies.
*/
modifier notDelegated() {
_checkNotDelegated();
_;
}
function __UUPSUpgradeable_init() internal onlyInitializing {
}
function __UUPSUpgradeable_init_unchained() internal onlyInitializing {
}
/**
* @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
* implementation. It is used to validate the implementation's compatibility when performing an upgrade.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
*/
function proxiableUUID() external view virtual notDelegated returns (bytes32) {
return ERC1967Utils.IMPLEMENTATION_SLOT;
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
* encoded in `data`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*
* @custom:oz-upgrades-unsafe-allow-reachable delegatecall
*/
function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallUUPS(newImplementation, data);
}
/**
* @dev Reverts if the execution is not performed via delegatecall or the execution
* context is not of a proxy with an ERC1967-compliant implementation pointing to self.
* See {_onlyProxy}.
*/
function _checkProxy() internal view virtual {
if (
address(this) == __self || // Must be called through delegatecall
ERC1967Utils.getImplementation() != __self // Must be called through an active proxy
) {
revert UUPSUnauthorizedCallContext();
}
}
/**
* @dev Reverts if the execution is performed via delegatecall.
* See {notDelegated}.
*/
function _checkNotDelegated() internal view virtual {
if (address(this) != __self) {
// Must not be called through delegatecall
revert UUPSUnauthorizedCallContext();
}
}
/**
* @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
* {upgradeToAndCall}.
*
* Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
*
* ```solidity
* function _authorizeUpgrade(address) internal onlyOwner {}
* ```
*/
function _authorizeUpgrade(address newImplementation) internal virtual;
/**
* @dev Performs an implementation upgrade with a security check for UUPS proxies, and additional setup call.
*
* As a security check, {proxiableUUID} is invoked in the new implementation, and the return value
* is expected to be the implementation slot in ERC1967.
*
* Emits an {IERC1967-Upgraded} event.
*/
function _upgradeToAndCallUUPS(address newImplementation, bytes memory data) private {
try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {
if (slot != ERC1967Utils.IMPLEMENTATION_SLOT) {
revert UUPSUnsupportedProxiableUUID(slot);
}
ERC1967Utils.upgradeToAndCall(newImplementation, data);
} catch {
// The implementation is not UUPS
revert ERC1967Utils.ERC1967InvalidImplementation(newImplementation);
}
}
}
// File: contracts/RayIsToken.sol
pragma solidity ^0.8.20;
contract RaylsToken is
Initializable,
ERC20Upgradeable,
ERC20BurnableUpgradeable,
ERC20PausableUpgradeable,
AccessControlUpgradeable,
ERC20PermitUpgradeable,
UUPSUpgradeable
{
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
bytes32 public constant UPGRADER_ROLE = keccak256("UPGRADER_ROLE");
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
uint256 public constant MAX_SUPPLY = 10000000000000000000000000000; // 10 bilhões de tokens
bool private _minted;
constructor() {}
function initialize(
address defaultAdmin,
address pauser,
address minter,
address upgrader
) public initializer {
__ERC20_init("Rayls", "RLS");
__ERC20Burnable_init();
__ERC20Pausable_init();
__AccessControl_init();
__ERC20Permit_init("Rayls");
__UUPSUpgradeable_init();
_grantRole(DEFAULT_ADMIN_ROLE, defaultAdmin);
_grantRole(PAUSER_ROLE, pauser);
_grantRole(UPGRADER_ROLE, upgrader);
_grantRole(MINTER_ROLE, minter);
_minted = false; // Inicializa como não-mintado
}
function mint(address receiver) public onlyRole(MINTER_ROLE) {
require(!_minted, "RaylsToken: Mint has already been performed");
_mint(receiver, MAX_SUPPLY); // Cunha 10 bilhões de tokens para o receiver
_minted = true; // Marca como mintado
}
function pause() public onlyRole(PAUSER_ROLE) {
_pause();
}
function unpause() public onlyRole(PAUSER_ROLE) {
_unpause();
}
function _authorizeUpgrade(
address newImplementation
) internal override onlyRole(UPGRADER_ROLE) {}
function _update(
address from,
address to,
uint256 value
) internal override(ERC20Upgradeable, ERC20PausableUpgradeable) {
super._update(from, to, value);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[],"name":"ECDSAInvalidSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"ECDSAInvalidSignatureLength","type":"error"},{"inputs":[{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"ECDSAInvalidSignatureS","type":"error"},{"inputs":[{"internalType":"address","name":"implementation","type":"address"}],"name":"ERC1967InvalidImplementation","type":"error"},{"inputs":[],"name":"ERC1967NonPayable","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"ERC2612ExpiredSignature","type":"error"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC2612InvalidSigner","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"currentNonce","type":"uint256"}],"name":"InvalidAccountNonce","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"UUPSUnauthorizedCallContext","type":"error"},{"inputs":[{"internalType":"bytes32","name":"slot","type":"bytes32"}],"name":"UUPSUnsupportedProxiableUUID","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","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":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":"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":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UPGRADER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UPGRADE_INTERFACE_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"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":"defaultAdmin","type":"address"},{"internalType":"address","name":"pauser","type":"address"},{"internalType":"address","name":"minter","type":"address"},{"internalType":"address","name":"upgrader","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"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":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","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":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","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
60a06040523073ffffffffffffffffffffffffffffffffffffffff1660809073ffffffffffffffffffffffffffffffffffffffff168152503480156041575f80fd5b50608051613d276100685f395f818161199d015281816119f20152611bcf0152613d275ff3fe6080604052600436106101f8575f3560e01c806370a082311161010c578063a9059cbb1161009f578063d547741f1161006e578063d547741f14610712578063dd62ed3e1461073a578063e63ab1e914610776578063f72c0d8b146107a0578063f8c8765e146107ca576101f8565b8063a9059cbb1461065a578063ad3cb1cc14610696578063d505accf146106c0578063d5391393146106e8576101f8565b806384b0196e116100db57806384b0196e1461059a57806391d14854146105ca57806395d89b4114610606578063a217fddf14610630576101f8565b806370a08231146104e457806379cc6790146105205780637ecebe00146105485780638456cb5914610584576101f8565b806332cb6b0c1161018f57806342966c681161015e57806342966c68146104245780634f1ef2861461044c57806352d1902d146104685780635c975abb146104925780636a627842146104bc576101f8565b806332cb6b0c146103925780633644e515146103bc57806336568abe146103e65780633f4ba83a1461040e576101f8565b806323b872dd116101cb57806323b872dd146102c8578063248a9ca3146103045780632f2ff15d14610340578063313ce56714610368576101f8565b806301ffc9a7146101fc57806306fdde0314610238578063095ea7b31461026257806318160ddd1461029e575b5f80fd5b348015610207575f80fd5b50610222600480360381019061021d9190612e28565b6107f2565b60405161022f9190612e6d565b60405180910390f35b348015610243575f80fd5b5061024c61086b565b6040516102599190612ef6565b60405180910390f35b34801561026d575f80fd5b5061028860048036038101906102839190612fa3565b610909565b6040516102959190612e6d565b60405180910390f35b3480156102a9575f80fd5b506102b261092b565b6040516102bf9190612ff0565b60405180910390f35b3480156102d3575f80fd5b506102ee60048036038101906102e99190613009565b610942565b6040516102fb9190612e6d565b60405180910390f35b34801561030f575f80fd5b5061032a6004803603810190610325919061308c565b610970565b60405161033791906130c6565b60405180910390f35b34801561034b575f80fd5b50610366600480360381019061036191906130df565b61099a565b005b348015610373575f80fd5b5061037c6109bc565b6040516103899190613138565b60405180910390f35b34801561039d575f80fd5b506103a66109c4565b6040516103b39190612ff0565b60405180910390f35b3480156103c7575f80fd5b506103d06109d4565b6040516103dd91906130c6565b60405180910390f35b3480156103f1575f80fd5b5061040c600480360381019061040791906130df565b6109e2565b005b348015610419575f80fd5b50610422610a5d565b005b34801561042f575f80fd5b5061044a60048036038101906104459190613151565b610a92565b005b610466600480360381019061046191906132a8565b610aa6565b005b348015610473575f80fd5b5061047c610ac5565b60405161048991906130c6565b60405180910390f35b34801561049d575f80fd5b506104a6610af6565b6040516104b39190612e6d565b60405180910390f35b3480156104c7575f80fd5b506104e260048036038101906104dd9190613302565b610b18565b005b3480156104ef575f80fd5b5061050a60048036038101906105059190613302565b610bc2565b6040516105179190612ff0565b60405180910390f35b34801561052b575f80fd5b5061054660048036038101906105419190612fa3565b610c15565b005b348015610553575f80fd5b5061056e60048036038101906105699190613302565b610c35565b60405161057b9190612ff0565b60405180910390f35b34801561058f575f80fd5b50610598610c46565b005b3480156105a5575f80fd5b506105ae610c7b565b6040516105c1979695949392919061342d565b60405180910390f35b3480156105d5575f80fd5b506105f060048036038101906105eb91906130df565b610d84565b6040516105fd9190612e6d565b60405180910390f35b348015610611575f80fd5b5061061a610df5565b6040516106279190612ef6565b60405180910390f35b34801561063b575f80fd5b50610644610e93565b60405161065191906130c6565b60405180910390f35b348015610665575f80fd5b50610680600480360381019061067b9190612fa3565b610e99565b60405161068d9190612e6d565b60405180910390f35b3480156106a1575f80fd5b506106aa610ebb565b6040516106b79190612ef6565b60405180910390f35b3480156106cb575f80fd5b506106e660048036038101906106e191906134d9565b610ef4565b005b3480156106f3575f80fd5b506106fc611039565b60405161070991906130c6565b60405180910390f35b34801561071d575f80fd5b50610738600480360381019061073391906130df565b61105d565b005b348015610745575f80fd5b50610760600480360381019061075b9190613576565b61107f565b60405161076d9190612ff0565b60405180910390f35b348015610781575f80fd5b5061078a61110f565b60405161079791906130c6565b60405180910390f35b3480156107ab575f80fd5b506107b4611133565b6040516107c191906130c6565b60405180910390f35b3480156107d5575f80fd5b506107f060048036038101906107eb91906135b4565b611157565b005b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061086457506108638261144a565b5b9050919050565b60605f6108766114b3565b905080600301805461088790613645565b80601f01602080910402602001604051908101604052809291908181526020018280546108b390613645565b80156108fe5780601f106108d5576101008083540402835291602001916108fe565b820191905f5260205f20905b8154815290600101906020018083116108e157829003601f168201915b505050505091505090565b5f806109136114da565b90506109208185856114e1565b600191505092915050565b5f806109356114b3565b9050806002015491505090565b5f8061094c6114da565b90506109598582856114f3565b610964858585611585565b60019150509392505050565b5f8061097a611675565b9050805f015f8481526020019081526020015f2060010154915050919050565b6109a382610970565b6109ac8161169c565b6109b683836116b0565b50505050565b5f6012905090565b6b204fce5e3e2502611000000081565b5f6109dd6117a8565b905090565b6109ea6114da565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a4e576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a5882826117b6565b505050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610a878161169c565b610a8f6118ae565b50565b610aa3610a9d6114da565b8261191c565b50565b610aae61199b565b610ab782611a81565b610ac18282611aaf565b5050565b5f610ace611bcd565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b905090565b5f80610b00611c54565b9050805f015f9054906101000a900460ff1691505090565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610b428161169c565b5f8054906101000a900460ff1615610b8f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b86906136e5565b60405180910390fd5b610ba5826b204fce5e3e25026110000000611c7b565b60015f806101000a81548160ff0219169083151502179055505050565b5f80610bcc6114b3565b9050805f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054915050919050565b610c2782610c216114da565b836114f3565b610c31828261191c565b5050565b5f610c3f82611cfa565b9050919050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610c708161169c565b610c78611d4d565b50565b5f6060805f805f60605f610c8d611dbc565b90505f801b815f0154148015610ca857505f801b8160010154145b610ce7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cde9061374d565b60405180910390fd5b610cef611de3565b610cf7611e81565b46305f801b5f67ffffffffffffffff811115610d1657610d15613184565b5b604051908082528060200260200182016040528015610d445781602001602082028036833780820191505090505b507f0f0000000000000000000000000000000000000000000000000000000000000095949392919097509750975097509750975097505090919293949596565b5f80610d8e611675565b9050805f015f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1691505092915050565b60605f610e006114b3565b9050806004018054610e1190613645565b80601f0160208091040260200160405190810160405280929190818152602001828054610e3d90613645565b8015610e885780601f10610e5f57610100808354040283529160200191610e88565b820191905f5260205f20905b815481529060010190602001808311610e6b57829003601f168201915b505050505091505090565b5f801b81565b5f80610ea36114da565b9050610eb0818585611585565b600191505092915050565b6040518060400160405280600581526020017f352e302e3000000000000000000000000000000000000000000000000000000081525081565b83421115610f3957836040517f62791302000000000000000000000000000000000000000000000000000000008152600401610f309190612ff0565b60405180910390fd5b5f7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610f678c611f1f565b89604051602001610f7d9695949392919061376b565b6040516020818303038152906040528051906020012090505f610f9f82611f7f565b90505f610fae82878787611f98565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461102257808a6040517f4b800e460000000000000000000000000000000000000000000000000000000081526004016110199291906137ca565b60405180910390fd5b61102d8a8a8a6114e1565b50505050505050505050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b61106682610970565b61106f8161169c565b61107983836117b6565b50505050565b5f806110896114b3565b9050806001015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205491505092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b7f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e381565b5f611160611fc6565b90505f815f0160089054906101000a900460ff161590505f825f015f9054906101000a900467ffffffffffffffff1690505f808267ffffffffffffffff161480156111a85750825b90505f60018367ffffffffffffffff161480156111db57505f3073ffffffffffffffffffffffffffffffffffffffff163b145b9050811580156111e9575080155b15611220576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001855f015f6101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550831561126d576001855f0160086101000a81548160ff0219169083151502179055505b6112e16040518060400160405280600581526020017f5261796c730000000000000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f524c530000000000000000000000000000000000000000000000000000000000815250611fed565b6112e9612003565b6112f161200d565b6112f961201f565b6113376040518060400160405280600581526020017f5261796c73000000000000000000000000000000000000000000000000000000815250612029565b61133f612073565b61134b5f801b8a6116b0565b506113767f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a896116b0565b506113a17f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e3876116b0565b506113cc7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6886116b0565b505f805f6101000a81548160ff021916908315150217905550831561143f575f855f0160086101000a81548160ff0219169083151502179055507fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d260016040516114369190613846565b60405180910390a15b505050505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00905090565b5f33905090565b6114ee838383600161207d565b505050565b5f6114fe848461107f565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461157f5781811015611570578281836040517ffb8f41b20000000000000000000000000000000000000000000000000000000081526004016115679392919061385f565b60405180910390fd5b61157e84848484035f61207d565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036115f5575f6040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081526004016115ec9190613894565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611665575f6040517fec442f0500000000000000000000000000000000000000000000000000000000815260040161165c9190613894565b60405180910390fd5b61167083838361225a565b505050565b5f7f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800905090565b6116ad816116a86114da565b61226a565b50565b5f806116ba611675565b90506116c68484610d84565b61179d576001815f015f8681526020019081526020015f205f015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506117396114da565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16857f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a460019150506117a2565b5f9150505b92915050565b5f6117b16122bb565b905090565b5f806117c0611675565b90506117cc8484610d84565b156118a3575f815f015f8681526020019081526020015f205f015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555061183f6114da565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16857ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a460019150506118a8565b5f9150505b92915050565b6118b661231e565b5f6118bf611c54565b90505f815f015f6101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6119046114da565b6040516119119190613894565b60405180910390a150565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361198c575f6040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081526004016119839190613894565b60405180910390fd5b611997825f8361225a565b5050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff161480611a4857507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16611a2f61235e565b73ffffffffffffffffffffffffffffffffffffffff1614155b15611a7f576040517fe07c8dba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e3611aab8161169c565b5050565b8173ffffffffffffffffffffffffffffffffffffffff166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611b1757506040513d601f19601f82011682018060405250810190611b1491906138c1565b60015b611b5857816040517f4c9c8ce3000000000000000000000000000000000000000000000000000000008152600401611b4f9190613894565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b8114611bbe57806040517faa1d49a4000000000000000000000000000000000000000000000000000000008152600401611bb591906130c6565b60405180910390fd5b611bc883836123b1565b505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614611c52576040517fe07c8dba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300905090565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ceb575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401611ce29190613894565b60405180910390fd5b611cf65f838361225a565b5050565b5f80611d04612423565b9050805f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054915050919050565b611d5561244a565b5f611d5e611c54565b90506001815f015f6101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611da46114da565b604051611db19190613894565b60405180910390a150565b5f7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100905090565b60605f611dee611dbc565b9050806002018054611dff90613645565b80601f0160208091040260200160405190810160405280929190818152602001828054611e2b90613645565b8015611e765780601f10611e4d57610100808354040283529160200191611e76565b820191905f5260205f20905b815481529060010190602001808311611e5957829003601f168201915b505050505091505090565b60605f611e8c611dbc565b9050806003018054611e9d90613645565b80601f0160208091040260200160405190810160405280929190818152602001828054611ec990613645565b8015611f145780601f10611eeb57610100808354040283529160200191611f14565b820191905f5260205f20905b815481529060010190602001808311611ef757829003601f168201915b505050505091505090565b5f80611f29612423565b9050805f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f81548092919060010191905055915050919050565b5f611f91611f8b6117a8565b8361248b565b9050919050565b5f805f80611fa8888888886124cb565b925092509250611fb882826125b2565b829350505050949350505050565b5f7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00905090565b611ff5612714565b611fff8282612754565b5050565b61200b612714565b565b612015612714565b61201d612790565b565b612027612714565b565b612031612714565b612070816040518060400160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152506127c0565b50565b61207b612714565b565b5f6120866114b3565b90505f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036120f8575f6040517fe602df050000000000000000000000000000000000000000000000000000000081526004016120ef9190613894565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612168575f6040517f94280d6200000000000000000000000000000000000000000000000000000000815260040161215f9190613894565b60405180910390fd5b82816001015f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508115612253578373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258560405161224a9190612ff0565b60405180910390a35b5050505050565b612265838383612811565b505050565b6122748282610d84565b6122b75780826040517fe2517d3f0000000000000000000000000000000000000000000000000000000081526004016122ae9291906138ec565b60405180910390fd5b5050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6122e5612829565b6122ed61289f565b4630604051602001612303959493929190613913565b60405160208183030381529060405280519060200120905090565b612326610af6565b61235c576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f61238a7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b612916565b5f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6123ba8261291f565b8173ffffffffffffffffffffffffffffffffffffffff167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b60405160405180910390a25f815111156124165761241082826129e8565b5061241f565b61241e612a68565b5b5050565b5f7f5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb00905090565b612452610af6565b15612489576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f6040517f190100000000000000000000000000000000000000000000000000000000000081528360028201528260228201526042812091505092915050565b5f805f7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0845f1c1115612507575f6003859250925092506125a8565b5f6001888888886040515f815260200160405260405161252a9493929190613964565b6020604051602081039080840390855afa15801561254a573d5f803e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361259b575f60015f801b935093509350506125a8565b805f805f1b935093509350505b9450945094915050565b5f60038111156125c5576125c46139a7565b5b8260038111156125d8576125d76139a7565b5b031561271057600160038111156125f2576125f16139a7565b5b826003811115612605576126046139a7565b5b0361263c576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600260038111156126505761264f6139a7565b5b826003811115612663576126626139a7565b5b036126a757805f1c6040517ffce698f700000000000000000000000000000000000000000000000000000000815260040161269e9190612ff0565b60405180910390fd5b6003808111156126ba576126b96139a7565b5b8260038111156126cd576126cc6139a7565b5b0361270f57806040517fd78bce0c00000000000000000000000000000000000000000000000000000000815260040161270691906130c6565b60405180910390fd5b5b5050565b61271c612aa4565b612752576040517fd7e6bcf800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b61275c612714565b5f6127656114b3565b9050828160030190816127789190613b68565b508181600401908161278a9190613b68565b50505050565b612798612714565b5f6127a1611c54565b90505f815f015f6101000a81548160ff02191690831515021790555050565b6127c8612714565b5f6127d1611dbc565b9050828160020190816127e49190613b68565b50818160030190816127f69190613b68565b505f801b815f01819055505f801b8160010181905550505050565b61281961244a565b612824838383612ac2565b505050565b5f80612833611dbc565b90505f61283e611de3565b90505f8151111561285a5780805190602001209250505061289c565b5f825f015490505f801b81146128755780935050505061289c565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47093505050505b90565b5f806128a9611dbc565b90505f6128b4611e81565b90505f815111156128d057808051906020012092505050612913565b5f826001015490505f801b81146128ec57809350505050612913565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47093505050505b90565b5f819050919050565b5f8173ffffffffffffffffffffffffffffffffffffffff163b0361297a57806040517f4c9c8ce30000000000000000000000000000000000000000000000000000000081526004016129719190613894565b60405180910390fd5b806129a67f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b612916565b5f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60605f808473ffffffffffffffffffffffffffffffffffffffff1684604051612a119190613c7b565b5f60405180830381855af49150503d805f8114612a49576040519150601f19603f3d011682016040523d82523d5f602084013e612a4e565b606091505b5091509150612a5e858383612cf1565b9250505092915050565b5f341115612aa2576040517fb398979f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f612aad611fc6565b5f0160089054906101000a900460ff16905090565b5f612acb6114b3565b90505f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612b1f5781816002015f828254612b139190613cbe565b92505081905550612bf1565b5f815f015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905082811015612baa578481846040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401612ba19392919061385f565b60405180910390fd5b828103825f015f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612c3a5781816002015f8282540392505081905550612c86565b81815f015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612ce39190612ff0565b60405180910390a350505050565b606082612d0657612d0182612d7e565b612d76565b5f8251148015612d2c57505f8473ffffffffffffffffffffffffffffffffffffffff163b145b15612d6e57836040517f9996b315000000000000000000000000000000000000000000000000000000008152600401612d659190613894565b60405180910390fd5b819050612d77565b5b9392505050565b5f81511115612d905780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612e0781612dd3565b8114612e11575f80fd5b50565b5f81359050612e2281612dfe565b92915050565b5f60208284031215612e3d57612e3c612dcb565b5b5f612e4a84828501612e14565b91505092915050565b5f8115159050919050565b612e6781612e53565b82525050565b5f602082019050612e805f830184612e5e565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f612ec882612e86565b612ed28185612e90565b9350612ee2818560208601612ea0565b612eeb81612eae565b840191505092915050565b5f6020820190508181035f830152612f0e8184612ebe565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612f3f82612f16565b9050919050565b612f4f81612f35565b8114612f59575f80fd5b50565b5f81359050612f6a81612f46565b92915050565b5f819050919050565b612f8281612f70565b8114612f8c575f80fd5b50565b5f81359050612f9d81612f79565b92915050565b5f8060408385031215612fb957612fb8612dcb565b5b5f612fc685828601612f5c565b9250506020612fd785828601612f8f565b9150509250929050565b612fea81612f70565b82525050565b5f6020820190506130035f830184612fe1565b92915050565b5f805f606084860312156130205761301f612dcb565b5b5f61302d86828701612f5c565b935050602061303e86828701612f5c565b925050604061304f86828701612f8f565b9150509250925092565b5f819050919050565b61306b81613059565b8114613075575f80fd5b50565b5f8135905061308681613062565b92915050565b5f602082840312156130a1576130a0612dcb565b5b5f6130ae84828501613078565b91505092915050565b6130c081613059565b82525050565b5f6020820190506130d95f8301846130b7565b92915050565b5f80604083850312156130f5576130f4612dcb565b5b5f61310285828601613078565b925050602061311385828601612f5c565b9150509250929050565b5f60ff82169050919050565b6131328161311d565b82525050565b5f60208201905061314b5f830184613129565b92915050565b5f6020828403121561316657613165612dcb565b5b5f61317384828501612f8f565b91505092915050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6131ba82612eae565b810181811067ffffffffffffffff821117156131d9576131d8613184565b5b80604052505050565b5f6131eb612dc2565b90506131f782826131b1565b919050565b5f67ffffffffffffffff82111561321657613215613184565b5b61321f82612eae565b9050602081019050919050565b828183375f83830152505050565b5f61324c613247846131fc565b6131e2565b90508281526020810184848401111561326857613267613180565b5b61327384828561322c565b509392505050565b5f82601f83011261328f5761328e61317c565b5b813561329f84826020860161323a565b91505092915050565b5f80604083850312156132be576132bd612dcb565b5b5f6132cb85828601612f5c565b925050602083013567ffffffffffffffff8111156132ec576132eb612dcf565b5b6132f88582860161327b565b9150509250929050565b5f6020828403121561331757613316612dcb565b5b5f61332484828501612f5c565b91505092915050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6133618161332d565b82525050565b61337081612f35565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6133a881612f70565b82525050565b5f6133b9838361339f565b60208301905092915050565b5f602082019050919050565b5f6133db82613376565b6133e58185613380565b93506133f083613390565b805f5b8381101561342057815161340788826133ae565b9750613412836133c5565b9250506001810190506133f3565b5085935050505092915050565b5f60e0820190506134405f83018a613358565b81810360208301526134528189612ebe565b905081810360408301526134668188612ebe565b90506134756060830187612fe1565b6134826080830186613367565b61348f60a08301856130b7565b81810360c08301526134a181846133d1565b905098975050505050505050565b6134b88161311d565b81146134c2575f80fd5b50565b5f813590506134d3816134af565b92915050565b5f805f805f805f60e0888a0312156134f4576134f3612dcb565b5b5f6135018a828b01612f5c565b97505060206135128a828b01612f5c565b96505060406135238a828b01612f8f565b95505060606135348a828b01612f8f565b94505060806135458a828b016134c5565b93505060a06135568a828b01613078565b92505060c06135678a828b01613078565b91505092959891949750929550565b5f806040838503121561358c5761358b612dcb565b5b5f61359985828601612f5c565b92505060206135aa85828601612f5c565b9150509250929050565b5f805f80608085870312156135cc576135cb612dcb565b5b5f6135d987828801612f5c565b94505060206135ea87828801612f5c565b93505060406135fb87828801612f5c565b925050606061360c87828801612f5c565b91505092959194509250565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061365c57607f821691505b60208210810361366f5761366e613618565b5b50919050565b7f5261796c73546f6b656e3a204d696e742068617320616c7265616479206265655f8201527f6e20706572666f726d6564000000000000000000000000000000000000000000602082015250565b5f6136cf602b83612e90565b91506136da82613675565b604082019050919050565b5f6020820190508181035f8301526136fc816136c3565b9050919050565b7f4549503731323a20556e696e697469616c697a656400000000000000000000005f82015250565b5f613737601583612e90565b915061374282613703565b602082019050919050565b5f6020820190508181035f8301526137648161372b565b9050919050565b5f60c08201905061377e5f8301896130b7565b61378b6020830188613367565b6137986040830187613367565b6137a56060830186612fe1565b6137b26080830185612fe1565b6137bf60a0830184612fe1565b979650505050505050565b5f6040820190506137dd5f830185613367565b6137ea6020830184613367565b9392505050565b5f819050919050565b5f67ffffffffffffffff82169050919050565b5f819050919050565b5f61383061382b613826846137f1565b61380d565b6137fa565b9050919050565b61384081613816565b82525050565b5f6020820190506138595f830184613837565b92915050565b5f6060820190506138725f830186613367565b61387f6020830185612fe1565b61388c6040830184612fe1565b949350505050565b5f6020820190506138a75f830184613367565b92915050565b5f815190506138bb81613062565b92915050565b5f602082840312156138d6576138d5612dcb565b5b5f6138e3848285016138ad565b91505092915050565b5f6040820190506138ff5f830185613367565b61390c60208301846130b7565b9392505050565b5f60a0820190506139265f8301886130b7565b61393360208301876130b7565b61394060408301866130b7565b61394d6060830185612fe1565b61395a6080830184613367565b9695505050505050565b5f6080820190506139775f8301876130b7565b6139846020830186613129565b61399160408301856130b7565b61399e60608301846130b7565b95945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302613a307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826139f5565b613a3a86836139f5565b95508019841693508086168417925050509392505050565b5f613a6c613a67613a6284612f70565b61380d565b612f70565b9050919050565b5f819050919050565b613a8583613a52565b613a99613a9182613a73565b848454613a01565b825550505050565b5f90565b613aad613aa1565b613ab8818484613a7c565b505050565b5b81811015613adb57613ad05f82613aa5565b600181019050613abe565b5050565b601f821115613b2057613af1816139d4565b613afa846139e6565b81016020851015613b09578190505b613b1d613b15856139e6565b830182613abd565b50505b505050565b5f82821c905092915050565b5f613b405f1984600802613b25565b1980831691505092915050565b5f613b588383613b31565b9150826002028217905092915050565b613b7182612e86565b67ffffffffffffffff811115613b8a57613b89613184565b5b613b948254613645565b613b9f828285613adf565b5f60209050601f831160018114613bd0575f8415613bbe578287015190505b613bc88582613b4d565b865550613c2f565b601f198416613bde866139d4565b5f5b82811015613c0557848901518255600182019150602085019450602081019050613be0565b86831015613c225784890151613c1e601f891682613b31565b8355505b6001600288020188555050505b505050505050565b5f81519050919050565b5f81905092915050565b5f613c5582613c37565b613c5f8185613c41565b9350613c6f818560208601612ea0565b80840191505092915050565b5f613c868284613c4b565b915081905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f613cc882612f70565b9150613cd383612f70565b9250828201905080821115613ceb57613cea613c91565b5b9291505056fea2646970667358221220be5d7e59a28195315b3d6fb01d3d3ebcce894ab0a564f8fd27a8b08fecc34a0b64736f6c634300081a0033
Deployed Bytecode
0x6080604052600436106101f8575f3560e01c806370a082311161010c578063a9059cbb1161009f578063d547741f1161006e578063d547741f14610712578063dd62ed3e1461073a578063e63ab1e914610776578063f72c0d8b146107a0578063f8c8765e146107ca576101f8565b8063a9059cbb1461065a578063ad3cb1cc14610696578063d505accf146106c0578063d5391393146106e8576101f8565b806384b0196e116100db57806384b0196e1461059a57806391d14854146105ca57806395d89b4114610606578063a217fddf14610630576101f8565b806370a08231146104e457806379cc6790146105205780637ecebe00146105485780638456cb5914610584576101f8565b806332cb6b0c1161018f57806342966c681161015e57806342966c68146104245780634f1ef2861461044c57806352d1902d146104685780635c975abb146104925780636a627842146104bc576101f8565b806332cb6b0c146103925780633644e515146103bc57806336568abe146103e65780633f4ba83a1461040e576101f8565b806323b872dd116101cb57806323b872dd146102c8578063248a9ca3146103045780632f2ff15d14610340578063313ce56714610368576101f8565b806301ffc9a7146101fc57806306fdde0314610238578063095ea7b31461026257806318160ddd1461029e575b5f80fd5b348015610207575f80fd5b50610222600480360381019061021d9190612e28565b6107f2565b60405161022f9190612e6d565b60405180910390f35b348015610243575f80fd5b5061024c61086b565b6040516102599190612ef6565b60405180910390f35b34801561026d575f80fd5b5061028860048036038101906102839190612fa3565b610909565b6040516102959190612e6d565b60405180910390f35b3480156102a9575f80fd5b506102b261092b565b6040516102bf9190612ff0565b60405180910390f35b3480156102d3575f80fd5b506102ee60048036038101906102e99190613009565b610942565b6040516102fb9190612e6d565b60405180910390f35b34801561030f575f80fd5b5061032a6004803603810190610325919061308c565b610970565b60405161033791906130c6565b60405180910390f35b34801561034b575f80fd5b50610366600480360381019061036191906130df565b61099a565b005b348015610373575f80fd5b5061037c6109bc565b6040516103899190613138565b60405180910390f35b34801561039d575f80fd5b506103a66109c4565b6040516103b39190612ff0565b60405180910390f35b3480156103c7575f80fd5b506103d06109d4565b6040516103dd91906130c6565b60405180910390f35b3480156103f1575f80fd5b5061040c600480360381019061040791906130df565b6109e2565b005b348015610419575f80fd5b50610422610a5d565b005b34801561042f575f80fd5b5061044a60048036038101906104459190613151565b610a92565b005b610466600480360381019061046191906132a8565b610aa6565b005b348015610473575f80fd5b5061047c610ac5565b60405161048991906130c6565b60405180910390f35b34801561049d575f80fd5b506104a6610af6565b6040516104b39190612e6d565b60405180910390f35b3480156104c7575f80fd5b506104e260048036038101906104dd9190613302565b610b18565b005b3480156104ef575f80fd5b5061050a60048036038101906105059190613302565b610bc2565b6040516105179190612ff0565b60405180910390f35b34801561052b575f80fd5b5061054660048036038101906105419190612fa3565b610c15565b005b348015610553575f80fd5b5061056e60048036038101906105699190613302565b610c35565b60405161057b9190612ff0565b60405180910390f35b34801561058f575f80fd5b50610598610c46565b005b3480156105a5575f80fd5b506105ae610c7b565b6040516105c1979695949392919061342d565b60405180910390f35b3480156105d5575f80fd5b506105f060048036038101906105eb91906130df565b610d84565b6040516105fd9190612e6d565b60405180910390f35b348015610611575f80fd5b5061061a610df5565b6040516106279190612ef6565b60405180910390f35b34801561063b575f80fd5b50610644610e93565b60405161065191906130c6565b60405180910390f35b348015610665575f80fd5b50610680600480360381019061067b9190612fa3565b610e99565b60405161068d9190612e6d565b60405180910390f35b3480156106a1575f80fd5b506106aa610ebb565b6040516106b79190612ef6565b60405180910390f35b3480156106cb575f80fd5b506106e660048036038101906106e191906134d9565b610ef4565b005b3480156106f3575f80fd5b506106fc611039565b60405161070991906130c6565b60405180910390f35b34801561071d575f80fd5b50610738600480360381019061073391906130df565b61105d565b005b348015610745575f80fd5b50610760600480360381019061075b9190613576565b61107f565b60405161076d9190612ff0565b60405180910390f35b348015610781575f80fd5b5061078a61110f565b60405161079791906130c6565b60405180910390f35b3480156107ab575f80fd5b506107b4611133565b6040516107c191906130c6565b60405180910390f35b3480156107d5575f80fd5b506107f060048036038101906107eb91906135b4565b611157565b005b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061086457506108638261144a565b5b9050919050565b60605f6108766114b3565b905080600301805461088790613645565b80601f01602080910402602001604051908101604052809291908181526020018280546108b390613645565b80156108fe5780601f106108d5576101008083540402835291602001916108fe565b820191905f5260205f20905b8154815290600101906020018083116108e157829003601f168201915b505050505091505090565b5f806109136114da565b90506109208185856114e1565b600191505092915050565b5f806109356114b3565b9050806002015491505090565b5f8061094c6114da565b90506109598582856114f3565b610964858585611585565b60019150509392505050565b5f8061097a611675565b9050805f015f8481526020019081526020015f2060010154915050919050565b6109a382610970565b6109ac8161169c565b6109b683836116b0565b50505050565b5f6012905090565b6b204fce5e3e2502611000000081565b5f6109dd6117a8565b905090565b6109ea6114da565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a4e576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a5882826117b6565b505050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610a878161169c565b610a8f6118ae565b50565b610aa3610a9d6114da565b8261191c565b50565b610aae61199b565b610ab782611a81565b610ac18282611aaf565b5050565b5f610ace611bcd565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b905090565b5f80610b00611c54565b9050805f015f9054906101000a900460ff1691505090565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610b428161169c565b5f8054906101000a900460ff1615610b8f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b86906136e5565b60405180910390fd5b610ba5826b204fce5e3e25026110000000611c7b565b60015f806101000a81548160ff0219169083151502179055505050565b5f80610bcc6114b3565b9050805f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054915050919050565b610c2782610c216114da565b836114f3565b610c31828261191c565b5050565b5f610c3f82611cfa565b9050919050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610c708161169c565b610c78611d4d565b50565b5f6060805f805f60605f610c8d611dbc565b90505f801b815f0154148015610ca857505f801b8160010154145b610ce7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cde9061374d565b60405180910390fd5b610cef611de3565b610cf7611e81565b46305f801b5f67ffffffffffffffff811115610d1657610d15613184565b5b604051908082528060200260200182016040528015610d445781602001602082028036833780820191505090505b507f0f0000000000000000000000000000000000000000000000000000000000000095949392919097509750975097509750975097505090919293949596565b5f80610d8e611675565b9050805f015f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1691505092915050565b60605f610e006114b3565b9050806004018054610e1190613645565b80601f0160208091040260200160405190810160405280929190818152602001828054610e3d90613645565b8015610e885780601f10610e5f57610100808354040283529160200191610e88565b820191905f5260205f20905b815481529060010190602001808311610e6b57829003601f168201915b505050505091505090565b5f801b81565b5f80610ea36114da565b9050610eb0818585611585565b600191505092915050565b6040518060400160405280600581526020017f352e302e3000000000000000000000000000000000000000000000000000000081525081565b83421115610f3957836040517f62791302000000000000000000000000000000000000000000000000000000008152600401610f309190612ff0565b60405180910390fd5b5f7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610f678c611f1f565b89604051602001610f7d9695949392919061376b565b6040516020818303038152906040528051906020012090505f610f9f82611f7f565b90505f610fae82878787611f98565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461102257808a6040517f4b800e460000000000000000000000000000000000000000000000000000000081526004016110199291906137ca565b60405180910390fd5b61102d8a8a8a6114e1565b50505050505050505050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b61106682610970565b61106f8161169c565b61107983836117b6565b50505050565b5f806110896114b3565b9050806001015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205491505092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b7f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e381565b5f611160611fc6565b90505f815f0160089054906101000a900460ff161590505f825f015f9054906101000a900467ffffffffffffffff1690505f808267ffffffffffffffff161480156111a85750825b90505f60018367ffffffffffffffff161480156111db57505f3073ffffffffffffffffffffffffffffffffffffffff163b145b9050811580156111e9575080155b15611220576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001855f015f6101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550831561126d576001855f0160086101000a81548160ff0219169083151502179055505b6112e16040518060400160405280600581526020017f5261796c730000000000000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f524c530000000000000000000000000000000000000000000000000000000000815250611fed565b6112e9612003565b6112f161200d565b6112f961201f565b6113376040518060400160405280600581526020017f5261796c73000000000000000000000000000000000000000000000000000000815250612029565b61133f612073565b61134b5f801b8a6116b0565b506113767f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a896116b0565b506113a17f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e3876116b0565b506113cc7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6886116b0565b505f805f6101000a81548160ff021916908315150217905550831561143f575f855f0160086101000a81548160ff0219169083151502179055507fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d260016040516114369190613846565b60405180910390a15b505050505050505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00905090565b5f33905090565b6114ee838383600161207d565b505050565b5f6114fe848461107f565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461157f5781811015611570578281836040517ffb8f41b20000000000000000000000000000000000000000000000000000000081526004016115679392919061385f565b60405180910390fd5b61157e84848484035f61207d565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036115f5575f6040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081526004016115ec9190613894565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611665575f6040517fec442f0500000000000000000000000000000000000000000000000000000000815260040161165c9190613894565b60405180910390fd5b61167083838361225a565b505050565b5f7f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800905090565b6116ad816116a86114da565b61226a565b50565b5f806116ba611675565b90506116c68484610d84565b61179d576001815f015f8681526020019081526020015f205f015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506117396114da565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16857f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a460019150506117a2565b5f9150505b92915050565b5f6117b16122bb565b905090565b5f806117c0611675565b90506117cc8484610d84565b156118a3575f815f015f8681526020019081526020015f205f015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555061183f6114da565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16857ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a460019150506118a8565b5f9150505b92915050565b6118b661231e565b5f6118bf611c54565b90505f815f015f6101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6119046114da565b6040516119119190613894565b60405180910390a150565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361198c575f6040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081526004016119839190613894565b60405180910390fd5b611997825f8361225a565b5050565b7f000000000000000000000000b5f7b021a78f470d31d762c1dda05ea549904fbd73ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff161480611a4857507f000000000000000000000000b5f7b021a78f470d31d762c1dda05ea549904fbd73ffffffffffffffffffffffffffffffffffffffff16611a2f61235e565b73ffffffffffffffffffffffffffffffffffffffff1614155b15611a7f576040517fe07c8dba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e3611aab8161169c565b5050565b8173ffffffffffffffffffffffffffffffffffffffff166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611b1757506040513d601f19601f82011682018060405250810190611b1491906138c1565b60015b611b5857816040517f4c9c8ce3000000000000000000000000000000000000000000000000000000008152600401611b4f9190613894565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b8114611bbe57806040517faa1d49a4000000000000000000000000000000000000000000000000000000008152600401611bb591906130c6565b60405180910390fd5b611bc883836123b1565b505050565b7f000000000000000000000000b5f7b021a78f470d31d762c1dda05ea549904fbd73ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614611c52576040517fe07c8dba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f7fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300905090565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ceb575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401611ce29190613894565b60405180910390fd5b611cf65f838361225a565b5050565b5f80611d04612423565b9050805f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054915050919050565b611d5561244a565b5f611d5e611c54565b90506001815f015f6101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611da46114da565b604051611db19190613894565b60405180910390a150565b5f7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100905090565b60605f611dee611dbc565b9050806002018054611dff90613645565b80601f0160208091040260200160405190810160405280929190818152602001828054611e2b90613645565b8015611e765780601f10611e4d57610100808354040283529160200191611e76565b820191905f5260205f20905b815481529060010190602001808311611e5957829003601f168201915b505050505091505090565b60605f611e8c611dbc565b9050806003018054611e9d90613645565b80601f0160208091040260200160405190810160405280929190818152602001828054611ec990613645565b8015611f145780601f10611eeb57610100808354040283529160200191611f14565b820191905f5260205f20905b815481529060010190602001808311611ef757829003601f168201915b505050505091505090565b5f80611f29612423565b9050805f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f81548092919060010191905055915050919050565b5f611f91611f8b6117a8565b8361248b565b9050919050565b5f805f80611fa8888888886124cb565b925092509250611fb882826125b2565b829350505050949350505050565b5f7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00905090565b611ff5612714565b611fff8282612754565b5050565b61200b612714565b565b612015612714565b61201d612790565b565b612027612714565b565b612031612714565b612070816040518060400160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152506127c0565b50565b61207b612714565b565b5f6120866114b3565b90505f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036120f8575f6040517fe602df050000000000000000000000000000000000000000000000000000000081526004016120ef9190613894565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612168575f6040517f94280d6200000000000000000000000000000000000000000000000000000000815260040161215f9190613894565b60405180910390fd5b82816001015f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508115612253578373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258560405161224a9190612ff0565b60405180910390a35b5050505050565b612265838383612811565b505050565b6122748282610d84565b6122b75780826040517fe2517d3f0000000000000000000000000000000000000000000000000000000081526004016122ae9291906138ec565b60405180910390fd5b5050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6122e5612829565b6122ed61289f565b4630604051602001612303959493929190613913565b60405160208183030381529060405280519060200120905090565b612326610af6565b61235c576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f61238a7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b612916565b5f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6123ba8261291f565b8173ffffffffffffffffffffffffffffffffffffffff167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b60405160405180910390a25f815111156124165761241082826129e8565b5061241f565b61241e612a68565b5b5050565b5f7f5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb00905090565b612452610af6565b15612489576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f6040517f190100000000000000000000000000000000000000000000000000000000000081528360028201528260228201526042812091505092915050565b5f805f7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0845f1c1115612507575f6003859250925092506125a8565b5f6001888888886040515f815260200160405260405161252a9493929190613964565b6020604051602081039080840390855afa15801561254a573d5f803e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361259b575f60015f801b935093509350506125a8565b805f805f1b935093509350505b9450945094915050565b5f60038111156125c5576125c46139a7565b5b8260038111156125d8576125d76139a7565b5b031561271057600160038111156125f2576125f16139a7565b5b826003811115612605576126046139a7565b5b0361263c576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600260038111156126505761264f6139a7565b5b826003811115612663576126626139a7565b5b036126a757805f1c6040517ffce698f700000000000000000000000000000000000000000000000000000000815260040161269e9190612ff0565b60405180910390fd5b6003808111156126ba576126b96139a7565b5b8260038111156126cd576126cc6139a7565b5b0361270f57806040517fd78bce0c00000000000000000000000000000000000000000000000000000000815260040161270691906130c6565b60405180910390fd5b5b5050565b61271c612aa4565b612752576040517fd7e6bcf800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b61275c612714565b5f6127656114b3565b9050828160030190816127789190613b68565b508181600401908161278a9190613b68565b50505050565b612798612714565b5f6127a1611c54565b90505f815f015f6101000a81548160ff02191690831515021790555050565b6127c8612714565b5f6127d1611dbc565b9050828160020190816127e49190613b68565b50818160030190816127f69190613b68565b505f801b815f01819055505f801b8160010181905550505050565b61281961244a565b612824838383612ac2565b505050565b5f80612833611dbc565b90505f61283e611de3565b90505f8151111561285a5780805190602001209250505061289c565b5f825f015490505f801b81146128755780935050505061289c565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47093505050505b90565b5f806128a9611dbc565b90505f6128b4611e81565b90505f815111156128d057808051906020012092505050612913565b5f826001015490505f801b81146128ec57809350505050612913565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47093505050505b90565b5f819050919050565b5f8173ffffffffffffffffffffffffffffffffffffffff163b0361297a57806040517f4c9c8ce30000000000000000000000000000000000000000000000000000000081526004016129719190613894565b60405180910390fd5b806129a67f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b612916565b5f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60605f808473ffffffffffffffffffffffffffffffffffffffff1684604051612a119190613c7b565b5f60405180830381855af49150503d805f8114612a49576040519150601f19603f3d011682016040523d82523d5f602084013e612a4e565b606091505b5091509150612a5e858383612cf1565b9250505092915050565b5f341115612aa2576040517fb398979f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f612aad611fc6565b5f0160089054906101000a900460ff16905090565b5f612acb6114b3565b90505f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612b1f5781816002015f828254612b139190613cbe565b92505081905550612bf1565b5f815f015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905082811015612baa578481846040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401612ba19392919061385f565b60405180910390fd5b828103825f015f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612c3a5781816002015f8282540392505081905550612c86565b81815f015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612ce39190612ff0565b60405180910390a350505050565b606082612d0657612d0182612d7e565b612d76565b5f8251148015612d2c57505f8473ffffffffffffffffffffffffffffffffffffffff163b145b15612d6e57836040517f9996b315000000000000000000000000000000000000000000000000000000008152600401612d659190613894565b60405180910390fd5b819050612d77565b5b9392505050565b5f81511115612d905780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612e0781612dd3565b8114612e11575f80fd5b50565b5f81359050612e2281612dfe565b92915050565b5f60208284031215612e3d57612e3c612dcb565b5b5f612e4a84828501612e14565b91505092915050565b5f8115159050919050565b612e6781612e53565b82525050565b5f602082019050612e805f830184612e5e565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f612ec882612e86565b612ed28185612e90565b9350612ee2818560208601612ea0565b612eeb81612eae565b840191505092915050565b5f6020820190508181035f830152612f0e8184612ebe565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612f3f82612f16565b9050919050565b612f4f81612f35565b8114612f59575f80fd5b50565b5f81359050612f6a81612f46565b92915050565b5f819050919050565b612f8281612f70565b8114612f8c575f80fd5b50565b5f81359050612f9d81612f79565b92915050565b5f8060408385031215612fb957612fb8612dcb565b5b5f612fc685828601612f5c565b9250506020612fd785828601612f8f565b9150509250929050565b612fea81612f70565b82525050565b5f6020820190506130035f830184612fe1565b92915050565b5f805f606084860312156130205761301f612dcb565b5b5f61302d86828701612f5c565b935050602061303e86828701612f5c565b925050604061304f86828701612f8f565b9150509250925092565b5f819050919050565b61306b81613059565b8114613075575f80fd5b50565b5f8135905061308681613062565b92915050565b5f602082840312156130a1576130a0612dcb565b5b5f6130ae84828501613078565b91505092915050565b6130c081613059565b82525050565b5f6020820190506130d95f8301846130b7565b92915050565b5f80604083850312156130f5576130f4612dcb565b5b5f61310285828601613078565b925050602061311385828601612f5c565b9150509250929050565b5f60ff82169050919050565b6131328161311d565b82525050565b5f60208201905061314b5f830184613129565b92915050565b5f6020828403121561316657613165612dcb565b5b5f61317384828501612f8f565b91505092915050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6131ba82612eae565b810181811067ffffffffffffffff821117156131d9576131d8613184565b5b80604052505050565b5f6131eb612dc2565b90506131f782826131b1565b919050565b5f67ffffffffffffffff82111561321657613215613184565b5b61321f82612eae565b9050602081019050919050565b828183375f83830152505050565b5f61324c613247846131fc565b6131e2565b90508281526020810184848401111561326857613267613180565b5b61327384828561322c565b509392505050565b5f82601f83011261328f5761328e61317c565b5b813561329f84826020860161323a565b91505092915050565b5f80604083850312156132be576132bd612dcb565b5b5f6132cb85828601612f5c565b925050602083013567ffffffffffffffff8111156132ec576132eb612dcf565b5b6132f88582860161327b565b9150509250929050565b5f6020828403121561331757613316612dcb565b5b5f61332484828501612f5c565b91505092915050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6133618161332d565b82525050565b61337081612f35565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6133a881612f70565b82525050565b5f6133b9838361339f565b60208301905092915050565b5f602082019050919050565b5f6133db82613376565b6133e58185613380565b93506133f083613390565b805f5b8381101561342057815161340788826133ae565b9750613412836133c5565b9250506001810190506133f3565b5085935050505092915050565b5f60e0820190506134405f83018a613358565b81810360208301526134528189612ebe565b905081810360408301526134668188612ebe565b90506134756060830187612fe1565b6134826080830186613367565b61348f60a08301856130b7565b81810360c08301526134a181846133d1565b905098975050505050505050565b6134b88161311d565b81146134c2575f80fd5b50565b5f813590506134d3816134af565b92915050565b5f805f805f805f60e0888a0312156134f4576134f3612dcb565b5b5f6135018a828b01612f5c565b97505060206135128a828b01612f5c565b96505060406135238a828b01612f8f565b95505060606135348a828b01612f8f565b94505060806135458a828b016134c5565b93505060a06135568a828b01613078565b92505060c06135678a828b01613078565b91505092959891949750929550565b5f806040838503121561358c5761358b612dcb565b5b5f61359985828601612f5c565b92505060206135aa85828601612f5c565b9150509250929050565b5f805f80608085870312156135cc576135cb612dcb565b5b5f6135d987828801612f5c565b94505060206135ea87828801612f5c565b93505060406135fb87828801612f5c565b925050606061360c87828801612f5c565b91505092959194509250565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061365c57607f821691505b60208210810361366f5761366e613618565b5b50919050565b7f5261796c73546f6b656e3a204d696e742068617320616c7265616479206265655f8201527f6e20706572666f726d6564000000000000000000000000000000000000000000602082015250565b5f6136cf602b83612e90565b91506136da82613675565b604082019050919050565b5f6020820190508181035f8301526136fc816136c3565b9050919050565b7f4549503731323a20556e696e697469616c697a656400000000000000000000005f82015250565b5f613737601583612e90565b915061374282613703565b602082019050919050565b5f6020820190508181035f8301526137648161372b565b9050919050565b5f60c08201905061377e5f8301896130b7565b61378b6020830188613367565b6137986040830187613367565b6137a56060830186612fe1565b6137b26080830185612fe1565b6137bf60a0830184612fe1565b979650505050505050565b5f6040820190506137dd5f830185613367565b6137ea6020830184613367565b9392505050565b5f819050919050565b5f67ffffffffffffffff82169050919050565b5f819050919050565b5f61383061382b613826846137f1565b61380d565b6137fa565b9050919050565b61384081613816565b82525050565b5f6020820190506138595f830184613837565b92915050565b5f6060820190506138725f830186613367565b61387f6020830185612fe1565b61388c6040830184612fe1565b949350505050565b5f6020820190506138a75f830184613367565b92915050565b5f815190506138bb81613062565b92915050565b5f602082840312156138d6576138d5612dcb565b5b5f6138e3848285016138ad565b91505092915050565b5f6040820190506138ff5f830185613367565b61390c60208301846130b7565b9392505050565b5f60a0820190506139265f8301886130b7565b61393360208301876130b7565b61394060408301866130b7565b61394d6060830185612fe1565b61395a6080830184613367565b9695505050505050565b5f6080820190506139775f8301876130b7565b6139846020830186613129565b61399160408301856130b7565b61399e60608301846130b7565b95945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302613a307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826139f5565b613a3a86836139f5565b95508019841693508086168417925050509392505050565b5f613a6c613a67613a6284612f70565b61380d565b612f70565b9050919050565b5f819050919050565b613a8583613a52565b613a99613a9182613a73565b848454613a01565b825550505050565b5f90565b613aad613aa1565b613ab8818484613a7c565b505050565b5b81811015613adb57613ad05f82613aa5565b600181019050613abe565b5050565b601f821115613b2057613af1816139d4565b613afa846139e6565b81016020851015613b09578190505b613b1d613b15856139e6565b830182613abd565b50505b505050565b5f82821c905092915050565b5f613b405f1984600802613b25565b1980831691505092915050565b5f613b588383613b31565b9150826002028217905092915050565b613b7182612e86565b67ffffffffffffffff811115613b8a57613b89613184565b5b613b948254613645565b613b9f828285613adf565b5f60209050601f831160018114613bd0575f8415613bbe578287015190505b613bc88582613b4d565b865550613c2f565b601f198416613bde866139d4565b5f5b82811015613c0557848901518255600182019150602085019450602081019050613be0565b86831015613c225784890151613c1e601f891682613b31565b8355505b6001600288020188555050505b505050505050565b5f81519050919050565b5f81905092915050565b5f613c5582613c37565b613c5f8185613c41565b9350613c6f818560208601612ea0565b80840191505092915050565b5f613c868284613c4b565b915081905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f613cc882612f70565b9150613cd383612f70565b9250828201905080821115613ceb57613cea613c91565b5b9291505056fea2646970667358221220be5d7e59a28195315b3d6fb01d3d3ebcce894ab0a564f8fd27a8b08fecc34a0b64736f6c634300081a0033
Deployed Bytecode Sourcemap
129800:1987:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48800:204;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;23485:147;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26058:190;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24699:155;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26826:249;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50152:194;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50656:138;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;24550:84;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;130230:66;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104225:114;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51793:251;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;131374:77;;;;;;;;;;;;;:::i;:::-;;34039:89;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;127220:217;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;126753:136;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37323:148;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;131009:276;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;24917:174;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34457:161;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103956:156;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;131293:73;;;;;;;;;;;;;:::i;:::-;;95451:931;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;49096:210;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;23751:151;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47640:49;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25296:182;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;124821:58;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103202:695;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;130159:62;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51087:140;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;25541:198;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;130017:62;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;130086:66;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;130381:620;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;48800:204;48885:4;48924:32;48909:47;;;:11;:47;;;;:87;;;;48960:36;48984:11;48960:23;:36::i;:::-;48909:87;48902:94;;48800:204;;;:::o;23485:147::-;23530:13;23556:22;23581:18;:16;:18::i;:::-;23556:43;;23617:1;:7;;23610:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23485:147;:::o;26058:190::-;26131:4;26148:13;26164:12;:10;:12::i;:::-;26148:28;;26187:31;26196:5;26203:7;26212:5;26187:8;:31::i;:::-;26236:4;26229:11;;;26058:190;;;;:::o;24699:155::-;24751:7;24771:22;24796:18;:16;:18::i;:::-;24771:43;;24832:1;:14;;;24825:21;;;24699:155;:::o;26826:249::-;26913:4;26930:15;26948:12;:10;:12::i;:::-;26930:30;;26971:37;26987:4;26993:7;27002:5;26971:15;:37::i;:::-;27019:26;27029:4;27035:2;27039:5;27019:9;:26::i;:::-;27063:4;27056:11;;;26826:249;;;;;:::o;50152:194::-;50217:7;50237:30;50270:26;:24;:26::i;:::-;50237:59;;50314:1;:8;;:14;50323:4;50314:14;;;;;;;;;;;:24;;;50307:31;;;50152:194;;;:::o;50656:138::-;50730:18;50743:4;50730:12;:18::i;:::-;48536:16;48547:4;48536:10;:16::i;:::-;50761:25:::1;50772:4;50778:7;50761:10;:25::i;:::-;;50656:138:::0;;;:::o;24550:84::-;24599:5;24624:2;24617:9;;24550:84;:::o;130230:66::-;130267:29;130230:66;:::o;104225:114::-;104284:7;104311:20;:18;:20::i;:::-;104304:27;;104225:114;:::o;51793:251::-;51909:12;:10;:12::i;:::-;51887:34;;:18;:34;;;51883:104;;51945:30;;;;;;;;;;;;;;51883:104;51999:37;52011:4;52017:18;51999:11;:37::i;:::-;;51793:251;;:::o;131374:77::-;130055:24;48536:16;48547:4;48536:10;:16::i;:::-;131433:10:::1;:8;:10::i;:::-;131374:77:::0;:::o;34039:89::-;34094:26;34100:12;:10;:12::i;:::-;34114:5;34094;:26::i;:::-;34039:89;:::o;127220:217::-;125675:13;:11;:13::i;:::-;127336:36:::1;127354:17;127336;:36::i;:::-;127383:46;127405:17;127424:4;127383:21;:46::i;:::-;127220:217:::0;;:::o;126753:136::-;126822:7;125955:20;:18;:20::i;:::-;117591:66:::1;126849:32;;126842:39;;126753:136:::0;:::o;37323:148::-;37370:4;37387:25;37415:21;:19;:21::i;:::-;37387:49;;37454:1;:9;;;;;;;;;;;;37447:16;;;37323:148;:::o;131009:276::-;130197:24;48536:16;48547:4;48536:10;:16::i;:::-;131090:7:::1;::::0;::::1;;;;;;;;131089:8;131081:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;131156:27;131162:8;130267:29;131156:5;:27::i;:::-;131251:4;131241:7;::::0;:14:::1;;;;;;;;;;;;;;;;;;131009:276:::0;;:::o;24917:174::-;24982:7;25002:22;25027:18;:16;:18::i;:::-;25002:43;;25063:1;:11;;:20;25075:7;25063:20;;;;;;;;;;;;;;;;25056:27;;;24917:174;;;:::o;34457:161::-;34533:45;34549:7;34558:12;:10;:12::i;:::-;34572:5;34533:15;:45::i;:::-;34589:21;34595:7;34604:5;34589;:21::i;:::-;34457:161;;:::o;103956:156::-;104058:7;104085:19;104098:5;104085:12;:19::i;:::-;104078:26;;103956:156;;;:::o;131293:73::-;130055:24;48536:16;48547:4;48536:10;:16::i;:::-;131350:8:::1;:6;:8::i;:::-;131293:73:::0;:::o;95451:931::-;95554:13;95582:18;95615:21;95651:15;95681:25;95721:12;95748:27;95803:23;95829:19;:17;:19::i;:::-;95803:45;;96089:1;96072:18;;:1;:13;;;:18;:43;;;;;96114:1;96094:21;;:1;:16;;;:21;96072:43;96064:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;96207:13;:11;:13::i;:::-;96235:16;:14;:16::i;:::-;96266:13;96302:4;96330:1;96322:10;;96361:1;96347:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96154:220;;;;;;;;;;;;;;;;;;;;;;95451:931;;;;;;;:::o;49096:210::-;49173:4;49190:30;49223:26;:24;:26::i;:::-;49190:59;;49267:1;:8;;:14;49276:4;49267:14;;;;;;;;;;;:22;;:31;49290:7;49267:31;;;;;;;;;;;;;;;;;;;;;;;;;49260:38;;;49096:210;;;;:::o;23751:151::-;23798:13;23824:22;23849:18;:16;:18::i;:::-;23824:43;;23885:1;:9;;23878:16;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23751:151;:::o;47640:49::-;47685:4;47640:49;;;:::o;25296:182::-;25365:4;25382:13;25398:12;:10;:12::i;:::-;25382:28;;25421:27;25431:5;25438:2;25442:5;25421:9;:27::i;:::-;25466:4;25459:11;;;25296:182;;;;:::o;124821:58::-;;;;;;;;;;;;;;;;;;;:::o;103202:695::-;103432:8;103414:15;:26;103410:99;;;103488:8;103464:33;;;;;;;;;;;:::i;:::-;;;;;;;;103410:99;103521:18;102358:95;103580:5;103587:7;103596:5;103603:16;103613:5;103603:9;:16::i;:::-;103621:8;103552:78;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;103542:89;;;;;;103521:110;;103644:12;103659:28;103676:10;103659:16;:28::i;:::-;103644:43;;103700:14;103717:28;103731:4;103737:1;103740;103743;103717:13;:28::i;:::-;103700:45;;103770:5;103760:15;;:6;:15;;;103756:90;;103820:6;103828:5;103799:35;;;;;;;;;;;;:::i;:::-;;;;;;;;103756:90;103858:31;103867:5;103874:7;103883:5;103858:8;:31::i;:::-;103399:498;;;103202:695;;;;;;;:::o;130159:62::-;130197:24;130159:62;:::o;51087:140::-;51162:18;51175:4;51162:12;:18::i;:::-;48536:16;48547:4;48536:10;:16::i;:::-;51193:26:::1;51205:4;51211:7;51193:11;:26::i;:::-;;51087:140:::0;;;:::o;25541:198::-;25621:7;25641:22;25666:18;:16;:18::i;:::-;25641:43;;25702:1;:13;;:20;25716:5;25702:20;;;;;;;;;;;;;;;:29;25723:7;25702:29;;;;;;;;;;;;;;;;25695:36;;;25541:198;;;;:::o;130017:62::-;130055:24;130017:62;:::o;130086:66::-;130126:26;130086:66;:::o;130381:620::-;7917:30;7950:26;:24;:26::i;:::-;7917:59;;8041:19;8064:1;:15;;;;;;;;;;;;8063:16;8041:38;;8090:18;8111:1;:14;;;;;;;;;;;;8090:35;;8476:17;8511:1;8496:11;:16;;;:34;;;;;8516:14;8496:34;8476:54;;8541:17;8576:1;8561:11;:16;;;:50;;;;;8610:1;8589:4;8581:25;;;:30;8561:50;8541:70;;8629:12;8628:13;:30;;;;;8646:12;8645:13;8628:30;8624:93;;;8682:23;;;;;;;;;;;;;;8624:93;8744:1;8727;:14;;;:18;;;;;;;;;;;;;;;;;;8760:14;8756:69;;;8809:4;8791:1;:15;;;:22;;;;;;;;;;;;;;;;;;8756:69;130546:28:::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;::::0;:12:::1;:28::i;:::-;130585:22;:20;:22::i;:::-;130618;:20;:22::i;:::-;130651;:20;:22::i;:::-;130684:27;;;;;;;;;;;;;;;;;::::0;:18:::1;:27::i;:::-;130722:24;:22;:24::i;:::-;130759:44;47685:4;130770:18:::0;::::1;130790:12;130759:10;:44::i;:::-;;130814:31;130055:24;130838:6;130814:10;:31::i;:::-;;130856:35;130126:26;130882:8;130856:10;:35::i;:::-;;130902:31;130197:24;130926:6;130902:10;:31::i;:::-;;130956:5;130946:7:::0;::::1;:15;;;;;;;;;;;;;;;;;;8851:14:::0;8847:104;;;8900:5;8882:1;:15;;;:23;;;;;;;;;;;;;;;;;;8925:14;8937:1;8925:14;;;;;;:::i;:::-;;;;;;;;8847:104;7849:1109;;;;;130381:620;;;;:::o;45352:148::-;45428:4;45467:25;45452:40;;;:11;:40;;;;45445:47;;45352:148;;;:::o;22691:157::-;22741:22;22810:20;22800:30;;22691:157;:::o;13686:98::-;13739:7;13766:10;13759:17;;13686:98;:::o;30949:130::-;31034:37;31043:5;31050:7;31059:5;31066:4;31034:8;:37::i;:::-;30949:130;;;:::o;32721:487::-;32821:24;32848:25;32858:5;32865:7;32848:9;:25::i;:::-;32821:52;;32908:17;32888:16;:37;32884:317;;32965:5;32946:16;:24;32942:132;;;33025:7;33034:16;33052:5;32998:60;;;;;;;;;;;;;:::i;:::-;;;;;;;;32942:132;33117:57;33126:5;33133:7;33161:5;33142:16;:24;33168:5;33117:8;:57::i;:::-;32884:317;32810:398;32721:487;;;:::o;27460:308::-;27560:1;27544:18;;:4;:18;;;27540:88;;27613:1;27586:30;;;;;;;;;;;:::i;:::-;;;;;;;;27540:88;27656:1;27642:16;;:2;:16;;;27638:88;;27711:1;27682:32;;;;;;;;;;;:::i;:::-;;;;;;;;27638:88;27736:24;27744:4;27750:2;27754:5;27736:7;:24::i;:::-;27460:308;;;:::o;48121:181::-;48179:30;48256:28;48246:38;;48121:181;:::o;49521:105::-;49588:30;49599:4;49605:12;:10;:12::i;:::-;49588:10;:30::i;:::-;49521:105;:::o;52742:396::-;52819:4;52836:30;52869:26;:24;:26::i;:::-;52836:59;;52911:22;52919:4;52925:7;52911;:22::i;:::-;52906:225;;52984:4;52950:1;:8;;:14;52959:4;52950:14;;;;;;;;;;;:22;;:31;52973:7;52950:31;;;;;;;;;;;;;;;;:38;;;;;;;;;;;;;;;;;;53035:12;:10;:12::i;:::-;53008:40;;53026:7;53008:40;;53020:4;53008:40;;;;;;;;;;53070:4;53063:11;;;;;52906:225;53114:5;53107:12;;;52742:396;;;;;:::o;94263:111::-;94316:7;94343:23;:21;:23::i;:::-;94336:30;;94263:111;:::o;53382:397::-;53460:4;53477:30;53510:26;:24;:26::i;:::-;53477:59;;53551:22;53559:4;53565:7;53551;:22::i;:::-;53547:225;;;53624:5;53590:1;:8;;:14;53599:4;53590:14;;;;;;;;;;;:22;;:31;53613:7;53590:31;;;;;;;;;;;;;;;;:39;;;;;;;;;;;;;;;;;;53676:12;:10;:12::i;:::-;53649:40;;53667:7;53649:40;;53661:4;53649:40;;;;;;;;;;53711:4;53704:11;;;;;53547:225;53755:5;53748:12;;;53382:397;;;;;:::o;38348:182::-;37187:16;:14;:16::i;:::-;38407:25:::1;38435:21;:19;:21::i;:::-;38407:49;;38479:5;38467:1;:9;;;:17;;;;;;;;;;;;;;;;;;38500:22;38509:12;:10;:12::i;:::-;38500:22;;;;;;:::i;:::-;;;;;;;;38396:134;38348:182::o:0;30185:211::-;30275:1;30256:21;;:7;:21;;;30252:91;;30328:1;30301:30;;;;;;;;;;;:::i;:::-;;;;;;;;30252:91;30353:35;30361:7;30378:1;30382:5;30353:7;:35::i;:::-;30185:211;;:::o;127671:319::-;127762:6;127745:23;;127753:4;127745:23;;;:121;;;;127860:6;127824:42;;:32;:30;:32::i;:::-;:42;;;;127745:121;127727:256;;;127942:29;;;;;;;;;;;;;;127727:256;127671:319::o;131459:114::-;130126:26;48536:16;48547:4;48536:10;:16::i;:::-;131459:114;;:::o;129164:548::-;129282:17;129264:50;;;:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;129260:445;;129675:17;129633:60;;;;;;;;;;;:::i;:::-;;;;;;;;129260:445;117591:66;129367:32;;129359:4;:40;129355:122;;129456:4;129427:34;;;;;;;;;;;:::i;:::-;;;;;;;;129355:122;129491:54;129521:17;129540:4;129491:29;:54::i;:::-;129317:240;129164:548;;:::o;128113:218::-;128197:6;128180:23;;128188:4;128180:23;;;128176:148;;128283:29;;;;;;;;;;;;;;128176:148;128113:218::o;35713:166::-;35766:25;35838:23;35828:33;;35713:166;:::o;29644:213::-;29734:1;29715:21;;:7;:21;;;29711:93;;29789:1;29760:32;;;;;;;;;;;:::i;:::-;;;;;;;;29711:93;29814:35;29830:1;29834:7;29843:5;29814:7;:35::i;:::-;29644:213;;:::o;100345:167::-;100405:7;100425:23;100451:19;:17;:19::i;:::-;100425:45;;100488:1;:9;;:16;100498:5;100488:16;;;;;;;;;;;;;;;;100481:23;;;100345:167;;;:::o;38027:180::-;36928:19;:17;:19::i;:::-;38087:25:::1;38115:21;:19;:21::i;:::-;38087:49;;38159:4;38147:1;:9;;;:16;;;;;;;;;;;;;;;;;;38179:20;38186:12;:10;:12::i;:::-;38179:20;;;;;;:::i;:::-;;;;;;;;38076:131;38027:180::o:0;92933:160::-;92984:23;93054:21;93044:31;;92933:160;:::o;96614:158::-;96668:13;96694:23;96720:19;:17;:19::i;:::-;96694:45;;96757:1;:7;;96750:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96614:158;:::o;97007:164::-;97064:13;97090:23;97116:19;:17;:19::i;:::-;97090:45;;97153:1;:10;;97146:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97007:164;:::o;100633:460::-;100693:7;100713:23;100739:19;:17;:19::i;:::-;100713:45;;101056:1;:9;;:16;101066:5;101056:16;;;;;;;;;;;;;;;;:18;;;;;;;;;;;;101049:25;;;100633:460;;;:::o;95217:178::-;95294:7;95321:66;95354:20;:18;:20::i;:::-;95376:10;95321:32;:66::i;:::-;95314:73;;95217:178;;;:::o;64716:264::-;64801:7;64822:17;64841:18;64861:16;64881:25;64892:4;64898:1;64901;64904;64881:10;:25::i;:::-;64821:85;;;;;;64917:28;64929:5;64936:8;64917:11;:28::i;:::-;64963:9;64956:16;;;;;64716:264;;;;;;:::o;12613:174::-;12671:30;12748:21;12738:31;;12613:174;:::o;23038:149::-;10755:20;:18;:20::i;:::-;23141:38:::1;23164:5;23171:7;23141:22;:38::i;:::-;23038:149:::0;;:::o;33764:66::-;10755:20;:18;:20::i;:::-;33764:66::o;39574:104::-;10755:20;:18;:20::i;:::-;39643:27:::1;:25;:27::i;:::-;39574:104::o:0;48580:66::-;10755:20;:18;:20::i;:::-;48580:66::o;102927:127::-;10755:20;:18;:20::i;:::-;103012:34:::1;103036:4;103012:34;;;;;;;;;;;;;;;;::::0;:23:::1;:34::i;:::-;102927:127:::0;:::o;126003:68::-;10755:20;:18;:20::i;:::-;126003:68::o;31930:499::-;32039:22;32064:18;:16;:18::i;:::-;32039:43;;32114:1;32097:19;;:5;:19;;;32093:91;;32169:1;32140:32;;;;;;;;;;;:::i;:::-;;;;;;;;32093:91;32217:1;32198:21;;:7;:21;;;32194:92;;32271:1;32243:31;;;;;;;;;;;:::i;:::-;;;;;;;;32194:92;32328:5;32296:1;:13;;:20;32310:5;32296:20;;;;;;;;;;;;;;;:29;32317:7;32296:29;;;;;;;;;;;;;;;:37;;;;32348:9;32344:78;;;32395:7;32379:31;;32388:5;32379:31;;;32404:5;32379:31;;;;;;:::i;:::-;;;;;;;;32344:78;32028:401;31930:499;;;;:::o;131581:203::-;131746:30;131760:4;131766:2;131770:5;131746:13;:30::i;:::-;131581:203;;;:::o;49762:201::-;49851:22;49859:4;49865:7;49851;:22::i;:::-;49846:110;;49930:7;49939:4;49897:47;;;;;;;;;;;;:::i;:::-;;;;;;;;49846:110;49762:201;;:::o;94382:193::-;94437:7;92270:95;94496:17;:15;:17::i;:::-;94515:20;:18;:20::i;:::-;94537:13;94560:4;94474:92;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;94464:103;;;;;;94457:110;;94382:193;:::o;37753:130::-;37817:8;:6;:8::i;:::-;37812:64;;37849:15;;;;;;;;;;;;;;37812:64;37753:130::o;118246:140::-;118298:7;118325:47;117591:66;118352:19;;118325:26;:47::i;:::-;:53;;;;;;;;;;;;118318:60;;118246:140;:::o;119089:344::-;119181:37;119200:17;119181:18;:37::i;:::-;119243:17;119234:27;;;;;;;;;;;;119292:1;119278:4;:11;:15;119274:152;;;119310:53;119339:17;119358:4;119310:28;:53::i;:::-;;119274:152;;;119396:18;:16;:18::i;:::-;119274:152;119089:344;;:::o;99958:160::-;100009:23;100079:21;100069:31;;99958:160;:::o;37544:132::-;37610:8;:6;:8::i;:::-;37606:63;;;37642:15;;;;;;;;;;;;;;37606:63;37544:132::o;89129:410::-;89222:14;89334:4;89328:11;89365:10;89360:3;89353:23;89413:15;89406:4;89401:3;89397:14;89390:39;89466:10;89459:4;89454:3;89450:14;89443:34;89516:4;89511:3;89501:20;89491:30;;89302:230;89129:410;;;;:::o;63021:1556::-;63152:7;63161:12;63175:7;64095:66;64090:1;64082:10;;:79;64078:166;;;64194:1;64198:30;64230:1;64178:54;;;;;;;;64078:166;64341:14;64358:24;64368:4;64374:1;64377;64380;64358:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64341:41;;64415:1;64397:20;;:6;:20;;;64393:115;;64450:1;64454:29;64493:1;64485:10;;64434:62;;;;;;;;;64393:115;64528:6;64536:20;64566:1;64558:10;;64520:49;;;;;;;63021:1556;;;;;;;;;:::o;65118:542::-;65214:20;65205:29;;;;;;;;:::i;:::-;;:5;:29;;;;;;;;:::i;:::-;;;65201:452;65251:7;65201:452;65312:29;65303:38;;;;;;;;:::i;:::-;;:5;:38;;;;;;;;:::i;:::-;;;65299:354;;65365:23;;;;;;;;;;;;;;65299:354;65419:35;65410:44;;;;;;;;:::i;:::-;;:5;:44;;;;;;;;:::i;:::-;;;65406:247;;65514:8;65506:17;;65478:46;;;;;;;;;;;:::i;:::-;;;;;;;;65406:247;65555:30;65546:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;65542:111;;65632:8;65609:32;;;;;;;;;;;:::i;:::-;;;;;;;;65542:111;65118:542;;;:::o;10915:145::-;10983:17;:15;:17::i;:::-;10978:75;;11024:17;;;;;;;;;;;;;;10978:75;10915:145::o;23195:220::-;10755:20;:18;:20::i;:::-;23308:22:::1;23333:18;:16;:18::i;:::-;23308:43;;23372:5;23362:1;:7;;:15;;;;;;:::i;:::-;;23400:7;23388:1;:9;;:19;;;;;;:::i;:::-;;23297:118;23195:220:::0;;:::o;36538:159::-;10755:20;:18;:20::i;:::-;36612:25:::1;36640:21;:19;:21::i;:::-;36612:49;;36684:5;36672:1;:9;;;:17;;;;;;;;;;;;;;;;;;36601:96;36538:159::o:0;93834:338::-;10755:20;:18;:20::i;:::-;93947:23:::1;93973:19;:17;:19::i;:::-;93947:45;;94013:4;94003:1;:7;;:14;;;;;;:::i;:::-;;94041:7;94028:1;:10;;:20;;;;;;:::i;:::-;;94132:1;94116:17:::0;::::1;:1;:13;;:17;;;;94163:1;94144:20:::0;::::1;:1;:16;;:20;;;;93936:236;93834:338:::0;;:::o;39901:147::-;36928:19;:17;:19::i;:::-;40010:30:::1;40024:4;40030:2;40034:5;40010:13;:30::i;:::-;39901:147:::0;;;:::o;97393:702::-;97443:7;97463:23;97489:19;:17;:19::i;:::-;97463:45;;97519:18;97540:13;:11;:13::i;:::-;97519:34;;97589:1;97574:4;97568:18;:22;97564:524;;;97630:4;97614:22;;;;;;97607:29;;;;;;97564:524;97894:18;97915:1;:13;;;97894:34;;97961:1;97947:15;;:10;:15;97943:134;;97990:10;97983:17;;;;;;;97943:134;98048:13;98041:20;;;;;97393:702;;:::o;98323:738::-;98376:7;98396:23;98422:19;:17;:19::i;:::-;98396:45;;98452:21;98476:16;:14;:16::i;:::-;98452:40;;98531:1;98513:7;98507:21;:25;98503:551;;;98572:7;98556:25;;;;;;98549:32;;;;;;98503:551;98848:21;98872:1;:16;;;98848:40;;98924:1;98907:18;;:13;:18;98903:140;;98953:13;98946:20;;;;;;;98903:140;99014:13;99007:20;;;;;98323:738;;:::o;114018:195::-;114079:21;114191:4;114181:14;;114018:195;;;:::o;118482:286::-;118593:1;118560:17;:29;;;:34;118556:121;;118647:17;118618:47;;;;;;;;;;;:::i;:::-;;;;;;;;118556:121;118743:17;118687:47;117591:66;118714:19;;118687:26;:47::i;:::-;:53;;;:73;;;;;;;;;;;;;;;;;;118482:286;:::o;110035:256::-;110118:12;110144;110158:23;110185:6;:19;;110205:4;110185:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;110143:67;;;;110228:55;110255:6;110263:7;110272:10;110228:26;:55::i;:::-;110221:62;;;;110035:256;;;;:::o;123013:126::-;123076:1;123064:9;:13;123060:72;;;123101:19;;;;;;;;;;;;;;123060:72;123013:126::o;12355:122::-;12405:4;12429:26;:24;:26::i;:::-;:40;;;;;;;;;;;;12422:47;;12355:122;:::o;28092:1199::-;28178:22;28203:18;:16;:18::i;:::-;28178:43;;28252:1;28236:18;;:4;:18;;;28232:558;;28392:5;28374:1;:14;;;:23;;;;;;;:::i;:::-;;;;;;;;28232:558;;;28430:19;28452:1;:11;;:17;28464:4;28452:17;;;;;;;;;;;;;;;;28430:39;;28502:5;28488:11;:19;28484:117;;;28560:4;28566:11;28579:5;28535:50;;;;;;;;;;;;;:::i;:::-;;;;;;;;28484:117;28758:5;28744:11;:19;28724:1;:11;;:17;28736:4;28724:17;;;;;;;;;;;;;;;:39;;;;28415:375;28232:558;28820:1;28806:16;;:2;:16;;;28802:439;;28990:5;28972:1;:14;;;:23;;;;;;;;;;;28802:439;;;29209:5;29190:1;:11;;:15;29202:2;29190:15;;;;;;;;;;;;;;;;:24;;;;;;;;;;;28802:439;29273:2;29258:25;;29267:4;29258:25;;;29277:5;29258:25;;;;;;:::i;:::-;;;;;;;;28167:1124;28092:1199;;;:::o;110564:597::-;110712:12;110742:7;110737:417;;110766:19;110774:10;110766:7;:19::i;:::-;110737:417;;;111015:1;110994:10;:17;:22;:49;;;;;111042:1;111020:6;:18;;;:23;110994:49;110990:121;;;111088:6;111071:24;;;;;;;;;;;:::i;:::-;;;;;;;;110990:121;111132:10;111125:17;;;;110737:417;110564:597;;;;;;:::o;111714:528::-;111867:1;111847:10;:17;:21;111843:392;;;112079:10;112073:17;112136:15;112123:10;112119:2;112115:19;112108:44;111843:392;112206:17;;;;;;;;;;;;;;7:75:1;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:139::-;1887:6;1882:3;1877;1871:23;1928:1;1919:6;1914:3;1910:16;1903:27;1798:139;;;:::o;1943:102::-;1984:6;2035:2;2031:7;2026:2;2019:5;2015:14;2011:28;2001:38;;1943:102;;;:::o;2051:377::-;2139:3;2167:39;2200:5;2167:39;:::i;:::-;2222:71;2286:6;2281:3;2222:71;:::i;:::-;2215:78;;2302:65;2360:6;2355:3;2348:4;2341:5;2337:16;2302:65;:::i;:::-;2392:29;2414:6;2392:29;:::i;:::-;2387:3;2383:39;2376:46;;2143:285;2051:377;;;;:::o;2434:313::-;2547:4;2585:2;2574:9;2570:18;2562:26;;2634:9;2628:4;2624:20;2620:1;2609:9;2605:17;2598:47;2662:78;2735:4;2726:6;2662:78;:::i;:::-;2654:86;;2434:313;;;;:::o;2753:126::-;2790:7;2830:42;2823:5;2819:54;2808:65;;2753:126;;;:::o;2885:96::-;2922:7;2951:24;2969:5;2951:24;:::i;:::-;2940:35;;2885:96;;;:::o;2987:122::-;3060:24;3078:5;3060:24;:::i;:::-;3053:5;3050:35;3040:63;;3099:1;3096;3089:12;3040:63;2987:122;:::o;3115:139::-;3161:5;3199:6;3186:20;3177:29;;3215:33;3242:5;3215:33;:::i;:::-;3115:139;;;;:::o;3260:77::-;3297:7;3326:5;3315:16;;3260:77;;;:::o;3343:122::-;3416:24;3434:5;3416:24;:::i;:::-;3409:5;3406:35;3396:63;;3455:1;3452;3445:12;3396:63;3343:122;:::o;3471:139::-;3517:5;3555:6;3542:20;3533:29;;3571:33;3598:5;3571:33;:::i;:::-;3471:139;;;;:::o;3616:474::-;3684:6;3692;3741:2;3729:9;3720:7;3716:23;3712:32;3709:119;;;3747:79;;:::i;:::-;3709:119;3867:1;3892:53;3937:7;3928:6;3917:9;3913:22;3892:53;:::i;:::-;3882:63;;3838:117;3994:2;4020:53;4065:7;4056:6;4045:9;4041:22;4020:53;:::i;:::-;4010:63;;3965:118;3616:474;;;;;:::o;4096:118::-;4183:24;4201:5;4183:24;:::i;:::-;4178:3;4171:37;4096:118;;:::o;4220:222::-;4313:4;4351:2;4340:9;4336:18;4328:26;;4364:71;4432:1;4421:9;4417:17;4408:6;4364:71;:::i;:::-;4220:222;;;;:::o;4448:619::-;4525:6;4533;4541;4590:2;4578:9;4569:7;4565:23;4561:32;4558:119;;;4596:79;;:::i;:::-;4558:119;4716:1;4741:53;4786:7;4777:6;4766:9;4762:22;4741:53;:::i;:::-;4731:63;;4687:117;4843:2;4869:53;4914:7;4905:6;4894:9;4890:22;4869:53;:::i;:::-;4859:63;;4814:118;4971:2;4997:53;5042:7;5033:6;5022:9;5018:22;4997:53;:::i;:::-;4987:63;;4942:118;4448:619;;;;;:::o;5073:77::-;5110:7;5139:5;5128:16;;5073:77;;;:::o;5156:122::-;5229:24;5247:5;5229:24;:::i;:::-;5222:5;5219:35;5209:63;;5268:1;5265;5258:12;5209:63;5156:122;:::o;5284:139::-;5330:5;5368:6;5355:20;5346:29;;5384:33;5411:5;5384:33;:::i;:::-;5284:139;;;;:::o;5429:329::-;5488:6;5537:2;5525:9;5516:7;5512:23;5508:32;5505:119;;;5543:79;;:::i;:::-;5505:119;5663:1;5688:53;5733:7;5724:6;5713:9;5709:22;5688:53;:::i;:::-;5678:63;;5634:117;5429:329;;;;:::o;5764:118::-;5851:24;5869:5;5851:24;:::i;:::-;5846:3;5839:37;5764:118;;:::o;5888:222::-;5981:4;6019:2;6008:9;6004:18;5996:26;;6032:71;6100:1;6089:9;6085:17;6076:6;6032:71;:::i;:::-;5888:222;;;;:::o;6116:474::-;6184:6;6192;6241:2;6229:9;6220:7;6216:23;6212:32;6209:119;;;6247:79;;:::i;:::-;6209:119;6367:1;6392:53;6437:7;6428:6;6417:9;6413:22;6392:53;:::i;:::-;6382:63;;6338:117;6494:2;6520:53;6565:7;6556:6;6545:9;6541:22;6520:53;:::i;:::-;6510:63;;6465:118;6116:474;;;;;:::o;6596:86::-;6631:7;6671:4;6664:5;6660:16;6649:27;;6596:86;;;:::o;6688:112::-;6771:22;6787:5;6771:22;:::i;:::-;6766:3;6759:35;6688:112;;:::o;6806:214::-;6895:4;6933:2;6922:9;6918:18;6910:26;;6946:67;7010:1;6999:9;6995:17;6986:6;6946:67;:::i;:::-;6806:214;;;;:::o;7026:329::-;7085:6;7134:2;7122:9;7113:7;7109:23;7105:32;7102:119;;;7140:79;;:::i;:::-;7102:119;7260:1;7285:53;7330:7;7321:6;7310:9;7306:22;7285:53;:::i;:::-;7275:63;;7231:117;7026:329;;;;:::o;7361:117::-;7470:1;7467;7460:12;7484:117;7593:1;7590;7583:12;7607:180;7655:77;7652:1;7645:88;7752:4;7749:1;7742:15;7776:4;7773:1;7766:15;7793:281;7876:27;7898:4;7876:27;:::i;:::-;7868:6;7864:40;8006:6;7994:10;7991:22;7970:18;7958:10;7955:34;7952:62;7949:88;;;8017:18;;:::i;:::-;7949:88;8057:10;8053:2;8046:22;7836:238;7793:281;;:::o;8080:129::-;8114:6;8141:20;;:::i;:::-;8131:30;;8170:33;8198:4;8190:6;8170:33;:::i;:::-;8080:129;;;:::o;8215:307::-;8276:4;8366:18;8358:6;8355:30;8352:56;;;8388:18;;:::i;:::-;8352:56;8426:29;8448:6;8426:29;:::i;:::-;8418:37;;8510:4;8504;8500:15;8492:23;;8215:307;;;:::o;8528:148::-;8626:6;8621:3;8616;8603:30;8667:1;8658:6;8653:3;8649:16;8642:27;8528:148;;;:::o;8682:423::-;8759:5;8784:65;8800:48;8841:6;8800:48;:::i;:::-;8784:65;:::i;:::-;8775:74;;8872:6;8865:5;8858:21;8910:4;8903:5;8899:16;8948:3;8939:6;8934:3;8930:16;8927:25;8924:112;;;8955:79;;:::i;:::-;8924:112;9045:54;9092:6;9087:3;9082;9045:54;:::i;:::-;8765:340;8682:423;;;;;:::o;9124:338::-;9179:5;9228:3;9221:4;9213:6;9209:17;9205:27;9195:122;;9236:79;;:::i;:::-;9195:122;9353:6;9340:20;9378:78;9452:3;9444:6;9437:4;9429:6;9425:17;9378:78;:::i;:::-;9369:87;;9185:277;9124:338;;;;:::o;9468:652::-;9545:6;9553;9602:2;9590:9;9581:7;9577:23;9573:32;9570:119;;;9608:79;;:::i;:::-;9570:119;9728:1;9753:53;9798:7;9789:6;9778:9;9774:22;9753:53;:::i;:::-;9743:63;;9699:117;9883:2;9872:9;9868:18;9855:32;9914:18;9906:6;9903:30;9900:117;;;9936:79;;:::i;:::-;9900:117;10041:62;10095:7;10086:6;10075:9;10071:22;10041:62;:::i;:::-;10031:72;;9826:287;9468:652;;;;;:::o;10126:329::-;10185:6;10234:2;10222:9;10213:7;10209:23;10205:32;10202:119;;;10240:79;;:::i;:::-;10202:119;10360:1;10385:53;10430:7;10421:6;10410:9;10406:22;10385:53;:::i;:::-;10375:63;;10331:117;10126:329;;;;:::o;10461:149::-;10497:7;10537:66;10530:5;10526:78;10515:89;;10461:149;;;:::o;10616:115::-;10701:23;10718:5;10701:23;:::i;:::-;10696:3;10689:36;10616:115;;:::o;10737:118::-;10824:24;10842:5;10824:24;:::i;:::-;10819:3;10812:37;10737:118;;:::o;10861:114::-;10928:6;10962:5;10956:12;10946:22;;10861:114;;;:::o;10981:184::-;11080:11;11114:6;11109:3;11102:19;11154:4;11149:3;11145:14;11130:29;;10981:184;;;;:::o;11171:132::-;11238:4;11261:3;11253:11;;11291:4;11286:3;11282:14;11274:22;;11171:132;;;:::o;11309:108::-;11386:24;11404:5;11386:24;:::i;:::-;11381:3;11374:37;11309:108;;:::o;11423:179::-;11492:10;11513:46;11555:3;11547:6;11513:46;:::i;:::-;11591:4;11586:3;11582:14;11568:28;;11423:179;;;;:::o;11608:113::-;11678:4;11710;11705:3;11701:14;11693:22;;11608:113;;;:::o;11757:732::-;11876:3;11905:54;11953:5;11905:54;:::i;:::-;11975:86;12054:6;12049:3;11975:86;:::i;:::-;11968:93;;12085:56;12135:5;12085:56;:::i;:::-;12164:7;12195:1;12180:284;12205:6;12202:1;12199:13;12180:284;;;12281:6;12275:13;12308:63;12367:3;12352:13;12308:63;:::i;:::-;12301:70;;12394:60;12447:6;12394:60;:::i;:::-;12384:70;;12240:224;12227:1;12224;12220:9;12215:14;;12180:284;;;12184:14;12480:3;12473:10;;11881:608;;;11757:732;;;;:::o;12495:1215::-;12844:4;12882:3;12871:9;12867:19;12859:27;;12896:69;12962:1;12951:9;12947:17;12938:6;12896:69;:::i;:::-;13012:9;13006:4;13002:20;12997:2;12986:9;12982:18;12975:48;13040:78;13113:4;13104:6;13040:78;:::i;:::-;13032:86;;13165:9;13159:4;13155:20;13150:2;13139:9;13135:18;13128:48;13193:78;13266:4;13257:6;13193:78;:::i;:::-;13185:86;;13281:72;13349:2;13338:9;13334:18;13325:6;13281:72;:::i;:::-;13363:73;13431:3;13420:9;13416:19;13407:6;13363:73;:::i;:::-;13446;13514:3;13503:9;13499:19;13490:6;13446:73;:::i;:::-;13567:9;13561:4;13557:20;13551:3;13540:9;13536:19;13529:49;13595:108;13698:4;13689:6;13595:108;:::i;:::-;13587:116;;12495:1215;;;;;;;;;;:::o;13716:118::-;13787:22;13803:5;13787:22;:::i;:::-;13780:5;13777:33;13767:61;;13824:1;13821;13814:12;13767:61;13716:118;:::o;13840:135::-;13884:5;13922:6;13909:20;13900:29;;13938:31;13963:5;13938:31;:::i;:::-;13840:135;;;;:::o;13981:1199::-;14092:6;14100;14108;14116;14124;14132;14140;14189:3;14177:9;14168:7;14164:23;14160:33;14157:120;;;14196:79;;:::i;:::-;14157:120;14316:1;14341:53;14386:7;14377:6;14366:9;14362:22;14341:53;:::i;:::-;14331:63;;14287:117;14443:2;14469:53;14514:7;14505:6;14494:9;14490:22;14469:53;:::i;:::-;14459:63;;14414:118;14571:2;14597:53;14642:7;14633:6;14622:9;14618:22;14597:53;:::i;:::-;14587:63;;14542:118;14699:2;14725:53;14770:7;14761:6;14750:9;14746:22;14725:53;:::i;:::-;14715:63;;14670:118;14827:3;14854:51;14897:7;14888:6;14877:9;14873:22;14854:51;:::i;:::-;14844:61;;14798:117;14954:3;14981:53;15026:7;15017:6;15006:9;15002:22;14981:53;:::i;:::-;14971:63;;14925:119;15083:3;15110:53;15155:7;15146:6;15135:9;15131:22;15110:53;:::i;:::-;15100:63;;15054:119;13981:1199;;;;;;;;;;:::o;15186:474::-;15254:6;15262;15311:2;15299:9;15290:7;15286:23;15282:32;15279:119;;;15317:79;;:::i;:::-;15279:119;15437:1;15462:53;15507:7;15498:6;15487:9;15483:22;15462:53;:::i;:::-;15452:63;;15408:117;15564:2;15590:53;15635:7;15626:6;15615:9;15611:22;15590:53;:::i;:::-;15580:63;;15535:118;15186:474;;;;;:::o;15666:765::-;15752:6;15760;15768;15776;15825:3;15813:9;15804:7;15800:23;15796:33;15793:120;;;15832:79;;:::i;:::-;15793:120;15952:1;15977:53;16022:7;16013:6;16002:9;15998:22;15977:53;:::i;:::-;15967:63;;15923:117;16079:2;16105:53;16150:7;16141:6;16130:9;16126:22;16105:53;:::i;:::-;16095:63;;16050:118;16207:2;16233:53;16278:7;16269:6;16258:9;16254:22;16233:53;:::i;:::-;16223:63;;16178:118;16335:2;16361:53;16406:7;16397:6;16386:9;16382:22;16361:53;:::i;:::-;16351:63;;16306:118;15666:765;;;;;;;:::o;16437:180::-;16485:77;16482:1;16475:88;16582:4;16579:1;16572:15;16606:4;16603:1;16596:15;16623:320;16667:6;16704:1;16698:4;16694:12;16684:22;;16751:1;16745:4;16741:12;16772:18;16762:81;;16828:4;16820:6;16816:17;16806:27;;16762:81;16890:2;16882:6;16879:14;16859:18;16856:38;16853:84;;16909:18;;:::i;:::-;16853:84;16674:269;16623:320;;;:::o;16949:230::-;17089:34;17085:1;17077:6;17073:14;17066:58;17158:13;17153:2;17145:6;17141:15;17134:38;16949:230;:::o;17185:366::-;17327:3;17348:67;17412:2;17407:3;17348:67;:::i;:::-;17341:74;;17424:93;17513:3;17424:93;:::i;:::-;17542:2;17537:3;17533:12;17526:19;;17185:366;;;:::o;17557:419::-;17723:4;17761:2;17750:9;17746:18;17738:26;;17810:9;17804:4;17800:20;17796:1;17785:9;17781:17;17774:47;17838:131;17964:4;17838:131;:::i;:::-;17830:139;;17557:419;;;:::o;17982:171::-;18122:23;18118:1;18110:6;18106:14;18099:47;17982:171;:::o;18159:366::-;18301:3;18322:67;18386:2;18381:3;18322:67;:::i;:::-;18315:74;;18398:93;18487:3;18398:93;:::i;:::-;18516:2;18511:3;18507:12;18500:19;;18159:366;;;:::o;18531:419::-;18697:4;18735:2;18724:9;18720:18;18712:26;;18784:9;18778:4;18774:20;18770:1;18759:9;18755:17;18748:47;18812:131;18938:4;18812:131;:::i;:::-;18804:139;;18531:419;;;:::o;18956:775::-;19189:4;19227:3;19216:9;19212:19;19204:27;;19241:71;19309:1;19298:9;19294:17;19285:6;19241:71;:::i;:::-;19322:72;19390:2;19379:9;19375:18;19366:6;19322:72;:::i;:::-;19404;19472:2;19461:9;19457:18;19448:6;19404:72;:::i;:::-;19486;19554:2;19543:9;19539:18;19530:6;19486:72;:::i;:::-;19568:73;19636:3;19625:9;19621:19;19612:6;19568:73;:::i;:::-;19651;19719:3;19708:9;19704:19;19695:6;19651:73;:::i;:::-;18956:775;;;;;;;;;:::o;19737:332::-;19858:4;19896:2;19885:9;19881:18;19873:26;;19909:71;19977:1;19966:9;19962:17;19953:6;19909:71;:::i;:::-;19990:72;20058:2;20047:9;20043:18;20034:6;19990:72;:::i;:::-;19737:332;;;;;:::o;20075:85::-;20120:7;20149:5;20138:16;;20075:85;;;:::o;20166:101::-;20202:7;20242:18;20235:5;20231:30;20220:41;;20166:101;;;:::o;20273:60::-;20301:3;20322:5;20315:12;;20273:60;;;:::o;20339:156::-;20396:9;20429:60;20446:42;20455:32;20481:5;20455:32;:::i;:::-;20446:42;:::i;:::-;20429:60;:::i;:::-;20416:73;;20339:156;;;:::o;20501:145::-;20595:44;20633:5;20595:44;:::i;:::-;20590:3;20583:57;20501:145;;:::o;20652:236::-;20752:4;20790:2;20779:9;20775:18;20767:26;;20803:78;20878:1;20867:9;20863:17;20854:6;20803:78;:::i;:::-;20652:236;;;;:::o;20894:442::-;21043:4;21081:2;21070:9;21066:18;21058:26;;21094:71;21162:1;21151:9;21147:17;21138:6;21094:71;:::i;:::-;21175:72;21243:2;21232:9;21228:18;21219:6;21175:72;:::i;:::-;21257;21325:2;21314:9;21310:18;21301:6;21257:72;:::i;:::-;20894:442;;;;;;:::o;21342:222::-;21435:4;21473:2;21462:9;21458:18;21450:26;;21486:71;21554:1;21543:9;21539:17;21530:6;21486:71;:::i;:::-;21342:222;;;;:::o;21570:143::-;21627:5;21658:6;21652:13;21643:22;;21674:33;21701:5;21674:33;:::i;:::-;21570:143;;;;:::o;21719:351::-;21789:6;21838:2;21826:9;21817:7;21813:23;21809:32;21806:119;;;21844:79;;:::i;:::-;21806:119;21964:1;21989:64;22045:7;22036:6;22025:9;22021:22;21989:64;:::i;:::-;21979:74;;21935:128;21719:351;;;;:::o;22076:332::-;22197:4;22235:2;22224:9;22220:18;22212:26;;22248:71;22316:1;22305:9;22301:17;22292:6;22248:71;:::i;:::-;22329:72;22397:2;22386:9;22382:18;22373:6;22329:72;:::i;:::-;22076:332;;;;;:::o;22414:664::-;22619:4;22657:3;22646:9;22642:19;22634:27;;22671:71;22739:1;22728:9;22724:17;22715:6;22671:71;:::i;:::-;22752:72;22820:2;22809:9;22805:18;22796:6;22752:72;:::i;:::-;22834;22902:2;22891:9;22887:18;22878:6;22834:72;:::i;:::-;22916;22984:2;22973:9;22969:18;22960:6;22916:72;:::i;:::-;22998:73;23066:3;23055:9;23051:19;23042:6;22998:73;:::i;:::-;22414:664;;;;;;;;:::o;23084:545::-;23257:4;23295:3;23284:9;23280:19;23272:27;;23309:71;23377:1;23366:9;23362:17;23353:6;23309:71;:::i;:::-;23390:68;23454:2;23443:9;23439:18;23430:6;23390:68;:::i;:::-;23468:72;23536:2;23525:9;23521:18;23512:6;23468:72;:::i;:::-;23550;23618:2;23607:9;23603:18;23594:6;23550:72;:::i;:::-;23084:545;;;;;;;:::o;23635:180::-;23683:77;23680:1;23673:88;23780:4;23777:1;23770:15;23804:4;23801:1;23794:15;23821:141;23870:4;23893:3;23885:11;;23916:3;23913:1;23906:14;23950:4;23947:1;23937:18;23929:26;;23821:141;;;:::o;23968:93::-;24005:6;24052:2;24047;24040:5;24036:14;24032:23;24022:33;;23968:93;;;:::o;24067:107::-;24111:8;24161:5;24155:4;24151:16;24130:37;;24067:107;;;;:::o;24180:393::-;24249:6;24299:1;24287:10;24283:18;24322:97;24352:66;24341:9;24322:97;:::i;:::-;24440:39;24470:8;24459:9;24440:39;:::i;:::-;24428:51;;24512:4;24508:9;24501:5;24497:21;24488:30;;24561:4;24551:8;24547:19;24540:5;24537:30;24527:40;;24256:317;;24180:393;;;;;:::o;24579:142::-;24629:9;24662:53;24680:34;24689:24;24707:5;24689:24;:::i;:::-;24680:34;:::i;:::-;24662:53;:::i;:::-;24649:66;;24579:142;;;:::o;24727:75::-;24770:3;24791:5;24784:12;;24727:75;;;:::o;24808:269::-;24918:39;24949:7;24918:39;:::i;:::-;24979:91;25028:41;25052:16;25028:41;:::i;:::-;25020:6;25013:4;25007:11;24979:91;:::i;:::-;24973:4;24966:105;24884:193;24808:269;;;:::o;25083:73::-;25128:3;25083:73;:::o;25162:189::-;25239:32;;:::i;:::-;25280:65;25338:6;25330;25324:4;25280:65;:::i;:::-;25215:136;25162:189;;:::o;25357:186::-;25417:120;25434:3;25427:5;25424:14;25417:120;;;25488:39;25525:1;25518:5;25488:39;:::i;:::-;25461:1;25454:5;25450:13;25441:22;;25417:120;;;25357:186;;:::o;25549:543::-;25650:2;25645:3;25642:11;25639:446;;;25684:38;25716:5;25684:38;:::i;:::-;25768:29;25786:10;25768:29;:::i;:::-;25758:8;25754:44;25951:2;25939:10;25936:18;25933:49;;;25972:8;25957:23;;25933:49;25995:80;26051:22;26069:3;26051:22;:::i;:::-;26041:8;26037:37;26024:11;25995:80;:::i;:::-;25654:431;;25639:446;25549:543;;;:::o;26098:117::-;26152:8;26202:5;26196:4;26192:16;26171:37;;26098:117;;;;:::o;26221:169::-;26265:6;26298:51;26346:1;26342:6;26334:5;26331:1;26327:13;26298:51;:::i;:::-;26294:56;26379:4;26373;26369:15;26359:25;;26272:118;26221:169;;;;:::o;26395:295::-;26471:4;26617:29;26642:3;26636:4;26617:29;:::i;:::-;26609:37;;26679:3;26676:1;26672:11;26666:4;26663:21;26655:29;;26395:295;;;;:::o;26695:1395::-;26812:37;26845:3;26812:37;:::i;:::-;26914:18;26906:6;26903:30;26900:56;;;26936:18;;:::i;:::-;26900:56;26980:38;27012:4;27006:11;26980:38;:::i;:::-;27065:67;27125:6;27117;27111:4;27065:67;:::i;:::-;27159:1;27183:4;27170:17;;27215:2;27207:6;27204:14;27232:1;27227:618;;;;27889:1;27906:6;27903:77;;;27955:9;27950:3;27946:19;27940:26;27931:35;;27903:77;28006:67;28066:6;28059:5;28006:67;:::i;:::-;28000:4;27993:81;27862:222;27197:887;;27227:618;27279:4;27275:9;27267:6;27263:22;27313:37;27345:4;27313:37;:::i;:::-;27372:1;27386:208;27400:7;27397:1;27394:14;27386:208;;;27479:9;27474:3;27470:19;27464:26;27456:6;27449:42;27530:1;27522:6;27518:14;27508:24;;27577:2;27566:9;27562:18;27549:31;;27423:4;27420:1;27416:12;27411:17;;27386:208;;;27622:6;27613:7;27610:19;27607:179;;;27680:9;27675:3;27671:19;27665:26;27723:48;27765:4;27757:6;27753:17;27742:9;27723:48;:::i;:::-;27715:6;27708:64;27630:156;27607:179;27832:1;27828;27820:6;27816:14;27812:22;27806:4;27799:36;27234:611;;;27197:887;;26787:1303;;;26695:1395;;:::o;28096:98::-;28147:6;28181:5;28175:12;28165:22;;28096:98;;;:::o;28200:147::-;28301:11;28338:3;28323:18;;28200:147;;;;:::o;28353:386::-;28457:3;28485:38;28517:5;28485:38;:::i;:::-;28539:88;28620:6;28615:3;28539:88;:::i;:::-;28532:95;;28636:65;28694:6;28689:3;28682:4;28675:5;28671:16;28636:65;:::i;:::-;28726:6;28721:3;28717:16;28710:23;;28461:278;28353:386;;;;:::o;28745:271::-;28875:3;28897:93;28986:3;28977:6;28897:93;:::i;:::-;28890:100;;29007:3;29000:10;;28745:271;;;;:::o;29022:180::-;29070:77;29067:1;29060:88;29167:4;29164:1;29157:15;29191:4;29188:1;29181:15;29208:191;29248:3;29267:20;29285:1;29267:20;:::i;:::-;29262:25;;29301:20;29319:1;29301:20;:::i;:::-;29296:25;;29344:1;29341;29337:9;29330:16;;29365:3;29362:1;29359:10;29356:36;;;29372:18;;:::i;:::-;29356:36;29208:191;;;;:::o
Swarm Source
ipfs://be5d7e59a28195315b3d6fb01d3d3ebcce894ab0a564f8fd27a8b08fecc34a0b
Loading...
Loading
Loading...
Loading
Net Worth in USD
$218.66
Net Worth in ETH
0.113126
Token Allocations
RLS
100.00%
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ETH | 100.00% | $0.00512 | 42,708.0318 | $218.66 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.