Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 135 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer | 20239346 | 150 days ago | IN | 0 ETH | 0.00203496 | ||||
Transfer | 20239345 | 150 days ago | IN | 0 ETH | 0.00203496 | ||||
Transfer | 20231888 | 151 days ago | IN | 0 ETH | 0.00203496 | ||||
Transfer | 19963181 | 188 days ago | IN | 0 ETH | 0.00203496 | ||||
Transfer | 19920188 | 194 days ago | IN | 0 ETH | 0.00203496 | ||||
Approve | 19850743 | 204 days ago | IN | 0 ETH | 0.00008668 | ||||
Transfer | 19740201 | 219 days ago | IN | 0 ETH | 0.00082843 | ||||
Transfer | 19576970 | 242 days ago | IN | 0 ETH | 0.00216586 | ||||
Transfer | 19575158 | 242 days ago | IN | 0 ETH | 0.0020346 | ||||
Approve | 19561214 | 244 days ago | IN | 0 ETH | 0.00111293 | ||||
Transfer | 19560385 | 244 days ago | IN | 0 ETH | 0.0020346 | ||||
Transfer | 19555402 | 245 days ago | IN | 0 ETH | 0.00132652 | ||||
Transfer | 19518940 | 250 days ago | IN | 0 ETH | 0.00254437 | ||||
Approve | 19482770 | 255 days ago | IN | 0 ETH | 0.00139022 | ||||
Transfer | 19319240 | 278 days ago | IN | 0 ETH | 0.00263198 | ||||
Transfer | 19198695 | 295 days ago | IN | 0 ETH | 0.00237553 | ||||
Transfer | 19182874 | 297 days ago | IN | 0 ETH | 0.00401943 | ||||
Transfer | 19161142 | 301 days ago | IN | 0 ETH | 0.0020346 | ||||
Transfer | 19113050 | 307 days ago | IN | 0 ETH | 0.00110529 | ||||
Transfer | 19018678 | 320 days ago | IN | 0 ETH | 0.00220605 | ||||
Transfer | 19000643 | 323 days ago | IN | 0 ETH | 0.0020346 | ||||
Transfer | 18977607 | 326 days ago | IN | 0 ETH | 0.00382832 | ||||
Transfer | 18933149 | 332 days ago | IN | 0 ETH | 0.00131926 | ||||
Transfer | 18799514 | 351 days ago | IN | 0 ETH | 0.00368633 | ||||
Transfer | 18765956 | 356 days ago | IN | 0 ETH | 0.00299233 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
CMTAT
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2024-01-29 */ // File: openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol // SPDX-License-Identifier: MPL-2.0 // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } } // File: openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract 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; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; } // File: openzeppelin-contracts-upgradeable/contracts/token/ERC20/IERC20Upgradeable.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); } // File: openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/IERC20MetadataUpgradeable.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20MetadataUpgradeable is IERC20Upgradeable { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File: openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing { __ERC20_init_unchained(name_, symbol_); } function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer( address from, address to, uint256 amount ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; } _balances[to] += amount; emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance( address owner, address spender, uint256 amount ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[45] private __gap; } // File: contracts/modules/BaseModule.sol pragma solidity ^0.8.17; // required OZ imports here abstract contract BaseModule is Initializable, ERC20Upgradeable { /* Events */ event Spend(address indexed owner, address indexed spender, uint256 amount); /* Variables */ uint8 private _decimals; string public tokenId; string public terms; /* Initializers */ /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ function __Base_init( string memory name_, string memory symbol_, uint8 decimals_, string memory tokenId_, string memory terms_ ) internal onlyInitializing { __ERC20_init(name_, symbol_); _decimals = decimals_; tokenId = tokenId_; terms = terms_; } function __Base_init_unchained( uint8 decimals_, string memory tokenId_, string memory terms_ ) internal onlyInitializing { _decimals = decimals_; tokenId = tokenId_; terms = terms_; } /* Methods */ /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return _decimals; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { bool result = super.transferFrom(sender, recipient, amount); if (result == true) { emit Spend(sender, _msgSender(), amount); } return result; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve( address spender, uint256 amount, uint256 currentAllowance ) public virtual returns (bool) { require( allowance(_msgSender(), spender) == currentAllowance, "CMTAT: current allowance is not right" ); super.approve(spender, amount); return true; } uint256[50] private __gap; } // File: openzeppelin-contracts-upgradeable/contracts/access/IAccessControlUpgradeable.sol // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControlUpgradeable { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; } // File: openzeppelin-contracts-upgradeable/contracts/utils/StringsUpgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @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); } } // File: openzeppelin-contracts-upgradeable/contracts/utils/introspection/IERC165Upgradeable.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165Upgradeable.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing { } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; } // File: openzeppelin-contracts-upgradeable/contracts/access/AccessControlUpgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol) pragma solidity ^0.8.0; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable { function __AccessControl_init() internal onlyInitializing { } function __AccessControl_init_unchained() internal onlyInitializing { } struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", StringsUpgradeable.toHexString(uint160(account), 20), " is missing role ", StringsUpgradeable.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; } // File: contracts/modules/AuthorizationModule.sol pragma solidity ^0.8.17; abstract contract AuthorizationModule is AccessControlUpgradeable {} // File: contracts/modules/BurnModule.sol pragma solidity ^0.8.17; abstract contract BurnModule is Initializable { bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE"); event Burn(address indexed owner, uint256 amount); } // File: contracts/modules/MintModule.sol pragma solidity ^0.8.17; abstract contract MintModule { bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); event Mint(address indexed beneficiary, uint256 amount); } // File: contracts/modules/EnforcementModule.sol pragma solidity ^0.8.17; /** * @dev Enforcement module. * * Allows the issuer to freeze transfers from a given address */ abstract contract EnforcementModule is Initializable, ContextUpgradeable, ERC20Upgradeable { /** * @dev Emitted when an address is frozen. */ event Freeze(address indexed enforcer, address indexed owner); /** * @dev Emitted when an address is unfrozen. */ event Unfreeze(address indexed enforcer, address indexed owner); mapping(address => bool) private _frozen; bytes32 public constant ENFORCER_ROLE = keccak256("ENFORCER_ROLE"); string internal constant TEXT_TRANSFER_REJECTED_FROZEN = "The address is frozen"; /** * @dev Initializes the contract in unpaused state. */ function __Enforcement_init() internal onlyInitializing { __Context_init_unchained(); __Enforcement_init_unchained(); } function __Enforcement_init_unchained() internal onlyInitializing {} /** * @dev Returns true if the contract is paused, and false otherwise. */ function frozen(address account) public view virtual returns (bool) { return _frozen[account]; } /** * @dev Freezes an address. * */ function _freeze(address account) internal virtual returns (bool) { if (_frozen[account]) return false; _frozen[account] = true; emit Freeze(_msgSender(), account); return true; } /** * @dev Unfreezes an address. * */ function _unfreeze(address account) internal virtual returns (bool) { if (!_frozen[account]) return false; _frozen[account] = false; emit Unfreeze(_msgSender(), account); return true; } uint256[50] private __gap; } // File: openzeppelin-contracts-upgradeable/contracts/security/PausableUpgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; } // File: contracts/modules/PauseModule.sol pragma solidity ^0.8.17; /** * @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. */ abstract contract PauseModule is Initializable, PausableUpgradeable { bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); string internal constant TEXT_TRANSFER_REJECTED_PAUSED = "All transfers paused"; } // File: contracts/interfaces/IERC1404.sol pragma solidity ^0.8.17; interface IERC1404 { /** * @dev See ERC-1404 * */ function detectTransferRestriction( address _from, address _to, uint256 _amount ) external view returns (uint8); /** * @dev See ERC-1404 * */ function messageForTransferRestriction(uint8 _restrictionCode) external view returns (string memory); } // File: contracts/interfaces/IERC1404Wrapper.sol pragma solidity ^0.8.17; interface IERC1404Wrapper is IERC1404 { /** * @dev Returns true if the transfer is valid, and false otherwise. */ function validateTransfer( address _from, address _to, uint256 _amount ) external view returns (bool isValid); } // File: contracts/interfaces/IRule.sol pragma solidity ^0.8.17; interface IRule is IERC1404Wrapper { /** * @dev Returns true if the restriction code exists, and false otherwise. */ function canReturnTransferRestrictionCode(uint8 _restrictionCode) external view returns (bool); } // File: contracts/interfaces/IRuleEngine.sol pragma solidity ^0.8.17; interface IRuleEngine is IERC1404Wrapper{ /** * @dev define the rules, the precedent rules will be overwritten */ function setRules(IRule[] calldata rules_) external; /** * @dev return the number of rules */ function ruleLength() external view returns (uint256); /** * @dev return the rule at the index specified by ruleId */ function rule(uint256 ruleId) external view returns (IRule); /** * @dev return all the rules */ function rules() external view returns (IRule[] memory); } // File: contracts/modules/ValidationModule.sol pragma solidity ^0.8.17; /** * @dev Validation module. * * Useful for to restrict and validate transfers */ abstract contract ValidationModule is Initializable, ContextUpgradeable { /** * @dev Emitted when a rule engine is set. */ event RuleEngineSet(address indexed newRuleEngine); IRuleEngine public ruleEngine; /** * @dev Initializes the contract with rule engine. */ function __Validation_init(IRuleEngine ruleEngine_) internal onlyInitializing { __Context_init_unchained(); __Validation_init_unchained(ruleEngine_); } function __Validation_init_unchained(IRuleEngine ruleEngine_) internal onlyInitializing { if (address(ruleEngine_) != address(0)) { ruleEngine = ruleEngine_; emit RuleEngineSet(address(ruleEngine)); } } function _validateTransfer( address from, address to, uint256 amount ) internal view returns (bool) { return ruleEngine.validateTransfer(from, to, amount); } function _messageForTransferRestriction(uint8 restrictionCode) internal view returns (string memory) { return ruleEngine.messageForTransferRestriction(restrictionCode); } function _detectTransferRestriction( address from, address to, uint256 amount ) internal view returns (uint8) { return ruleEngine.detectTransferRestriction(from, to, amount); } uint256[50] private __gap; } // File: openzeppelin-contracts-upgradeable/contracts/metatx/ERC2771ContextUpgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (metatx/ERC2771Context.sol) pragma solidity ^0.8.9; /** * @dev Context variant with ERC2771 support. */ abstract contract ERC2771ContextUpgradeable is Initializable, ContextUpgradeable { /// @custom:oz-upgrades-unsafe-allow state-variable-immutable address private immutable _trustedForwarder; /// @custom:oz-upgrades-unsafe-allow constructor constructor(address trustedForwarder) { _trustedForwarder = trustedForwarder; } function isTrustedForwarder(address forwarder) public view virtual returns (bool) { return forwarder == _trustedForwarder; } function _msgSender() internal view virtual override returns (address sender) { if (isTrustedForwarder(msg.sender)) { // The assembly code is more direct than the Solidity version using `abi.decode`. /// @solidity memory-safe-assembly assembly { sender := shr(96, calldataload(sub(calldatasize(), 20))) } } else { return super._msgSender(); } } function _msgData() internal view virtual override returns (bytes calldata) { if (isTrustedForwarder(msg.sender)) { return msg.data[:msg.data.length - 20]; } else { return super._msgData(); } } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; } // File: contracts/modules/MetaTxModule.sol pragma solidity ^0.8.17; /** * @dev Meta transaction (gasless) module. * * Useful for to provide UX where the user does not pay gas for token exchange */ abstract contract MetaTxModule is ERC2771ContextUpgradeable { /// @custom:oz-upgrades-unsafe-allow constructor constructor(address trustedForwarder) ERC2771ContextUpgradeable(trustedForwarder) { // TODO : Emit an event ? // See : https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/master/contracts/mocks/ERC2771ContextMockUpgradeable.sol // emit Sender(_msgSender()); } } // File: openzeppelin-contracts-upgradeable/contracts/utils/math/MathUpgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`. // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`. // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a // good first aproximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1; uint256 x = a; if (x >> 128 > 0) { x >>= 128; result <<= 64; } if (x >> 64 > 0) { x >>= 64; result <<= 32; } if (x >> 32 > 0) { x >>= 32; result <<= 16; } if (x >> 16 > 0) { x >>= 16; result <<= 8; } if (x >> 8 > 0) { x >>= 8; result <<= 4; } if (x >> 4 > 0) { x >>= 4; result <<= 2; } if (x >> 2 > 0) { result <<= 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) { uint256 result = sqrt(a); if (rounding == Rounding.Up && result * result < a) { result += 1; } return result; } } // File: openzeppelin-contracts-upgradeable/contracts/utils/ArraysUpgradeable.sol // OpenZeppelin Contracts v4.4.1 (utils/Arrays.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to array types. */ library ArraysUpgradeable { /** * @dev Searches a sorted `array` and returns the first index that contains * a value greater or equal to `element`. If no such index exists (i.e. all * values in the array are strictly less than `element`), the array length is * returned. Time complexity O(log n). * * `array` is expected to be sorted in ascending order, and to contain no * repeated elements. */ function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) { if (array.length == 0) { return 0; } uint256 low = 0; uint256 high = array.length; while (low < high) { uint256 mid = MathUpgradeable.average(low, high); // Note that mid will always be strictly less than high (i.e. it will be a valid array index) // because Math.average rounds down (it does integer division with truncation). if (array[mid] > element) { high = mid; } else { low = mid + 1; } } // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound. if (low > 0 && array[low - 1] == element) { return low - 1; } else { return low; } } } // File: contracts/modules/SnapshotModule.sol pragma solidity ^0.8.17; /** * @dev Snapshot module. * * Useful to take a snapshot of token holder balance and total supply at a specific time */ abstract contract SnapshotModule is Initializable, ContextUpgradeable, ERC20Upgradeable { using ArraysUpgradeable for uint256[]; event SnapshotSchedule(uint256 indexed oldTime, uint256 indexed newTime); event SnapshotUnschedule(uint256 indexed time); struct Snapshots { uint256[] ids; uint256[] values; } bytes32 public constant SNAPSHOOTER_ROLE = keccak256("SNAPSHOOTER_ROLE"); mapping(address => Snapshots) private _accountBalanceSnapshots; Snapshots private _totalSupplySnapshots; uint256 private _currentSnapshot; uint256[] private _scheduledSnapshots; function __Snapshot_init() internal onlyInitializing { __Context_init_unchained(); __Snapshot_init_unchained(); } function __Snapshot_init_unchained() internal onlyInitializing{ _currentSnapshot = 0; } function _scheduleSnapshot(uint256 time) internal { require(block.timestamp < time, "Snapshot scheduled in the past"); (bool found, ) = _findScheduledSnapshotIndex(time); require(!found, "Snapshot already scheduled for this time"); _scheduledSnapshots.push(time); emit SnapshotSchedule(0, time); } function _rescheduleSnapshot(uint256 oldTime, uint256 newTime) internal { require(block.timestamp < oldTime, "Snapshot already done"); require(block.timestamp < newTime, "Snapshot scheduled in the past"); (bool foundNew, ) = _findScheduledSnapshotIndex(newTime); require(!foundNew, "Snapshot already scheduled for this time"); (bool foundOld, uint256 index) = _findScheduledSnapshotIndex(oldTime); require(foundOld, "Snapshot not found"); _scheduledSnapshots[index] = newTime; emit SnapshotSchedule(oldTime, newTime); } function _unscheduleSnapshot(uint256 time) internal { require(block.timestamp < time, "Snapshot already done"); (bool found, uint256 index) = _findScheduledSnapshotIndex(time); require(found, "Snapshot not found"); _removeScheduledItem(index); emit SnapshotUnschedule(time); } function getNextSnapshots() public view returns (uint256[] memory) { return _scheduledSnapshots; } function snapshotBalanceOf(uint256 time, address owner) public view returns (uint256) { (bool snapshotted, uint256 value) = _valueAt( time, _accountBalanceSnapshots[owner] ); return snapshotted ? value : balanceOf(owner); } function snapshotTotalSupply(uint256 time) public view returns (uint256) { (bool snapshotted, uint256 value) = _valueAt( time, _totalSupplySnapshots ); return snapshotted ? value : totalSupply(); } // Update balance and/or total supply snapshots before the values are modified. This is implemented // in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations. function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual override { super._beforeTokenTransfer(from, to, amount); _setCurrentSnapshot(); if (from != address(0)) { // for both burn and transfer _updateAccountSnapshot(from); if (to != address(0)) { // transfer _updateAccountSnapshot(to); } else { // burn _updateTotalSupplySnapshot(); } } else { // mint _updateAccountSnapshot(to); _updateTotalSupplySnapshot(); } } function _valueAt(uint256 time, Snapshots storage snapshots) private view returns (bool, uint256) { // When a valid snapshot is queried, there are three possibilities: // a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never // created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds // to this id is the current one. // b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the // requested id, and its value is the one to return. // c) More snapshots were created after the requested one, and the queried value was later modified. There will be // no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is // larger than the requested one. // // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does // exactly this. uint256 index = snapshots.ids.findUpperBound(time); if (index == snapshots.ids.length) { return (false, 0); } else { return (true, snapshots.values[index]); } } function _updateAccountSnapshot(address account) private { _updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account)); } function _updateTotalSupplySnapshot() private { _updateSnapshot(_totalSupplySnapshots, totalSupply()); } function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private { uint256 current = _getCurrentSnapshot(); if (_lastSnapshot(snapshots.ids) < current) { snapshots.ids.push(current); snapshots.values.push(currentValue); } } function _setCurrentSnapshot() internal { uint256 time = _findScheduledMostRecentPastSnapshot(); if (time > 0) { _currentSnapshot = time; _clearPastScheduled(); } } function _getCurrentSnapshot() internal view virtual returns (uint256) { return _currentSnapshot; } function _lastSnapshot(uint256[] storage ids) private view returns (uint256) { if (ids.length == 0) { return 0; } else { return ids[ids.length - 1]; } } function _findScheduledSnapshotIndex(uint256 time) private view returns (bool, uint256) { for (uint256 i = 0; i < _scheduledSnapshots.length; i++) { if (_scheduledSnapshots[i] == time) { return (true, i); } } return (false, 0); } function _findScheduledMostRecentPastSnapshot() private view returns (uint256) { if (_scheduledSnapshots.length == 0) return 0; uint256 mostRecent = 0; for (uint256 i = 0; i < _scheduledSnapshots.length; i++) { if ( _scheduledSnapshots[i] <= block.timestamp && _scheduledSnapshots[i] > mostRecent ) { mostRecent = _scheduledSnapshots[i]; } } return mostRecent; } function _clearPastScheduled() private { uint256 i = 0; while (i < _scheduledSnapshots.length) { if (_scheduledSnapshots[i] <= block.timestamp) { _removeScheduledItem(i); } else { i += 1; } } } function _removeScheduledItem(uint256 index) private { _scheduledSnapshots[index] = _scheduledSnapshots[ _scheduledSnapshots.length - 1 ]; _scheduledSnapshots.pop(); } uint256[50] private __gap; } // File: contracts/CMTAT.sol pragma solidity ^0.8.17; // required OZ imports here contract CMTAT is Initializable, ContextUpgradeable, BaseModule, AuthorizationModule, PauseModule, MintModule, BurnModule, EnforcementModule, ValidationModule, MetaTxModule, SnapshotModule { enum REJECTED_CODE { TRANSFER_OK, TRANSFER_REJECTED_PAUSED, TRANSFER_REJECTED_FROZEN } string constant TEXT_TRANSFER_OK = "No restriction"; event TermSet(string indexed newTerm); event TokenIdSet(string indexed newTokenId); /// @custom:oz-upgrades-unsafe-allow constructor constructor( address forwarder ) MetaTxModule(forwarder) { } function initialize( address owner, string memory name, string memory symbol, string memory tokenId, string memory terms ) public initializer { __CMTAT_init(owner, name, symbol, tokenId, terms); } /** * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the * account that deploys the contract. * * See {ERC20-constructor}. */ function __CMTAT_init( address owner, string memory name, string memory symbol, string memory tokenId, string memory terms ) internal onlyInitializing { __Context_init_unchained(); __Base_init_unchained(0, tokenId, terms); __AccessControl_init_unchained(); __ERC20_init_unchained(name, symbol); __Pausable_init_unchained(); __Enforcement_init_unchained(); __Snapshot_init_unchained(); __CMTAT_init_unchained(owner); } function __CMTAT_init_unchained(address owner) internal onlyInitializing { _setupRole(DEFAULT_ADMIN_ROLE, owner); _setupRole(ENFORCER_ROLE, owner); _setupRole(MINTER_ROLE, owner); _setupRole(BURNER_ROLE, owner); _setupRole(PAUSER_ROLE, owner); _setupRole(SNAPSHOOTER_ROLE, owner); } /** * @dev Creates `amount` new tokens for `to`. * * See {ERC20-_mint}. * * Requirements: * * - the caller must have the `MINTER_ROLE`. */ function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) { _mint(to, amount); emit Mint(to, amount); } /** * @dev Destroys `amount` tokens from `account`, deducting from the caller's * allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `amount`. */ function burnFrom(address account, uint256 amount) public onlyRole(BURNER_ROLE) { uint256 currentAllowance = allowance(account, _msgSender()); require( currentAllowance >= amount, "CMTAT: burn amount exceeds allowance" ); unchecked { _approve(account, _msgSender(), currentAllowance - amount); } _burn(account, amount); emit Burn(account, amount); } /** * @dev Pauses all token transfers. * * See {ERC20Pausable} and {Pausable-_pause}. * * Requirements: * * - the caller must have the `PAUSER_ROLE`. */ function pause() public onlyRole(PAUSER_ROLE) { _pause(); } /** * @dev Unpauses all token transfers. * * See {ERC20Pausable} and {Pausable-_unpause}. * * Requirements: * * - the caller must have the `PAUSER_ROLE`. */ function unpause() public onlyRole(PAUSER_ROLE) { _unpause(); } /** * @dev Freezes an address. * */ function freeze(address account) public onlyRole(ENFORCER_ROLE) returns (bool) { return _freeze(account); } /** * @dev Unfreezes an address. * */ function unfreeze(address account) public onlyRole(ENFORCER_ROLE) returns (bool) { return _unfreeze(account); } function decimals() public view virtual override(ERC20Upgradeable, BaseModule) returns (uint8) { return super.decimals(); } function transferFrom( address sender, address recipient, uint256 amount ) public virtual override(ERC20Upgradeable, BaseModule) returns (bool) { return super.transferFrom(sender, recipient, amount); } /** * @dev ERC1404 check if _value token can be transferred from _from to _to * @param from address The address which you want to send tokens from * @param to address The address which you want to transfer to * @param amount uint256 the amount of tokens to be transferred * @return code of the rejection reason */ function detectTransferRestriction( address from, address to, uint256 amount ) public view returns (uint8 code) { if (paused()) { return uint8(REJECTED_CODE.TRANSFER_REJECTED_PAUSED); } else if (frozen(from)) { return uint8(REJECTED_CODE.TRANSFER_REJECTED_FROZEN); } else if (address(ruleEngine) != address(0)) { return _detectTransferRestriction(from, to, amount); } return uint8(REJECTED_CODE.TRANSFER_OK); } /** * @dev ERC1404 returns the human readable explaination corresponding to the error code returned by detectTransferRestriction * @param restrictionCode The error code returned by detectTransferRestriction * @return message The human readable explaination corresponding to the error code returned by detectTransferRestriction */ function messageForTransferRestriction(uint8 restrictionCode) external view returns (string memory message) { if (restrictionCode == uint8(REJECTED_CODE.TRANSFER_OK)) { return TEXT_TRANSFER_OK; } else if (restrictionCode == uint8(REJECTED_CODE.TRANSFER_REJECTED_PAUSED)) { return TEXT_TRANSFER_REJECTED_PAUSED; } else if (restrictionCode == uint8(REJECTED_CODE.TRANSFER_REJECTED_FROZEN)) { return TEXT_TRANSFER_REJECTED_FROZEN; } else if (address(ruleEngine) != address(0)) { return _messageForTransferRestriction(restrictionCode); } } function scheduleSnapshot(uint256 time) public onlyRole(SNAPSHOOTER_ROLE) { _scheduleSnapshot(time); } function rescheduleSnapshot(uint256 oldTime, uint256 newTime) public onlyRole(SNAPSHOOTER_ROLE) { _rescheduleSnapshot(oldTime, newTime); } function unscheduleSnapshot(uint256 time) public onlyRole(SNAPSHOOTER_ROLE) { _unscheduleSnapshot(time); } function setTokenId(string memory tokenId_) public onlyRole(DEFAULT_ADMIN_ROLE) { tokenId = tokenId_; emit TokenIdSet(tokenId_); } function setTerms(string memory terms_) public onlyRole(DEFAULT_ADMIN_ROLE) { terms = terms_; emit TermSet(terms_); } /// @custom:oz-upgrades-unsafe-allow selfdestruct function kill() public onlyRole(DEFAULT_ADMIN_ROLE) { selfdestruct(payable(_msgSender())); } function setRuleEngine(IRuleEngine ruleEngine_) external onlyRole(DEFAULT_ADMIN_ROLE) { ruleEngine = ruleEngine_; emit RuleEngineSet(address(ruleEngine_)); } function _beforeTokenTransfer( address from, address to, uint256 amount ) internal override(SnapshotModule, ERC20Upgradeable) { require(!paused(), "CMTAT: token transfer while paused"); require(!frozen(from), "CMTAT: token transfer while frozen"); super._beforeTokenTransfer(from, to, amount); if (address(ruleEngine) != address(0)) { require( _validateTransfer(from, to, amount), "CMTAT: transfer rejected by validation module" ); } } function _msgSender() internal view override(ERC2771ContextUpgradeable, ContextUpgradeable) returns (address sender) { return super._msgSender(); } function _msgData() internal view override(ERC2771ContextUpgradeable, ContextUpgradeable) returns (bytes calldata) { return super._msgData(); } uint256[50] private __gap; }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"enforcer","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"Freeze","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Mint","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":"newRuleEngine","type":"address"}],"name":"RuleEngineSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"oldTime","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newTime","type":"uint256"}],"name":"SnapshotSchedule","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"time","type":"uint256"}],"name":"SnapshotUnschedule","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Spend","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"newTerm","type":"string"}],"name":"TermSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"newTokenId","type":"string"}],"name":"TokenIdSet","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":true,"internalType":"address","name":"enforcer","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"Unfreeze","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"BURNER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ENFORCER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"SNAPSHOOTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"currentAllowance","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":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"detectTransferRestriction","outputs":[{"internalType":"uint8","name":"code","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"freeze","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"frozen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNextSnapshots","outputs":[{"internalType":"uint256[]","name":"","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":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"tokenId","type":"string"},{"internalType":"string","name":"terms","type":"string"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"isTrustedForwarder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"kill","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"restrictionCode","type":"uint8"}],"name":"messageForTransferRestriction","outputs":[{"internalType":"string","name":"message","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"oldTime","type":"uint256"},{"internalType":"uint256","name":"newTime","type":"uint256"}],"name":"rescheduleSnapshot","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":[],"name":"ruleEngine","outputs":[{"internalType":"contract IRuleEngine","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"}],"name":"scheduleSnapshot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IRuleEngine","name":"ruleEngine_","type":"address"}],"name":"setRuleEngine","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"terms_","type":"string"}],"name":"setTerms","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"tokenId_","type":"string"}],"name":"setTokenId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"snapshotBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"}],"name":"snapshotTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"terms","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenId","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"unfreeze","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"}],"name":"unscheduleSnapshot","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b50604051620033aa380380620033aa833981016040819052620000349162000046565b6001600160a01b031660805262000078565b6000602082840312156200005957600080fd5b81516001600160a01b03811681146200007157600080fd5b9392505050565b60805161330f6200009b6000396000818161044a0152611f65015261330f6000f3fe608060405234801561001057600080fd5b50600436106102bb5760003560e01c806378f86afc11610182578063b6dbcae5116100e9578063d547741f116100a2578063e20c35e51161007c578063e20c35e51461067a578063e63ab1e91461068d578063fb78ed40146106a2578063fcf196b4146106b757600080fd5b8063d547741f14610641578063dcfd616f14610654578063dd62ed3e1461066757600080fd5b8063b6dbcae5146105ac578063d0516650146105bf578063d21268ef146105ec578063d4ce1415146105ff578063d502562514610612578063d53913931461061a57600080fd5b806395d89b411161013b57806395d89b4114610550578063a217fddf14610558578063a312e15514610560578063a457c2d714610573578063a4a0a30114610586578063a9059cbb1461059957600080fd5b806378f86afc146104e957806379cc6790146104fc5780637f4ab1dd1461050f5780638456cb59146105225780638d1fdf2f1461052a57806391d148541461053d57600080fd5b80633950935111610226578063572b6c05116101df578063572b6c051461043a5780635c975abb1461047a5780635ee7a94214610485578063634daf76146104985780636439fd75146104ab57806370a08231146104c057600080fd5b806339509351146103de5780633f4ba83a146103f157806340c10f19146103f957806341c0e1b51461040c578063426a84931461041457806345c8b1a61461042757600080fd5b8063246b72ec11610278578063246b72ec1461033d578063248a9ca314610352578063282c51f3146103755780632f2ff15d1461039c578063313ce567146103b157806336568abe146103cb57600080fd5b806301ffc9a7146102c057806306fdde03146102e8578063095ea7b3146102fd57806317d70f7c1461031057806318160ddd1461031857806323b872dd1461032a575b600080fd5b6102d36102ce366004612a85565b6106e3565b60405190151581526020015b60405180910390f35b6102f061071a565b6040516102df9190612ad3565b6102d361030b366004612b1b565b6107ac565b6102f06107ce565b6035545b6040519081526020016102df565b6102d3610338366004612b47565b61085c565b61031c60008051602061329a83398151915281565b61031c610360366004612b88565b600090815260cc602052604090206001015490565b61031c7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b6103af6103aa366004612ba1565b610873565b005b6103b961089d565b60405160ff90911681526020016102df565b6103af6103d9366004612ba1565b6108b0565b6102d36103ec366004612b1b565b610943565b6103af61096f565b6103af610407366004612b1b565b610992565b6103af610a0e565b6102d3610422366004612bd1565b610a2c565b6102d3610435366004612c06565b610ab0565b6102d3610448366004612c06565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0390811691161490565b60fe5460ff166102d3565b61031c610493366004612b88565b610adc565b61031c6104a6366004612ba1565b610b08565b61031c6000805160206132ba83398151915281565b61031c6104ce366004612c06565b6001600160a01b031660009081526033602052604090205490565b6103af6104f7366004612ce8565b610b62565b6103af61050a366004612b1b565b610bbc565b6102f061051d366004612d2c565b610cb9565b6103af610d86565b6102d3610538366004612c06565b610da6565b6102d361054b366004612ba1565b610dc9565b6102f0610df4565b61031c600081565b6103af61056e366004612b88565b610e03565b6102d3610581366004612b1b565b610e24565b6103af610594366004612c06565b610eaa565b6102d36105a7366004612b1b565b610f01565b6103af6105ba366004612d49565b610f19565b6102d36105cd366004612c06565b6001600160a01b03166000908152610130602052604090205460ff1690565b6103af6105fa366004612e09565b611034565b6103b961060d366004612b47565b611056565b6102f06110c0565b61031c7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6103af61064f366004612ba1565b6110cd565b6103af610662366004612ce8565b6110f2565b61031c610675366004612e2b565b61114c565b6103af610688366004612b88565b611177565b61031c60008051602061327a83398151915281565b6106aa611198565b6040516102df9190612e59565b610163546106cb906001600160a01b031681565b6040516001600160a01b0390911681526020016102df565b60006001600160e01b03198216637965db0b60e01b148061071457506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606036805461072990612e9d565b80601f016020809104026020016040519081016040528092919081815260200182805461075590612e9d565b80156107a25780601f10610777576101008083540402835291602001916107a2565b820191906000526020600020905b81548152906001019060200180831161078557829003601f168201915b5050505050905090565b6000806107b76111f0565b90506107c48185856111fa565b5060019392505050565b606680546107db90612e9d565b80601f016020809104026020016040519081016040528092919081815260200182805461080790612e9d565b80156108545780601f1061082957610100808354040283529160200191610854565b820191906000526020600020905b81548152906001019060200180831161083757829003601f168201915b505050505081565b600061086984848461131e565b90505b9392505050565b600082815260cc602052604090206001015461088e81611394565b61089883836113a5565b505050565b60006108ab60655460ff1690565b905090565b6108b86111f0565b6001600160a01b0316816001600160a01b0316146109355760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b61093f828261142c565b5050565b60008061094e6111f0565b90506107c4818585610960858961114c565b61096a9190612ee7565b6111fa565b60008051602061327a83398151915261098781611394565b61098f6114b1565b50565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a66109bc81611394565b6109c68383611509565b826001600160a01b03167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688583604051610a0191815260200190565b60405180910390a2505050565b6000610a1981611394565b610a216111f0565b6001600160a01b0316ff5b600081610a40610a3a6111f0565b8661114c565b14610a9b5760405162461bcd60e51b815260206004820152602560248201527f434d5441543a2063757272656e7420616c6c6f77616e6365206973206e6f74206044820152641c9a59da1d60da1b606482015260840161092c565b610aa584846107ac565b506001949350505050565b60006000805160206132ba833981519152610aca81611394565b610ad3836115f4565b91505b50919050565b6000806000610aed846101c9611683565b9150915081610afe57603554610b00565b805b949350505050565b6001600160a01b03811660009081526101c86020526040812081908190610b30908690611683565b9150915081610b57576001600160a01b038416600090815260336020526040902054610b59565b805b95945050505050565b6000610b6d81611394565b6067610b798382612f40565b5081604051610b889190613000565b604051908190038120907f04ad91be0cc2638e10a8fa52bb61221dcf70dfcd07e6beae6b0d5a3f75070fcf90600090a25050565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848610be681611394565b6000610bf4846106756111f0565b905082811015610c525760405162461bcd60e51b8152602060048201526024808201527f434d5441543a206275726e20616d6f756e74206578636565647320616c6c6f77604482015263616e636560e01b606482015260840161092c565b610c6684610c5e6111f0565b8584036111fa565b610c7084846116d8565b836001600160a01b03167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca584604051610cab91815260200190565b60405180910390a250505050565b606060ff8216610ced57505060408051808201909152600e81526d2737903932b9ba3934b1ba34b7b760911b602082015290565b60001960ff831601610d29575050604080518082019091526014815273105b1b081d1c985b9cd9995c9cc81c185d5cd95960621b602082015290565b60011960ff831601610d665750506040805180820190915260158152742a34329030b2323932b9b99034b990333937bd32b760591b602082015290565b610163546001600160a01b031615610d815761071482611832565b919050565b60008051602061327a833981519152610d9e81611394565b61098f6118a7565b60006000805160206132ba833981519152610dc081611394565b610ad3836118e5565b600091825260cc602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60606037805461072990612e9d565b60008051602061329a833981519152610e1b81611394565b61093f82611978565b600080610e2f6111f0565b90506000610e3d828661114c565b905083811015610e9d5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161092c565b610aa582868684036111fa565b6000610eb581611394565b61016380546001600160a01b0319166001600160a01b0384169081179091556040517f9c4d5c11b88d1e3d9c7ad50900cb6d10ac72853248cdc85ca868fb772e62b44990600090a25050565b600080610f0c6111f0565b90506107c4818585611a57565b600054610100900460ff1615808015610f395750600054600160ff909116105b80610f535750303b158015610f53575060005460ff166001145b610fb65760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161092c565b6000805460ff191660011790558015610fd9576000805461ff0019166101001790555b610fe68686868686611c32565b801561102c576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60008051602061329a83398151915261104c81611394565b6108988383611ca7565b600061106460fe5460ff1690565b156110735760015b905061086c565b6001600160a01b0384166000908152610130602052604090205460ff161561109c57600261106c565b610163546001600160a01b0316156110b95761106c848484611e10565b6000610869565b606780546107db90612e9d565b600082815260cc60205260409020600101546110e881611394565b610898838361142c565b60006110fd81611394565b60666111098382612f40565b50816040516111189190613000565b604051908190038120907f1a3f197f2cb06b445ad0c131c52bc822947dae771f49d55fbd17bb6e462254bd90600090a25050565b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b60008051602061329a83398151915261118f81611394565b61093f82611e8f565b60606101cc8054806020026020016040519081016040528092919081815260200182805480156107a257602002820191906000526020600020905b8154815260200190600101908083116111d3575050505050905090565b60006108ab611f61565b6001600160a01b03831661125c5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161092c565b6001600160a01b0382166112bd5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161092c565b6001600160a01b0383811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60008061132c858585611fa5565b9050801515600103610869576113406111f0565b6001600160a01b0316856001600160a01b03167f7c2b9369bf4a6bd9745889c658ad00a4d57e280c4c80fa1c74db2a9e52c136358560405161138491815260200190565b60405180910390a3949350505050565b61098f816113a06111f0565b611fc8565b6113af8282610dc9565b61093f57600082815260cc602090815260408083206001600160a01b03851684529091529020805460ff191660011790556113e86111f0565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6114368282610dc9565b1561093f57600082815260cc602090815260408083206001600160a01b03851684529091529020805460ff1916905561146d6111f0565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6114b961202c565b60fe805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6114ec6111f0565b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b03821661155f5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161092c565b61156b60008383612077565b806035600082825461157d9190612ee7565b90915550506001600160a01b038216600090815260336020526040812080548392906115aa908490612ee7565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b0381166000908152610130602052604081205460ff1661161d57506000919050565b6001600160a01b038216600081815261013060205260409020805460ff191690556116466111f0565b6001600160a01b03167f4f3ab9ff0cc4f039268532098e01239544b0420171876e36889d01c62c784c7960405160405180910390a3506001919050565b6000808061169184866121d4565b845490915081036116a95760008092509250506116d1565b60018460010182815481106116c0576116c061301c565b906000526020600020015492509250505b9250929050565b6001600160a01b0382166117385760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161092c565b61174482600083612077565b6001600160a01b038216600090815260336020526040902054818110156117b85760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161092c565b6001600160a01b03831660009081526033602052604081208383039055603580548492906117e7908490613032565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b61016354604051637f4ab1dd60e01b815260ff831660048201526060916001600160a01b031690637f4ab1dd90602401600060405180830381865afa15801561187f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107149190810190613045565b6118af612299565b60fe805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586114ec6111f0565b6001600160a01b0381166000908152610130602052604081205460ff161561190f57506000919050565b6001600160a01b038216600081815261013060205260409020805460ff1916600117905561193b6111f0565b6001600160a01b03167f51d18786e9cb144f87d46e7b796309ea84c7c687d91e09c97f051eacf59bc52860405160405180910390a3506001919050565b8042106119c75760405162461bcd60e51b815260206004820152601e60248201527f536e617073686f74207363686564756c656420696e2074686520706173740000604482015260640161092c565b60006119d2826122df565b50905080156119f35760405162461bcd60e51b815260040161092c906130b3565b6101cc805460018101825560009182527f9a37fbd5e796e9046c2f5f7e29046a230a4ba9ada48a80535ed93a51fec5cfbc018390556040518391907fe2ad3b1abe53383dbe6359f02f11ae76d91cfab321b37083b16e1d96a81d4183908290a35050565b6001600160a01b038316611abb5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161092c565b6001600160a01b038216611b1d5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161092c565b611b28838383612077565b6001600160a01b03831660009081526033602052604090205481811015611ba05760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161092c565b6001600160a01b03808516600090815260336020526040808220858503905591851681529081208054849290611bd7908490612ee7565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611c2391815260200190565b60405180910390a35b50505050565b600054610100900460ff16611c595760405162461bcd60e51b815260040161092c906130fb565b611c6161233e565b611c6d60008383612365565b611c7561233e565b611c7f84846123b4565b611c876123f4565b611c8f61233e565b611c97612427565b611ca085612456565b5050505050565b814210611cee5760405162461bcd60e51b8152602060048201526015602482015274536e617073686f7420616c726561647920646f6e6560581b604482015260640161092c565b804210611d3d5760405162461bcd60e51b815260206004820152601e60248201527f536e617073686f74207363686564756c656420696e2074686520706173740000604482015260640161092c565b6000611d48826122df565b5090508015611d695760405162461bcd60e51b815260040161092c906130b3565b600080611d75856122df565b9150915081611dbb5760405162461bcd60e51b815260206004820152601260248201527114db985c1cda1bdd081b9bdd08199bdd5b9960721b604482015260640161092c565b836101cc8281548110611dd057611dd061301c565b6000918252602082200191909155604051859187917fe2ad3b1abe53383dbe6359f02f11ae76d91cfab321b37083b16e1d96a81d41839190a35050505050565b6101635460405163d4ce141560e01b81526001600160a01b038581166004830152848116602483015260448201849052600092169063d4ce141590606401602060405180830381865afa158015611e6b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108699190613146565b804210611ed65760405162461bcd60e51b8152602060048201526015602482015274536e617073686f7420616c726561647920646f6e6560581b604482015260640161092c565b600080611ee2836122df565b9150915081611f285760405162461bcd60e51b815260206004820152601260248201527114db985c1cda1bdd081b9bdd08199bdd5b9960721b604482015260640161092c565b611f3181612524565b60405183907f06e2498f5548e5491bfe985562cc494131eae56b5b6543b59129c8886f129f6590600090a2505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163303611fa0575060131936013560601c90565b503390565b600080611fb06111f0565b9050611fbd85828561259b565b610aa5858585611a57565b611fd28282610dc9565b61093f57611fea816001600160a01b0316601461260f565b611ff583602061260f565b604051602001612006929190613163565b60408051601f198184030181529082905262461bcd60e51b825261092c91600401612ad3565b60fe5460ff166120755760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161092c565b565b60fe5460ff16156120d55760405162461bcd60e51b815260206004820152602260248201527f434d5441543a20746f6b656e207472616e73666572207768696c652070617573604482015261195960f21b606482015260840161092c565b6001600160a01b0383166000908152610130602052604090205460ff161561214a5760405162461bcd60e51b815260206004820152602260248201527f434d5441543a20746f6b656e207472616e73666572207768696c652066726f7a60448201526132b760f11b606482015260840161092c565b6121558383836127ab565b610163546001600160a01b031615610898576121728383836127f4565b6108985760405162461bcd60e51b815260206004820152602d60248201527f434d5441543a207472616e736665722072656a65637465642062792076616c6960448201526c646174696f6e206d6f64756c6560981b606482015260840161092c565b815460009081036121e757506000610714565b82546000905b808210156122435760006122018383612873565b9050848682815481106122165761221661301c565b9060005260206000200154111561222f5780915061223d565b61223a816001612ee7565b92505b506121ed565b6000821180156122785750838561225b600185613032565b8154811061226b5761226b61301c565b9060005260206000200154145b1561229157612288600183613032565b92505050610714565b509050610714565b60fe5460ff16156120755760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161092c565b60008060005b6101cc5481101561233257836101cc82815481106123055761230561301c565b90600052602060002001540361232057600194909350915050565b8061232a816131d8565b9150506122e5565b50600093849350915050565b600054610100900460ff166120755760405162461bcd60e51b815260040161092c906130fb565b600054610100900460ff1661238c5760405162461bcd60e51b815260040161092c906130fb565b6065805460ff191660ff851617905560666123a78382612f40565b506067611c2c8282612f40565b600054610100900460ff166123db5760405162461bcd60e51b815260040161092c906130fb565b60366123e78382612f40565b5060376108988282612f40565b600054610100900460ff1661241b5760405162461bcd60e51b815260040161092c906130fb565b60fe805460ff19169055565b600054610100900460ff1661244e5760405162461bcd60e51b815260040161092c906130fb565b60006101cb55565b600054610100900460ff1661247d5760405162461bcd60e51b815260040161092c906130fb565b61248860008261288e565b6124a06000805160206132ba8339815191528261288e565b6124ca7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a68261288e565b6124f47f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8488261288e565b61250c60008051602061327a8339815191528261288e565b61098f60008051602061329a8339815191528261288e565b6101cc805461253590600190613032565b815481106125455761254561301c565b90600052602060002001546101cc82815481106125645761256461301c565b6000918252602090912001556101cc805480612582576125826131f1565b6001900381819060005260206000200160009055905550565b60006125a7848461114c565b90506000198114611c2c57818110156126025760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161092c565b611c2c84848484036111fa565b6060600061261e836002613207565b612629906002612ee7565b67ffffffffffffffff81111561264157612641612c23565b6040519080825280601f01601f19166020018201604052801561266b576020820181803683370190505b509050600360fc1b816000815181106126865761268661301c565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106126b5576126b561301c565b60200101906001600160f81b031916908160001a90535060006126d9846002613207565b6126e4906001612ee7565b90505b600181111561275c576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106127185761271861301c565b1a60f81b82828151811061272e5761272e61301c565b60200101906001600160f81b031916908160001a90535060049490941c936127558161321e565b90506126e7565b50831561086c5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161092c565b6127b3612898565b6001600160a01b038316156127eb576127cb836128b8565b6001600160a01b038216156127e357610898826128b8565b6108986128ec565b6127e3826128b8565b6101635460405163634a350960e11b81526001600160a01b038581166004830152848116602483015260448201849052600092169063c6946a1290606401602060405180830381865afa15801561284f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108699190613235565b60006128826002848418613257565b61086c90848416612ee7565b61093f82826113a5565b60006128a26128fb565b9050801561098f576101cb81905561098f6129a1565b6001600160a01b03811660009081526101c86020908152604080832060339092529091205461098f91906129f4565b6129f4565b6120756101c96128e760355490565b6101cc54600090810361290e5750600090565b6000805b6101cc54811015610ad657426101cc82815481106129325761293261301c565b9060005260206000200154111580156129685750816101cc828154811061295b5761295b61301c565b9060005260206000200154115b1561298f576101cc81815481106129815761298161301c565b906000526020600020015491505b80612999816131d8565b915050612912565b60005b6101cc5481101561098f57426101cc82815481106129c4576129c461301c565b9060005260206000200154116129e2576129dd81612524565b6129a4565b6129ed600182612ee7565b90506129a4565b6000612a006101cb5490565b905080612a0c84612a40565b1015610898578254600180820185556000858152602080822090930193909355938401805494850181558252902090910155565b80546000908103612a5357506000919050565b81548290612a6390600190613032565b81548110612a7357612a7361301c565b90600052602060002001549050919050565b600060208284031215612a9757600080fd5b81356001600160e01b03198116811461086c57600080fd5b60005b83811015612aca578181015183820152602001612ab2565b50506000910152565b6020815260008251806020840152612af2816040850160208701612aaf565b601f01601f19169190910160400192915050565b6001600160a01b038116811461098f57600080fd5b60008060408385031215612b2e57600080fd5b8235612b3981612b06565b946020939093013593505050565b600080600060608486031215612b5c57600080fd5b8335612b6781612b06565b92506020840135612b7781612b06565b929592945050506040919091013590565b600060208284031215612b9a57600080fd5b5035919050565b60008060408385031215612bb457600080fd5b823591506020830135612bc681612b06565b809150509250929050565b600080600060608486031215612be657600080fd5b8335612bf181612b06565b95602085013595506040909401359392505050565b600060208284031215612c1857600080fd5b813561086c81612b06565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612c6257612c62612c23565b604052919050565b600067ffffffffffffffff821115612c8457612c84612c23565b50601f01601f191660200190565b600082601f830112612ca357600080fd5b8135612cb6612cb182612c6a565b612c39565b818152846020838601011115612ccb57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215612cfa57600080fd5b813567ffffffffffffffff811115612d1157600080fd5b610b0084828501612c92565b60ff8116811461098f57600080fd5b600060208284031215612d3e57600080fd5b813561086c81612d1d565b600080600080600060a08688031215612d6157600080fd5b8535612d6c81612b06565b9450602086013567ffffffffffffffff80821115612d8957600080fd5b612d9589838a01612c92565b95506040880135915080821115612dab57600080fd5b612db789838a01612c92565b94506060880135915080821115612dcd57600080fd5b612dd989838a01612c92565b93506080880135915080821115612def57600080fd5b50612dfc88828901612c92565b9150509295509295909350565b60008060408385031215612e1c57600080fd5b50508035926020909101359150565b60008060408385031215612e3e57600080fd5b8235612e4981612b06565b91506020830135612bc681612b06565b6020808252825182820181905260009190848201906040850190845b81811015612e9157835183529284019291840191600101612e75565b50909695505050505050565b600181811c90821680612eb157607f821691505b602082108103610ad657634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8082018082111561071457610714612ed1565b601f82111561089857600081815260208120601f850160051c81016020861015612f215750805b601f850160051c820191505b8181101561102c57828155600101612f2d565b815167ffffffffffffffff811115612f5a57612f5a612c23565b612f6e81612f688454612e9d565b84612efa565b602080601f831160018114612fa35760008415612f8b5750858301515b600019600386901b1c1916600185901b17855561102c565b600085815260208120601f198616915b82811015612fd257888601518255948401946001909101908401612fb3565b5085821015612ff05787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008251613012818460208701612aaf565b9190910192915050565b634e487b7160e01b600052603260045260246000fd5b8181038181111561071457610714612ed1565b60006020828403121561305757600080fd5b815167ffffffffffffffff81111561306e57600080fd5b8201601f8101841361307f57600080fd5b805161308d612cb182612c6a565b8181528560208385010111156130a257600080fd5b610b59826020830160208601612aaf565b60208082526028908201527f536e617073686f7420616c7265616479207363686564756c656420666f7220746040820152676869732074696d6560c01b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60006020828403121561315857600080fd5b815161086c81612d1d565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161319b816017850160208801612aaf565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516131cc816028840160208801612aaf565b01602801949350505050565b6000600182016131ea576131ea612ed1565b5060010190565b634e487b7160e01b600052603160045260246000fd5b808202811582820484141761071457610714612ed1565b60008161322d5761322d612ed1565b506000190190565b60006020828403121561324757600080fd5b8151801515811461086c57600080fd5b60008261327457634e487b7160e01b600052601260045260246000fd5b50049056fe65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a809a0fc49fc0600540f1d39e23454e1f6f215bc7505fa22b17c154616570ddef973ef39d76cc2c6090feab1c030bec6ab5db557f64df047a4c4f9b5953cf1df3a2646970667358221220a909904b22cdfda408a2defda054c455be54767f3c6f55aab9e1cc5736ee004464736f6c634300081100330000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102bb5760003560e01c806378f86afc11610182578063b6dbcae5116100e9578063d547741f116100a2578063e20c35e51161007c578063e20c35e51461067a578063e63ab1e91461068d578063fb78ed40146106a2578063fcf196b4146106b757600080fd5b8063d547741f14610641578063dcfd616f14610654578063dd62ed3e1461066757600080fd5b8063b6dbcae5146105ac578063d0516650146105bf578063d21268ef146105ec578063d4ce1415146105ff578063d502562514610612578063d53913931461061a57600080fd5b806395d89b411161013b57806395d89b4114610550578063a217fddf14610558578063a312e15514610560578063a457c2d714610573578063a4a0a30114610586578063a9059cbb1461059957600080fd5b806378f86afc146104e957806379cc6790146104fc5780637f4ab1dd1461050f5780638456cb59146105225780638d1fdf2f1461052a57806391d148541461053d57600080fd5b80633950935111610226578063572b6c05116101df578063572b6c051461043a5780635c975abb1461047a5780635ee7a94214610485578063634daf76146104985780636439fd75146104ab57806370a08231146104c057600080fd5b806339509351146103de5780633f4ba83a146103f157806340c10f19146103f957806341c0e1b51461040c578063426a84931461041457806345c8b1a61461042757600080fd5b8063246b72ec11610278578063246b72ec1461033d578063248a9ca314610352578063282c51f3146103755780632f2ff15d1461039c578063313ce567146103b157806336568abe146103cb57600080fd5b806301ffc9a7146102c057806306fdde03146102e8578063095ea7b3146102fd57806317d70f7c1461031057806318160ddd1461031857806323b872dd1461032a575b600080fd5b6102d36102ce366004612a85565b6106e3565b60405190151581526020015b60405180910390f35b6102f061071a565b6040516102df9190612ad3565b6102d361030b366004612b1b565b6107ac565b6102f06107ce565b6035545b6040519081526020016102df565b6102d3610338366004612b47565b61085c565b61031c60008051602061329a83398151915281565b61031c610360366004612b88565b600090815260cc602052604090206001015490565b61031c7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b6103af6103aa366004612ba1565b610873565b005b6103b961089d565b60405160ff90911681526020016102df565b6103af6103d9366004612ba1565b6108b0565b6102d36103ec366004612b1b565b610943565b6103af61096f565b6103af610407366004612b1b565b610992565b6103af610a0e565b6102d3610422366004612bd1565b610a2c565b6102d3610435366004612c06565b610ab0565b6102d3610448366004612c06565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0390811691161490565b60fe5460ff166102d3565b61031c610493366004612b88565b610adc565b61031c6104a6366004612ba1565b610b08565b61031c6000805160206132ba83398151915281565b61031c6104ce366004612c06565b6001600160a01b031660009081526033602052604090205490565b6103af6104f7366004612ce8565b610b62565b6103af61050a366004612b1b565b610bbc565b6102f061051d366004612d2c565b610cb9565b6103af610d86565b6102d3610538366004612c06565b610da6565b6102d361054b366004612ba1565b610dc9565b6102f0610df4565b61031c600081565b6103af61056e366004612b88565b610e03565b6102d3610581366004612b1b565b610e24565b6103af610594366004612c06565b610eaa565b6102d36105a7366004612b1b565b610f01565b6103af6105ba366004612d49565b610f19565b6102d36105cd366004612c06565b6001600160a01b03166000908152610130602052604090205460ff1690565b6103af6105fa366004612e09565b611034565b6103b961060d366004612b47565b611056565b6102f06110c0565b61031c7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6103af61064f366004612ba1565b6110cd565b6103af610662366004612ce8565b6110f2565b61031c610675366004612e2b565b61114c565b6103af610688366004612b88565b611177565b61031c60008051602061327a83398151915281565b6106aa611198565b6040516102df9190612e59565b610163546106cb906001600160a01b031681565b6040516001600160a01b0390911681526020016102df565b60006001600160e01b03198216637965db0b60e01b148061071457506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606036805461072990612e9d565b80601f016020809104026020016040519081016040528092919081815260200182805461075590612e9d565b80156107a25780601f10610777576101008083540402835291602001916107a2565b820191906000526020600020905b81548152906001019060200180831161078557829003601f168201915b5050505050905090565b6000806107b76111f0565b90506107c48185856111fa565b5060019392505050565b606680546107db90612e9d565b80601f016020809104026020016040519081016040528092919081815260200182805461080790612e9d565b80156108545780601f1061082957610100808354040283529160200191610854565b820191906000526020600020905b81548152906001019060200180831161083757829003601f168201915b505050505081565b600061086984848461131e565b90505b9392505050565b600082815260cc602052604090206001015461088e81611394565b61089883836113a5565b505050565b60006108ab60655460ff1690565b905090565b6108b86111f0565b6001600160a01b0316816001600160a01b0316146109355760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b61093f828261142c565b5050565b60008061094e6111f0565b90506107c4818585610960858961114c565b61096a9190612ee7565b6111fa565b60008051602061327a83398151915261098781611394565b61098f6114b1565b50565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a66109bc81611394565b6109c68383611509565b826001600160a01b03167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688583604051610a0191815260200190565b60405180910390a2505050565b6000610a1981611394565b610a216111f0565b6001600160a01b0316ff5b600081610a40610a3a6111f0565b8661114c565b14610a9b5760405162461bcd60e51b815260206004820152602560248201527f434d5441543a2063757272656e7420616c6c6f77616e6365206973206e6f74206044820152641c9a59da1d60da1b606482015260840161092c565b610aa584846107ac565b506001949350505050565b60006000805160206132ba833981519152610aca81611394565b610ad3836115f4565b91505b50919050565b6000806000610aed846101c9611683565b9150915081610afe57603554610b00565b805b949350505050565b6001600160a01b03811660009081526101c86020526040812081908190610b30908690611683565b9150915081610b57576001600160a01b038416600090815260336020526040902054610b59565b805b95945050505050565b6000610b6d81611394565b6067610b798382612f40565b5081604051610b889190613000565b604051908190038120907f04ad91be0cc2638e10a8fa52bb61221dcf70dfcd07e6beae6b0d5a3f75070fcf90600090a25050565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848610be681611394565b6000610bf4846106756111f0565b905082811015610c525760405162461bcd60e51b8152602060048201526024808201527f434d5441543a206275726e20616d6f756e74206578636565647320616c6c6f77604482015263616e636560e01b606482015260840161092c565b610c6684610c5e6111f0565b8584036111fa565b610c7084846116d8565b836001600160a01b03167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca584604051610cab91815260200190565b60405180910390a250505050565b606060ff8216610ced57505060408051808201909152600e81526d2737903932b9ba3934b1ba34b7b760911b602082015290565b60001960ff831601610d29575050604080518082019091526014815273105b1b081d1c985b9cd9995c9cc81c185d5cd95960621b602082015290565b60011960ff831601610d665750506040805180820190915260158152742a34329030b2323932b9b99034b990333937bd32b760591b602082015290565b610163546001600160a01b031615610d815761071482611832565b919050565b60008051602061327a833981519152610d9e81611394565b61098f6118a7565b60006000805160206132ba833981519152610dc081611394565b610ad3836118e5565b600091825260cc602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60606037805461072990612e9d565b60008051602061329a833981519152610e1b81611394565b61093f82611978565b600080610e2f6111f0565b90506000610e3d828661114c565b905083811015610e9d5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161092c565b610aa582868684036111fa565b6000610eb581611394565b61016380546001600160a01b0319166001600160a01b0384169081179091556040517f9c4d5c11b88d1e3d9c7ad50900cb6d10ac72853248cdc85ca868fb772e62b44990600090a25050565b600080610f0c6111f0565b90506107c4818585611a57565b600054610100900460ff1615808015610f395750600054600160ff909116105b80610f535750303b158015610f53575060005460ff166001145b610fb65760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161092c565b6000805460ff191660011790558015610fd9576000805461ff0019166101001790555b610fe68686868686611c32565b801561102c576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60008051602061329a83398151915261104c81611394565b6108988383611ca7565b600061106460fe5460ff1690565b156110735760015b905061086c565b6001600160a01b0384166000908152610130602052604090205460ff161561109c57600261106c565b610163546001600160a01b0316156110b95761106c848484611e10565b6000610869565b606780546107db90612e9d565b600082815260cc60205260409020600101546110e881611394565b610898838361142c565b60006110fd81611394565b60666111098382612f40565b50816040516111189190613000565b604051908190038120907f1a3f197f2cb06b445ad0c131c52bc822947dae771f49d55fbd17bb6e462254bd90600090a25050565b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b60008051602061329a83398151915261118f81611394565b61093f82611e8f565b60606101cc8054806020026020016040519081016040528092919081815260200182805480156107a257602002820191906000526020600020905b8154815260200190600101908083116111d3575050505050905090565b60006108ab611f61565b6001600160a01b03831661125c5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161092c565b6001600160a01b0382166112bd5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161092c565b6001600160a01b0383811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60008061132c858585611fa5565b9050801515600103610869576113406111f0565b6001600160a01b0316856001600160a01b03167f7c2b9369bf4a6bd9745889c658ad00a4d57e280c4c80fa1c74db2a9e52c136358560405161138491815260200190565b60405180910390a3949350505050565b61098f816113a06111f0565b611fc8565b6113af8282610dc9565b61093f57600082815260cc602090815260408083206001600160a01b03851684529091529020805460ff191660011790556113e86111f0565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6114368282610dc9565b1561093f57600082815260cc602090815260408083206001600160a01b03851684529091529020805460ff1916905561146d6111f0565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6114b961202c565b60fe805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6114ec6111f0565b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b03821661155f5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161092c565b61156b60008383612077565b806035600082825461157d9190612ee7565b90915550506001600160a01b038216600090815260336020526040812080548392906115aa908490612ee7565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b0381166000908152610130602052604081205460ff1661161d57506000919050565b6001600160a01b038216600081815261013060205260409020805460ff191690556116466111f0565b6001600160a01b03167f4f3ab9ff0cc4f039268532098e01239544b0420171876e36889d01c62c784c7960405160405180910390a3506001919050565b6000808061169184866121d4565b845490915081036116a95760008092509250506116d1565b60018460010182815481106116c0576116c061301c565b906000526020600020015492509250505b9250929050565b6001600160a01b0382166117385760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161092c565b61174482600083612077565b6001600160a01b038216600090815260336020526040902054818110156117b85760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161092c565b6001600160a01b03831660009081526033602052604081208383039055603580548492906117e7908490613032565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b61016354604051637f4ab1dd60e01b815260ff831660048201526060916001600160a01b031690637f4ab1dd90602401600060405180830381865afa15801561187f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107149190810190613045565b6118af612299565b60fe805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586114ec6111f0565b6001600160a01b0381166000908152610130602052604081205460ff161561190f57506000919050565b6001600160a01b038216600081815261013060205260409020805460ff1916600117905561193b6111f0565b6001600160a01b03167f51d18786e9cb144f87d46e7b796309ea84c7c687d91e09c97f051eacf59bc52860405160405180910390a3506001919050565b8042106119c75760405162461bcd60e51b815260206004820152601e60248201527f536e617073686f74207363686564756c656420696e2074686520706173740000604482015260640161092c565b60006119d2826122df565b50905080156119f35760405162461bcd60e51b815260040161092c906130b3565b6101cc805460018101825560009182527f9a37fbd5e796e9046c2f5f7e29046a230a4ba9ada48a80535ed93a51fec5cfbc018390556040518391907fe2ad3b1abe53383dbe6359f02f11ae76d91cfab321b37083b16e1d96a81d4183908290a35050565b6001600160a01b038316611abb5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161092c565b6001600160a01b038216611b1d5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161092c565b611b28838383612077565b6001600160a01b03831660009081526033602052604090205481811015611ba05760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161092c565b6001600160a01b03808516600090815260336020526040808220858503905591851681529081208054849290611bd7908490612ee7565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611c2391815260200190565b60405180910390a35b50505050565b600054610100900460ff16611c595760405162461bcd60e51b815260040161092c906130fb565b611c6161233e565b611c6d60008383612365565b611c7561233e565b611c7f84846123b4565b611c876123f4565b611c8f61233e565b611c97612427565b611ca085612456565b5050505050565b814210611cee5760405162461bcd60e51b8152602060048201526015602482015274536e617073686f7420616c726561647920646f6e6560581b604482015260640161092c565b804210611d3d5760405162461bcd60e51b815260206004820152601e60248201527f536e617073686f74207363686564756c656420696e2074686520706173740000604482015260640161092c565b6000611d48826122df565b5090508015611d695760405162461bcd60e51b815260040161092c906130b3565b600080611d75856122df565b9150915081611dbb5760405162461bcd60e51b815260206004820152601260248201527114db985c1cda1bdd081b9bdd08199bdd5b9960721b604482015260640161092c565b836101cc8281548110611dd057611dd061301c565b6000918252602082200191909155604051859187917fe2ad3b1abe53383dbe6359f02f11ae76d91cfab321b37083b16e1d96a81d41839190a35050505050565b6101635460405163d4ce141560e01b81526001600160a01b038581166004830152848116602483015260448201849052600092169063d4ce141590606401602060405180830381865afa158015611e6b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108699190613146565b804210611ed65760405162461bcd60e51b8152602060048201526015602482015274536e617073686f7420616c726561647920646f6e6560581b604482015260640161092c565b600080611ee2836122df565b9150915081611f285760405162461bcd60e51b815260206004820152601260248201527114db985c1cda1bdd081b9bdd08199bdd5b9960721b604482015260640161092c565b611f3181612524565b60405183907f06e2498f5548e5491bfe985562cc494131eae56b5b6543b59129c8886f129f6590600090a2505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163303611fa0575060131936013560601c90565b503390565b600080611fb06111f0565b9050611fbd85828561259b565b610aa5858585611a57565b611fd28282610dc9565b61093f57611fea816001600160a01b0316601461260f565b611ff583602061260f565b604051602001612006929190613163565b60408051601f198184030181529082905262461bcd60e51b825261092c91600401612ad3565b60fe5460ff166120755760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161092c565b565b60fe5460ff16156120d55760405162461bcd60e51b815260206004820152602260248201527f434d5441543a20746f6b656e207472616e73666572207768696c652070617573604482015261195960f21b606482015260840161092c565b6001600160a01b0383166000908152610130602052604090205460ff161561214a5760405162461bcd60e51b815260206004820152602260248201527f434d5441543a20746f6b656e207472616e73666572207768696c652066726f7a60448201526132b760f11b606482015260840161092c565b6121558383836127ab565b610163546001600160a01b031615610898576121728383836127f4565b6108985760405162461bcd60e51b815260206004820152602d60248201527f434d5441543a207472616e736665722072656a65637465642062792076616c6960448201526c646174696f6e206d6f64756c6560981b606482015260840161092c565b815460009081036121e757506000610714565b82546000905b808210156122435760006122018383612873565b9050848682815481106122165761221661301c565b9060005260206000200154111561222f5780915061223d565b61223a816001612ee7565b92505b506121ed565b6000821180156122785750838561225b600185613032565b8154811061226b5761226b61301c565b9060005260206000200154145b1561229157612288600183613032565b92505050610714565b509050610714565b60fe5460ff16156120755760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161092c565b60008060005b6101cc5481101561233257836101cc82815481106123055761230561301c565b90600052602060002001540361232057600194909350915050565b8061232a816131d8565b9150506122e5565b50600093849350915050565b600054610100900460ff166120755760405162461bcd60e51b815260040161092c906130fb565b600054610100900460ff1661238c5760405162461bcd60e51b815260040161092c906130fb565b6065805460ff191660ff851617905560666123a78382612f40565b506067611c2c8282612f40565b600054610100900460ff166123db5760405162461bcd60e51b815260040161092c906130fb565b60366123e78382612f40565b5060376108988282612f40565b600054610100900460ff1661241b5760405162461bcd60e51b815260040161092c906130fb565b60fe805460ff19169055565b600054610100900460ff1661244e5760405162461bcd60e51b815260040161092c906130fb565b60006101cb55565b600054610100900460ff1661247d5760405162461bcd60e51b815260040161092c906130fb565b61248860008261288e565b6124a06000805160206132ba8339815191528261288e565b6124ca7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a68261288e565b6124f47f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8488261288e565b61250c60008051602061327a8339815191528261288e565b61098f60008051602061329a8339815191528261288e565b6101cc805461253590600190613032565b815481106125455761254561301c565b90600052602060002001546101cc82815481106125645761256461301c565b6000918252602090912001556101cc805480612582576125826131f1565b6001900381819060005260206000200160009055905550565b60006125a7848461114c565b90506000198114611c2c57818110156126025760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161092c565b611c2c84848484036111fa565b6060600061261e836002613207565b612629906002612ee7565b67ffffffffffffffff81111561264157612641612c23565b6040519080825280601f01601f19166020018201604052801561266b576020820181803683370190505b509050600360fc1b816000815181106126865761268661301c565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106126b5576126b561301c565b60200101906001600160f81b031916908160001a90535060006126d9846002613207565b6126e4906001612ee7565b90505b600181111561275c576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106127185761271861301c565b1a60f81b82828151811061272e5761272e61301c565b60200101906001600160f81b031916908160001a90535060049490941c936127558161321e565b90506126e7565b50831561086c5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161092c565b6127b3612898565b6001600160a01b038316156127eb576127cb836128b8565b6001600160a01b038216156127e357610898826128b8565b6108986128ec565b6127e3826128b8565b6101635460405163634a350960e11b81526001600160a01b038581166004830152848116602483015260448201849052600092169063c6946a1290606401602060405180830381865afa15801561284f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108699190613235565b60006128826002848418613257565b61086c90848416612ee7565b61093f82826113a5565b60006128a26128fb565b9050801561098f576101cb81905561098f6129a1565b6001600160a01b03811660009081526101c86020908152604080832060339092529091205461098f91906129f4565b6129f4565b6120756101c96128e760355490565b6101cc54600090810361290e5750600090565b6000805b6101cc54811015610ad657426101cc82815481106129325761293261301c565b9060005260206000200154111580156129685750816101cc828154811061295b5761295b61301c565b9060005260206000200154115b1561298f576101cc81815481106129815761298161301c565b906000526020600020015491505b80612999816131d8565b915050612912565b60005b6101cc5481101561098f57426101cc82815481106129c4576129c461301c565b9060005260206000200154116129e2576129dd81612524565b6129a4565b6129ed600182612ee7565b90506129a4565b6000612a006101cb5490565b905080612a0c84612a40565b1015610898578254600180820185556000858152602080822090930193909355938401805494850181558252902090910155565b80546000908103612a5357506000919050565b81548290612a6390600190613032565b81548110612a7357612a7361301c565b90600052602060002001549050919050565b600060208284031215612a9757600080fd5b81356001600160e01b03198116811461086c57600080fd5b60005b83811015612aca578181015183820152602001612ab2565b50506000910152565b6020815260008251806020840152612af2816040850160208701612aaf565b601f01601f19169190910160400192915050565b6001600160a01b038116811461098f57600080fd5b60008060408385031215612b2e57600080fd5b8235612b3981612b06565b946020939093013593505050565b600080600060608486031215612b5c57600080fd5b8335612b6781612b06565b92506020840135612b7781612b06565b929592945050506040919091013590565b600060208284031215612b9a57600080fd5b5035919050565b60008060408385031215612bb457600080fd5b823591506020830135612bc681612b06565b809150509250929050565b600080600060608486031215612be657600080fd5b8335612bf181612b06565b95602085013595506040909401359392505050565b600060208284031215612c1857600080fd5b813561086c81612b06565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612c6257612c62612c23565b604052919050565b600067ffffffffffffffff821115612c8457612c84612c23565b50601f01601f191660200190565b600082601f830112612ca357600080fd5b8135612cb6612cb182612c6a565b612c39565b818152846020838601011115612ccb57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215612cfa57600080fd5b813567ffffffffffffffff811115612d1157600080fd5b610b0084828501612c92565b60ff8116811461098f57600080fd5b600060208284031215612d3e57600080fd5b813561086c81612d1d565b600080600080600060a08688031215612d6157600080fd5b8535612d6c81612b06565b9450602086013567ffffffffffffffff80821115612d8957600080fd5b612d9589838a01612c92565b95506040880135915080821115612dab57600080fd5b612db789838a01612c92565b94506060880135915080821115612dcd57600080fd5b612dd989838a01612c92565b93506080880135915080821115612def57600080fd5b50612dfc88828901612c92565b9150509295509295909350565b60008060408385031215612e1c57600080fd5b50508035926020909101359150565b60008060408385031215612e3e57600080fd5b8235612e4981612b06565b91506020830135612bc681612b06565b6020808252825182820181905260009190848201906040850190845b81811015612e9157835183529284019291840191600101612e75565b50909695505050505050565b600181811c90821680612eb157607f821691505b602082108103610ad657634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8082018082111561071457610714612ed1565b601f82111561089857600081815260208120601f850160051c81016020861015612f215750805b601f850160051c820191505b8181101561102c57828155600101612f2d565b815167ffffffffffffffff811115612f5a57612f5a612c23565b612f6e81612f688454612e9d565b84612efa565b602080601f831160018114612fa35760008415612f8b5750858301515b600019600386901b1c1916600185901b17855561102c565b600085815260208120601f198616915b82811015612fd257888601518255948401946001909101908401612fb3565b5085821015612ff05787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008251613012818460208701612aaf565b9190910192915050565b634e487b7160e01b600052603260045260246000fd5b8181038181111561071457610714612ed1565b60006020828403121561305757600080fd5b815167ffffffffffffffff81111561306e57600080fd5b8201601f8101841361307f57600080fd5b805161308d612cb182612c6a565b8181528560208385010111156130a257600080fd5b610b59826020830160208601612aaf565b60208082526028908201527f536e617073686f7420616c7265616479207363686564756c656420666f7220746040820152676869732074696d6560c01b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60006020828403121561315857600080fd5b815161086c81612d1d565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161319b816017850160208801612aaf565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516131cc816028840160208801612aaf565b01602801949350505050565b6000600182016131ea576131ea612ed1565b5060010190565b634e487b7160e01b600052603160045260246000fd5b808202811582820484141761071457610714612ed1565b60008161322d5761322d612ed1565b506000190190565b60006020828403121561324757600080fd5b8151801515811461086c57600080fd5b60008261327457634e487b7160e01b600052601260045260246000fd5b50049056fe65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a809a0fc49fc0600540f1d39e23454e1f6f215bc7505fa22b17c154616570ddef973ef39d76cc2c6090feab1c030bec6ab5db557f64df047a4c4f9b5953cf1df3a2646970667358221220a909904b22cdfda408a2defda054c455be54767f3c6f55aab9e1cc5736ee004464736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : forwarder (address): 0x0000000000000000000000000000000000000000
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
83838:8786:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46384:215;;;;;;:::i;:::-;;:::i;:::-;;;470:14:1;;463:22;445:41;;433:2;418:18;46384:215:0;;;;;;;;21016:100;;;:::i;:::-;;;;;;;:::i;23367:201::-;;;;;;:::i;:::-;;:::i;32434:21::-;;;:::i;22136:108::-;22224:12;;22136:108;;;1755:25:1;;;1743:2;1728:18;22136:108:0;1609:177:1;88189:247:0;;;;;;:::i;:::-;;:::i;76092:72::-;;-1:-1:-1;;;;;;;;;;;76092:72:0;;48253:131;;;;;;:::i;:::-;48327:7;48354:12;;;:6;:12;;;;;:22;;;;48253:131;52685:62;;52723:24;52685:62;;48694:147;;;;;;:::i;:::-;;:::i;:::-;;87994:187;;;:::i;:::-;;;3111:4:1;3099:17;;;3081:36;;3069:2;3054:18;87994:187:0;2939:184:1;49838:218:0;;;;;;:::i;:::-;;:::i;24852:238::-;;;;;;:::i;:::-;;:::i;87463:77::-;;;:::i;86021:139::-;;;;;;:::i;:::-;;:::i;91265:106::-;;;:::i;35025:361::-;;;;;;:::i;:::-;;:::i;87829:157::-;;;;;;:::i;:::-;;:::i;62911:138::-;;;;;;:::i;:::-;63024:17;-1:-1:-1;;;;;63011:30:0;;;;;;;62911:138;56888:86;56959:7;;;;56888:86;;78390:257;;;;;;:::i;:::-;;:::i;78067:315::-;;;;;;:::i;:::-;;:::i;53693:66::-;;-1:-1:-1;;;;;;;;;;;53693:66:0;;22307:127;;;;;;:::i;:::-;-1:-1:-1;;;;;22408:18:0;22381:7;22408:18;;;:9;:18;;;;;;;22307:127;91039:163;;;;;;:::i;:::-;;:::i;86479:479::-;;;;;;:::i;:::-;;:::i;89697:669::-;;;;;;:::i;:::-;;:::i;87172:73::-;;;:::i;87607:153::-;;;;;;:::i;:::-;;:::i;46691:147::-;;;;;;:::i;:::-;;:::i;21235:104::-;;;:::i;45785:49::-;;45830:4;45785:49;;90374:139;;;;;;:::i;:::-;;:::i;25593:436::-;;;;;;:::i;:::-;;:::i;91379:203::-;;;;;;:::i;:::-;;:::i;22640:193::-;;;;;;:::i;:::-;;:::i;84477:260::-;;;;;;:::i;:::-;;:::i;54257:110::-;;;;;;:::i;:::-;-1:-1:-1;;;;;54343:16:0;54319:4;54343:16;;;:7;:16;;;;;;;;;54257:110;90521:175;;;;;;:::i;:::-;;:::i;88799:531::-;;;;;;:::i;:::-;;:::i;32462:19::-;;;:::i;52926:62::-;;52964:24;52926:62;;49134:149;;;;;;:::i;:::-;;:::i;90855:176::-;;;;;;:::i;:::-;;:::i;22896:151::-;;;;;;:::i;:::-;;:::i;90704:143::-;;;;;;:::i;:::-;;:::i;58600:62::-;;-1:-1:-1;;;;;;;;;;;58600:62:0;;77947:112;;;:::i;:::-;;;;;;;:::i;61014:29::-;;;;;-1:-1:-1;;;;;61014:29:0;;;;;;-1:-1:-1;;;;;8864:32:1;;;8846:51;;8834:2;8819:18;61014:29:0;8680:223:1;46384:215:0;46469:4;-1:-1:-1;;;;;;46493:58:0;;-1:-1:-1;;;46493:58:0;;:98;;-1:-1:-1;;;;;;;;;;43196:51:0;;;46555:36;46486:105;46384:215;-1:-1:-1;;46384:215:0:o;21016:100::-;21070:13;21103:5;21096:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21016:100;:::o;23367:201::-;23450:4;23467:13;23483:12;:10;:12::i;:::-;23467:28;;23506:32;23515:5;23522:7;23531:6;23506:8;:32::i;:::-;-1:-1:-1;23556:4:0;;23367:201;-1:-1:-1;;;23367:201:0:o;32434:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;88189:247::-;88359:4;88383:45;88402:6;88410:9;88421:6;88383:18;:45::i;:::-;88376:52;;88189:247;;;;;;:::o;48694:147::-;48327:7;48354:12;;;:6;:12;;;;;:22;;;46276:16;46287:4;46276:10;:16::i;:::-;48808:25:::1;48819:4;48825:7;48808:10;:25::i;:::-;48694:147:::0;;;:::o;87994:187::-;88127:5;88157:16;34032:9;;;;;33949:100;88157:16;88150:23;;87994:187;:::o;49838:218::-;49945:12;:10;:12::i;:::-;-1:-1:-1;;;;;49934:23:0;:7;-1:-1:-1;;;;;49934:23:0;;49926:83;;;;-1:-1:-1;;;49926:83:0;;9495:2:1;49926:83:0;;;9477:21:1;9534:2;9514:18;;;9507:30;9573:34;9553:18;;;9546:62;-1:-1:-1;;;9624:18:1;;;9617:45;9679:19;;49926:83:0;;;;;;;;;50022:26;50034:4;50040:7;50022:11;:26::i;:::-;49838:218;;:::o;24852:238::-;24940:4;24957:13;24973:12;:10;:12::i;:::-;24957:28;;24996:64;25005:5;25012:7;25049:10;25021:25;25031:5;25038:7;25021:9;:25::i;:::-;:38;;;;:::i;:::-;24996:8;:64::i;87463:77::-;-1:-1:-1;;;;;;;;;;;46276:16:0;46287:4;46276:10;:16::i;:::-;87522:10:::1;:8;:10::i;:::-;87463:77:::0;:::o;86021:139::-;52964:24;46276:16;46287:4;46276:10;:16::i;:::-;86103:17:::1;86109:2;86113:6;86103:5;:17::i;:::-;86141:2;-1:-1:-1::0;;;;;86136:16:0::1;;86145:6;86136:16;;;;1755:25:1::0;;1743:2;1728:18;;1609:177;86136:16:0::1;;;;;;;;86021:139:::0;;;:::o;91265:106::-;45830:4;46276:16;45830:4;46276:10;:16::i;:::-;91349:12:::1;:10;:12::i;:::-;-1:-1:-1::0;;;;;91328:35:0::1;;35025:361:::0;35159:4;35234:16;35198:32;35208:12;:10;:12::i;:::-;35222:7;35198:9;:32::i;:::-;:52;35176:139;;;;-1:-1:-1;;;35176:139:0;;10173:2:1;35176:139:0;;;10155:21:1;10212:2;10192:18;;;10185:30;10251:34;10231:18;;;10224:62;-1:-1:-1;;;10302:18:1;;;10295:35;10347:19;;35176:139:0;9971:401:1;35176:139:0;35326:30;35340:7;35349:6;35326:13;:30::i;:::-;-1:-1:-1;35374:4:0;;35025:361;-1:-1:-1;;;;35025:361:0:o;87829:157::-;87931:4;-1:-1:-1;;;;;;;;;;;46276:16:0;46287:4;46276:10;:16::i;:::-;87960:18:::1;87970:7;87960:9;:18::i;:::-;87953:25;;46303:1;87829:157:::0;;;;:::o;78390:257::-;78454:7;78475:16;78493:13;78510:74;78533:4;78552:21;78510:8;:74::i;:::-;78474:110;;;;78604:11;:35;;22224:12;;78604:35;;;78618:5;78604:35;78597:42;78390:257;-1:-1:-1;;;;78390:257:0:o;78067:315::-;-1:-1:-1;;;;;78274:31:0;;78171:7;78274:31;;;:24;:31;;;;;78171:7;;;;78232:84;;78255:4;;78232:8;:84::i;:::-;78196:120;;;;78336:11;:38;;-1:-1:-1;;;;;22408:18:0;;22381:7;22408:18;;;:9;:18;;;;;;78336:38;;;78350:5;78336:38;78329:45;78067:315;-1:-1:-1;;;;;78067:315:0:o;91039:163::-;45830:4;46276:16;45830:4;46276:10;:16::i;:::-;91149:5:::1;:14;91157:6:::0;91149:5;:14:::1;:::i;:::-;;91187:6;91179:15;;;;;;:::i;:::-;;::::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;91039:163:::0;;:::o;86479:479::-;52723:24;46276:16;46287:4;46276:10;:16::i;:::-;86593:24:::1;86620:32;86630:7;86639:12;:10;:12::i;86620:32::-;86593:59;;86705:6;86685:16;:26;;86663:112;;;::::0;-1:-1:-1;;;86663:112:0;;13077:2:1;86663:112:0::1;::::0;::::1;13059:21:1::0;13116:2;13096:18;;;13089:30;13155:34;13135:18;;;13128:62;-1:-1:-1;;;13206:18:1;;;13199:34;13250:19;;86663:112:0::1;12875:400:1::0;86663:112:0::1;86811:58;86820:7;86829:12;:10;:12::i;:::-;86862:6;86843:16;:25;86811:8;:58::i;:::-;86891:22;86897:7;86906:6;86891:5;:22::i;:::-;86934:7;-1:-1:-1::0;;;;;86929:21:0::1;;86943:6;86929:21;;;;1755:25:1::0;;1743:2;1728:18;;1609:177;86929:21:0::1;;;;;;;;86582:376;86479:479:::0;;;:::o;89697:669::-;89809:21;89852:51;;;89848:511;;-1:-1:-1;;89927:16:0;;;;;;;;;;;;-1:-1:-1;;;89927:16:0;;;;;89697:669::o;89848:511::-;-1:-1:-1;;89965:64:0;;;;89961:398;;-1:-1:-1;;90053:29:0;;;;;;;;;;;;-1:-1:-1;;;90053:29:0;;;;;89697:669::o;89961:398::-;-1:-1:-1;;90104:64:0;;;;90100:259;;-1:-1:-1;;90192:29:0;;;;;;;;;;;;-1:-1:-1;;;90192:29:0;;;;;89697:669::o;90100:259::-;90251:10;;-1:-1:-1;;;;;90251:10:0;90243:33;90239:120;;90300:47;90331:15;90300:30;:47::i;90239:120::-;89697:669;;;:::o;87172:73::-;-1:-1:-1;;;;;;;;;;;46276:16:0;46287:4;46276:10;:16::i;:::-;87229:8:::1;:6;:8::i;87607:153::-:0;87707:4;-1:-1:-1;;;;;;;;;;;46276:16:0;46287:4;46276:10;:16::i;:::-;87736::::1;87744:7;87736;:16::i;46691:147::-:0;46777:4;46801:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;46801:29:0;;;;;;;;;;;;;;;46691:147::o;21235:104::-;21291:13;21324:7;21317:14;;;;;:::i;90374:139::-;-1:-1:-1;;;;;;;;;;;46276:16:0;46287:4;46276:10;:16::i;:::-;90482:23:::1;90500:4;90482:17;:23::i;25593:436::-:0;25686:4;25703:13;25719:12;:10;:12::i;:::-;25703:28;;25742:24;25769:25;25779:5;25786:7;25769:9;:25::i;:::-;25742:52;;25833:15;25813:16;:35;;25805:85;;;;-1:-1:-1;;;25805:85:0;;13614:2:1;25805:85:0;;;13596:21:1;13653:2;13633:18;;;13626:30;13692:34;13672:18;;;13665:62;-1:-1:-1;;;13743:18:1;;;13736:35;13788:19;;25805:85:0;13412:401:1;25805:85:0;25926:60;25935:5;25942:7;25970:15;25951:16;:34;25926:8;:60::i;91379:203::-;45830:4;46276:16;45830:4;46276:10;:16::i;:::-;91499:10:::1;:24:::0;;-1:-1:-1;;;;;;91499:24:0::1;-1:-1:-1::0;;;;;91499:24:0;::::1;::::0;;::::1;::::0;;;91539:35:::1;::::0;::::1;::::0;-1:-1:-1;;91539:35:0::1;91379:203:::0;;:::o;22640:193::-;22719:4;22736:13;22752:12;:10;:12::i;:::-;22736:28;;22775;22785:5;22792:2;22796:6;22775:9;:28::i;84477:260::-;10851:19;10874:13;;;;;;10873:14;;10921:34;;;;-1:-1:-1;10939:12:0;;10954:1;10939:12;;;;:16;10921:34;10920:108;;;-1:-1:-1;11000:4:0;1606:19;:23;;;10961:66;;-1:-1:-1;11010:12:0;;;;;:17;10961:66;10898:204;;;;-1:-1:-1;;;10898:204:0;;14020:2:1;10898:204:0;;;14002:21:1;14059:2;14039:18;;;14032:30;14098:34;14078:18;;;14071:62;-1:-1:-1;;;14149:18:1;;;14142:44;14203:19;;10898:204:0;13818:410:1;10898:204:0;11113:12;:16;;-1:-1:-1;;11113:16:0;11128:1;11113:16;;;11140:67;;;;11175:13;:20;;-1:-1:-1;;11175:20:0;;;;;11140:67;84680:49:::1;84693:5;84700:4;84706:6;84714:7;84723:5;84680:12;:49::i;:::-;11233:14:::0;11229:102;;;11280:5;11264:21;;-1:-1:-1;;11264:21:0;;;11305:14;;-1:-1:-1;3081:36:1;;11305:14:0;;3069:2:1;3054:18;11305:14:0;;;;;;;11229:102;10840:498;84477:260;;;;;:::o;90521:175::-;-1:-1:-1;;;;;;;;;;;46276:16:0;46287:4;46276:10;:16::i;:::-;90651:37:::1;90671:7;90680;90651:19;:37::i;88799:531::-:0;88931:10;88958:8;56959:7;;;;;56888:86;88958:8;88954:319;;;88996:38;88990:45;88983:52;;;;88954:319;-1:-1:-1;;;;;54343:16:0;;54319:4;54343:16;;;:7;:16;;;;;;;;89053:220;;;89099:38;89093:45;;89053:220;89168:10;;-1:-1:-1;;;;;89168:10:0;89160:33;89156:117;;89217:44;89244:4;89250:2;89254:6;89217:26;:44::i;89156:117::-;89296:25;89290:32;;32462:19;;;;;;;:::i;49134:149::-;48327:7;48354:12;;;:6;:12;;;;;:22;;;46276:16;46287:4;46276:10;:16::i;:::-;49249:26:::1;49261:4;49267:7;49249:11;:26::i;90855:176::-:0;45830:4;46276:16;45830:4;46276:10;:16::i;:::-;90969:7:::1;:18;90979:8:::0;90969:7;:18:::1;:::i;:::-;;91014:8;91003:20;;;;;;:::i;:::-;;::::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;90855:176:::0;;:::o;22896:151::-;-1:-1:-1;;;;;23012:18:0;;;22985:7;23012:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;22896:151::o;90704:143::-;-1:-1:-1;;;;;;;;;;;46276:16:0;46287:4;46276:10;:16::i;:::-;90814:25:::1;90834:4;90814:19;:25::i;77947:112::-:0;77996:16;78032:19;78025:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77947:112;:::o;92179:202::-;92316:14;92355:18;:16;:18::i;29218:380::-;-1:-1:-1;;;;;29354:19:0;;29346:68;;;;-1:-1:-1;;;29346:68:0;;14634:2:1;29346:68:0;;;14616:21:1;14673:2;14653:18;;;14646:30;14712:34;14692:18;;;14685:62;-1:-1:-1;;;14763:18:1;;;14756:34;14807:19;;29346:68:0;14432:400:1;29346:68:0;-1:-1:-1;;;;;29433:21:0;;29425:68;;;;-1:-1:-1;;;29425:68:0;;15039:2:1;29425:68:0;;;15021:21:1;15078:2;15058:18;;;15051:30;15117:34;15097:18;;;15090:62;-1:-1:-1;;;15168:18:1;;;15161:32;15210:19;;29425:68:0;14837:398:1;29425:68:0;-1:-1:-1;;;;;29506:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;29558:32;;1755:25:1;;;29558:32:0;;1728:18:1;29558:32:0;;;;;;;29218:380;;;:::o;34531:347::-;34671:4;34688:11;34702:45;34721:6;34729:9;34740:6;34702:18;:45::i;:::-;34688:59;-1:-1:-1;34762:14:0;;;34772:4;34762:14;34758:87;;34812:12;:10;:12::i;:::-;-1:-1:-1;;;;;34798:35:0;34804:6;-1:-1:-1;;;;;34798:35:0;;34826:6;34798:35;;;;1755:25:1;;1743:2;1728:18;;1609:177;34798:35:0;;;;;;;;34864:6;34531:347;-1:-1:-1;;;;34531:347:0:o;47142:105::-;47209:30;47220:4;47226:12;:10;:12::i;:::-;47209:10;:30::i;51435:238::-;51519:22;51527:4;51533:7;51519;:22::i;:::-;51514:152;;51558:12;;;;:6;:12;;;;;;;;-1:-1:-1;;;;;51558:29:0;;;;;;;;;:36;;-1:-1:-1;;51558:36:0;51590:4;51558:36;;;51641:12;:10;:12::i;:::-;-1:-1:-1;;;;;51614:40:0;51632:7;-1:-1:-1;;;;;51614:40:0;51626:4;51614:40;;;;;;;;;;51435:238;;:::o;51853:239::-;51937:22;51945:4;51951:7;51937;:22::i;:::-;51933:152;;;52008:5;51976:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;51976:29:0;;;;;;;;;:37;;-1:-1:-1;;51976:37:0;;;52060:12;:10;:12::i;:::-;-1:-1:-1;;;;;52033:40:0;52051:7;-1:-1:-1;;;;;52033:40:0;52045:4;52033:40;;;;;;;;;;51853:239;;:::o;57743:120::-;56752:16;:14;:16::i;:::-;57802:7:::1;:15:::0;;-1:-1:-1;;57802:15:0::1;::::0;;57833:22:::1;57842:12;:10;:12::i;:::-;57833:22;::::0;-1:-1:-1;;;;;8864:32:1;;;8846:51;;8834:2;8819:18;57833:22:0::1;;;;;;;57743:120::o:0;27457:399::-;-1:-1:-1;;;;;27541:21:0;;27533:65;;;;-1:-1:-1;;;27533:65:0;;15650:2:1;27533:65:0;;;15632:21:1;15689:2;15669:18;;;15662:30;15728:33;15708:18;;;15701:61;15779:18;;27533:65:0;15448:355:1;27533:65:0;27611:49;27640:1;27644:7;27653:6;27611:20;:49::i;:::-;27689:6;27673:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;27706:18:0;;;;;;:9;:18;;;;;:28;;27728:6;;27706:18;:28;;27728:6;;27706:28;:::i;:::-;;;;-1:-1:-1;;27750:37:0;;1755:25:1;;;-1:-1:-1;;;;;27750:37:0;;;27767:1;;27750:37;;1743:2:1;1728:18;27750:37:0;;;;;;;49838:218;;:::o;54723:226::-;-1:-1:-1;;;;;54807:16:0;;54785:4;54807:16;;;:7;:16;;;;;;;;54802:35;;-1:-1:-1;54832:5:0;;54723:226;-1:-1:-1;54723:226:0:o;54802:35::-;-1:-1:-1;;;;;54848:16:0;;54867:5;54848:16;;;:7;:16;;;;;:24;;-1:-1:-1;;54848:24:0;;;54897:12;:10;:12::i;:::-;-1:-1:-1;;;;;54888:31:0;;;;;;;;;;;-1:-1:-1;54937:4:0;;54723:226;-1:-1:-1;54723:226:0:o;79576:1487::-;79686:4;;;80859:34;:9;80888:4;80859:28;:34::i;:::-;80919:20;;80843:50;;-1:-1:-1;80910:29:0;;80906:150;;80964:5;80971:1;80956:17;;;;;;;80906:150;81014:4;81020:9;:16;;81037:5;81020:23;;;;;;;;:::i;:::-;;;;;;;;;81006:38;;;;;79576:1487;;;;;;:::o;28189:591::-;-1:-1:-1;;;;;28273:21:0;;28265:67;;;;-1:-1:-1;;;28265:67:0;;16142:2:1;28265:67:0;;;16124:21:1;16181:2;16161:18;;;16154:30;16220:34;16200:18;;;16193:62;-1:-1:-1;;;16271:18:1;;;16264:31;16312:19;;28265:67:0;15940:397:1;28265:67:0;28345:49;28366:7;28383:1;28387:6;28345:20;:49::i;:::-;-1:-1:-1;;;;;28432:18:0;;28407:22;28432:18;;;:9;:18;;;;;;28469:24;;;;28461:71;;;;-1:-1:-1;;;28461:71:0;;16544:2:1;28461:71:0;;;16526:21:1;16583:2;16563:18;;;16556:30;16622:34;16602:18;;;16595:62;-1:-1:-1;;;16673:18:1;;;16666:32;16715:19;;28461:71:0;16342:398:1;28461:71:0;-1:-1:-1;;;;;28568:18:0;;;;;;:9;:18;;;;;28589:23;;;28568:44;;28634:12;:22;;28606:6;;28568:18;28634:22;;28606:6;;28634:22;:::i;:::-;;;;-1:-1:-1;;28674:37:0;;1755:25:1;;;28700:1:0;;-1:-1:-1;;;;;28674:37:0;;;;;1743:2:1;1728:18;28674:37:0;;;;;;;48694:147;;;:::o;61801:216::-;61952:10;;:57;;-1:-1:-1;;;61952:57:0;;3111:4:1;3099:17;;61952:57:0;;;3081:36:1;61914:13:0;;-1:-1:-1;;;;;61952:10:0;;:40;;3054:18:1;;61952:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;61952:57:0;;;;;;;;;;;;:::i;57484:118::-;56493:19;:17;:19::i;:::-;57544:7:::1;:14:::0;;-1:-1:-1;;57544:14:0::1;57554:4;57544:14;::::0;;57574:20:::1;57581:12;:10;:12::i;54434:220::-:0;-1:-1:-1;;;;;54515:16:0;;54494:4;54515:16;;;:7;:16;;;;;;;;54511:34;;;-1:-1:-1;54540:5:0;;54434:220;-1:-1:-1;54434:220:0:o;54511:34::-;-1:-1:-1;;;;;54556:16:0;;;;;;:7;:16;;;;;:23;;-1:-1:-1;;54556:23:0;54575:4;54556:23;;;54602:12;:10;:12::i;:::-;-1:-1:-1;;;;;54595:29:0;;;;;;;;;;;-1:-1:-1;54642:4:0;;54434:220;-1:-1:-1;54434:220:0:o;76628:347::-;76715:4;76697:15;:22;76689:65;;;;-1:-1:-1;;;76689:65:0;;17734:2:1;76689:65:0;;;17716:21:1;17773:2;17753:18;;;17746:30;17812:32;17792:18;;;17785:60;17862:18;;76689:65:0;17532:354:1;76689:65:0;76766:10;76782:33;76810:4;76782:27;:33::i;:::-;76765:50;;;76835:5;76834:6;76826:59;;;;-1:-1:-1;;;76826:59:0;;;;;;;:::i;:::-;76896:19;:30;;;;;;;-1:-1:-1;76896:30:0;;;;;;;;76942:25;;76921:4;;-1:-1:-1;76942:25:0;;-1:-1:-1;;76942:25:0;76678:297;76628:347;:::o;26499:671::-;-1:-1:-1;;;;;26630:18:0;;26622:68;;;;-1:-1:-1;;;26622:68:0;;18502:2:1;26622:68:0;;;18484:21:1;18541:2;18521:18;;;18514:30;18580:34;18560:18;;;18553:62;-1:-1:-1;;;18631:18:1;;;18624:35;18676:19;;26622:68:0;18300:401:1;26622:68:0;-1:-1:-1;;;;;26709:16:0;;26701:64;;;;-1:-1:-1;;;26701:64:0;;18908:2:1;26701:64:0;;;18890:21:1;18947:2;18927:18;;;18920:30;18986:34;18966:18;;;18959:62;-1:-1:-1;;;19037:18:1;;;19030:33;19080:19;;26701:64:0;18706:399:1;26701:64:0;26778:38;26799:4;26805:2;26809:6;26778:20;:38::i;:::-;-1:-1:-1;;;;;26851:15:0;;26829:19;26851:15;;;:9;:15;;;;;;26885:21;;;;26877:72;;;;-1:-1:-1;;;26877:72:0;;19312:2:1;26877:72:0;;;19294:21:1;19351:2;19331:18;;;19324:30;19390:34;19370:18;;;19363:62;-1:-1:-1;;;19441:18:1;;;19434:36;19487:19;;26877:72:0;19110:402:1;26877:72:0;-1:-1:-1;;;;;26985:15:0;;;;;;;:9;:15;;;;;;27003:20;;;26985:38;;27045:13;;;;;;;;:23;;27017:6;;26985:15;27045:23;;27017:6;;27045:23;:::i;:::-;;;;;;;;27101:2;-1:-1:-1;;;;;27086:26:0;27095:4;-1:-1:-1;;;;;27086:26:0;;27105:6;27086:26;;;;1755:25:1;;1743:2;1728:18;;1609:177;27086:26:0;;;;;;;;27125:37;26611:559;26499:671;;;:::o;84928:544::-;12692:13;;;;;;;12684:69;;;;-1:-1:-1;;;12684:69:0;;;;;;;:::i;:::-;85140:26:::1;:24;:26::i;:::-;85177:40;85199:1;85202:7;85211:5;85177:21;:40::i;:::-;85228:32;:30;:32::i;:::-;85271:36;85294:4;85300:6;85271:22;:36::i;:::-;85318:27;:25;:27::i;:::-;85356:30;:28;:30::i;:::-;85397:27;:25;:27::i;:::-;85435:29;85458:5;85435:22;:29::i;:::-;84928:544:::0;;;;;:::o;76983:618::-;77106:7;77088:15;:25;77080:59;;;;-1:-1:-1;;;77080:59:0;;20131:2:1;77080:59:0;;;20113:21:1;20170:2;20150:18;;;20143:30;-1:-1:-1;;;20189:18:1;;;20182:51;20250:18;;77080:59:0;19929:345:1;77080:59:0;77176:7;77158:15;:25;77150:68;;;;-1:-1:-1;;;77150:68:0;;17734:2:1;77150:68:0;;;17716:21:1;17773:2;17753:18;;;17746:30;17812:32;17792:18;;;17785:60;17862:18;;77150:68:0;17532:354:1;77150:68:0;77232:13;77251:36;77279:7;77251:27;:36::i;:::-;77231:56;;;77307:8;77306:9;77298:62;;;;-1:-1:-1;;;77298:62:0;;;;;;;:::i;:::-;77374:13;77389;77406:36;77434:7;77406:27;:36::i;:::-;77373:69;;;;77461:8;77453:39;;;;-1:-1:-1;;;77453:39:0;;20481:2:1;77453:39:0;;;20463:21:1;20520:2;20500:18;;;20493:30;-1:-1:-1;;;20539:18:1;;;20532:48;20597:18;;77453:39:0;20279:342:1;77453:39:0;77534:7;77505:19;77525:5;77505:26;;;;;;;;:::i;:::-;;;;;;;;;:36;;;;77559:34;;77585:7;;77576;;77559:34;;77505:26;77559:34;77069:532;;;76983:618;;:::o;62025:222::-;62185:10;;:54;;-1:-1:-1;;;62185:54:0;;-1:-1:-1;;;;;20884:15:1;;;62185:54:0;;;20866:34:1;20936:15;;;20916:18;;;20909:43;20968:18;;;20961:34;;;62160:5:0;;62185:10;;:36;;20801:18:1;;62185:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;77609:330::-;77698:4;77680:15;:22;77672:56;;;;-1:-1:-1;;;77672:56:0;;20131:2:1;77672:56:0;;;20113:21:1;20170:2;20150:18;;;20143:30;-1:-1:-1;;;20189:18:1;;;20182:51;20250:18;;77672:56:0;19929:345:1;77672:56:0;77740:10;77752:13;77769:33;77797:4;77769:27;:33::i;:::-;77739:63;;;;77821:5;77813:36;;;;-1:-1:-1;;;77813:36:0;;20481:2:1;77813:36:0;;;20463:21:1;20520:2;20500:18;;;20493:30;-1:-1:-1;;;20539:18:1;;;20532:48;20597:18;;77813:36:0;20279:342:1;77813:36:0;77862:27;77883:5;77862:20;:27::i;:::-;77907:24;;77926:4;;77907:24;;;;;77661:278;;77609:330;:::o;63057:458::-;63119:14;63024:17;-1:-1:-1;;;;;63011:30:0;63169:10;63011:30;63146:362;;-1:-1:-1;;;63403:14:0;63399:23;63386:37;63382:2;63378:46;63057:458;:::o;63146:362::-;-1:-1:-1;14435:10:0;;87994:187::o;24148:295::-;24279:4;24296:15;24314:12;:10;:12::i;:::-;24296:30;;24337:38;24353:4;24359:7;24368:6;24337:15;:38::i;:::-;24386:27;24396:4;24402:2;24406:6;24386:9;:27::i;47537:527::-;47626:22;47634:4;47640:7;47626;:22::i;:::-;47621:436;;47814:52;47853:7;-1:-1:-1;;;;;47814:52:0;47863:2;47814:30;:52::i;:::-;47939:49;47978:4;47985:2;47939:30;:49::i;:::-;47719:292;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;47719:292:0;;;;;;;;;;-1:-1:-1;;;47665:380:0;;;;;;;:::i;57232:108::-;56959:7;;;;57291:41;;;;-1:-1:-1;;;57291:41:0;;22277:2:1;57291:41:0;;;22259:21:1;22316:2;22296:18;;;22289:30;-1:-1:-1;;;22335:18:1;;;22328:50;22395:18;;57291:41:0;22075:344:1;57291:41:0;57232:108::o;91590:581::-;56959:7;;;;91767:9;91759:56;;;;-1:-1:-1;;;91759:56:0;;22626:2:1;91759:56:0;;;22608:21:1;22665:2;22645:18;;;22638:30;22704:34;22684:18;;;22677:62;-1:-1:-1;;;22755:18:1;;;22748:32;22797:19;;91759:56:0;22424:398:1;91759:56:0;-1:-1:-1;;;;;54343:16:0;;54319:4;54343:16;;;:7;:16;;;;;;;;91834:13;91826:60;;;;-1:-1:-1;;;91826:60:0;;23029:2:1;91826:60:0;;;23011:21:1;23068:2;23048:18;;;23041:30;23107:34;23087:18;;;23080:62;-1:-1:-1;;;23158:18:1;;;23151:32;23200:19;;91826:60:0;22827:398:1;91826:60:0;91899:44;91926:4;91932:2;91936:6;91899:26;:44::i;:::-;91968:10;;-1:-1:-1;;;;;91968:10:0;91960:33;91956:208;;92036:35;92054:4;92060:2;92064:6;92036:17;:35::i;:::-;92010:142;;;;-1:-1:-1;;;92010:142:0;;23432:2:1;92010:142:0;;;23414:21:1;23471:2;23451:18;;;23444:30;23510:34;23490:18;;;23483:62;-1:-1:-1;;;23561:18:1;;;23554:43;23614:19;;92010:142:0;23230:409:1;74562:929:0;74675:12;;74651:7;;74675:17;;74671:58;;-1:-1:-1;74716:1:0;74709:8;;74671:58;74782:12;;74741:11;;74807:435;74820:4;74814:3;:10;74807:435;;;74841:11;74855:34;74879:3;74884:4;74855:23;:34::i;:::-;74841:48;;75123:7;75110:5;75116:3;75110:10;;;;;;;;:::i;:::-;;;;;;;;;:20;75106:125;;;75158:3;75151:10;;75106:125;;;75208:7;:3;75214:1;75208:7;:::i;:::-;75202:13;;75106:125;74826:416;74807:435;;;75368:1;75362:3;:7;:36;;;;-1:-1:-1;75391:7:0;75373:5;75379:7;75385:1;75379:3;:7;:::i;:::-;75373:14;;;;;;;;:::i;:::-;;;;;;;;;:25;75362:36;75358:126;;;75422:7;75428:1;75422:3;:7;:::i;:::-;75415:14;;;;;;75358:126;-1:-1:-1;75469:3:0;-1:-1:-1;75462:10:0;;57047:108;56959:7;;;;57117:9;57109:38;;;;-1:-1:-1;;;57109:38:0;;23846:2:1;57109:38:0;;;23828:21:1;23885:2;23865:18;;;23858:30;-1:-1:-1;;;23904:18:1;;;23897:46;23960:18;;57109:38:0;23644:340:1;82274:336:0;82374:4;82380:7;82410:9;82405:170;82429:19;:26;82425:30;;82405:170;;;82507:4;82481:19;82501:1;82481:22;;;;;;;;:::i;:::-;;;;;;;;;:30;82477:87;;82540:4;;82546:1;;-1:-1:-1;82274:336:0;-1:-1:-1;;82274:336:0:o;82477:87::-;82457:3;;;;:::i;:::-;;;;82405:170;;;-1:-1:-1;82593:5:0;;;;-1:-1:-1;82274:336:0;-1:-1:-1;;82274:336:0:o;14279:70::-;12692:13;;;;;;;12684:69;;;;-1:-1:-1;;;12684:69:0;;;;;;;:::i;33043:248::-;12692:13;;;;;;;12684:69;;;;-1:-1:-1;;;12684:69:0;;;;;;;:::i;:::-;33208:9:::1;:21:::0;;-1:-1:-1;;33208:21:0::1;;::::0;::::1;;::::0;;33240:7:::1;:18;33250:8:::0;33240:7;:18:::1;:::i;:::-;-1:-1:-1::0;33269:5:0::1;:14;33277:6:::0;33269:5;:14:::1;:::i;20784:162::-:0;12692:13;;;;;;;12684:69;;;;-1:-1:-1;;;12684:69:0;;;;;;;:::i;:::-;20897:5:::1;:13;20905:5:::0;20897;:13:::1;:::i;:::-;-1:-1:-1::0;20921:7:0::1;:17;20931:7:::0;20921;:17:::1;:::i;56165:97::-:0;12692:13;;;;;;;12684:69;;;;-1:-1:-1;;;12684:69:0;;;;;;;:::i;:::-;56239:7:::1;:15:::0;;-1:-1:-1;;56239:15:0::1;::::0;;56165:97::o;76519:101::-;12692:13;;;;;;;12684:69;;;;-1:-1:-1;;;12684:69:0;;;;;;;:::i;:::-;76611:1:::1;76592:16;:20:::0;76519:101::o;85480:341::-;12692:13;;;;;;;12684:69;;;;-1:-1:-1;;;12684:69:0;;;;;;;:::i;:::-;85564:37:::1;45830:4;85595:5:::0;85564:10:::1;:37::i;:::-;85612:32;-1:-1:-1::0;;;;;;;;;;;85638:5:0::1;85612:10;:32::i;:::-;85655:30;52964:24;85679:5;85655:10;:30::i;:::-;85696;52723:24;85720:5;85696:10;:30::i;:::-;85737;-1:-1:-1::0;;;;;;;;;;;85761:5:0::1;85737:10;:30::i;:::-;85778:35;-1:-1:-1::0;;;;;;;;;;;85807:5:0::1;85778:10;:35::i;83466:212::-:0;83559:19;83593:26;;:30;;83622:1;;83593:30;:::i;:::-;83559:75;;;;;;;;:::i;:::-;;;;;;;;;83530:19;83550:5;83530:26;;;;;;;;:::i;:::-;;;;;;;;;;:104;83645:19;:25;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;83466:212;:::o;29889:453::-;30024:24;30051:25;30061:5;30068:7;30051:9;:25::i;:::-;30024:52;;-1:-1:-1;;30091:16:0;:37;30087:248;;30173:6;30153:16;:26;;30145:68;;;;-1:-1:-1;;;30145:68:0;;24463:2:1;30145:68:0;;;24445:21:1;24502:2;24482:18;;;24475:30;24541:31;24521:18;;;24514:59;24590:18;;30145:68:0;24261:353:1;30145:68:0;30257:51;30266:5;30273:7;30301:6;30282:16;:25;30257:8;:51::i;40285:451::-;40360:13;40386:19;40418:10;40422:6;40418:1;:10;:::i;:::-;:14;;40431:1;40418:14;:::i;:::-;40408:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40408:25:0;;40386:47;;-1:-1:-1;;;40444:6:0;40451:1;40444:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;40444:15:0;;;;;;;;;-1:-1:-1;;;40470:6:0;40477:1;40470:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;40470:15:0;;;;;;;;-1:-1:-1;40501:9:0;40513:10;40517:6;40513:1;:10;:::i;:::-;:14;;40526:1;40513:14;:::i;:::-;40501:26;;40496:135;40533:1;40529;:5;40496:135;;;-1:-1:-1;;;40581:5:0;40589:3;40581:11;40568:25;;;;;;;:::i;:::-;;;;40556:6;40563:1;40556:9;;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;;;;;40556:37:0;;;;;;;;-1:-1:-1;40618:1:0;40608:11;;;;;40536:3;;;:::i;:::-;;;40496:135;;;-1:-1:-1;40649:10:0;;40641:55;;;;-1:-1:-1;;;40641:55:0;;25135:2:1;40641:55:0;;;25117:21:1;;;25154:18;;;25147:30;25213:34;25193:18;;;25186:62;25265:18;;40641:55:0;24933:356:1;78864:704:0;79064:21;:19;:21::i;:::-;-1:-1:-1;;;;;79100:18:0;;;79096:465;;79178:28;79201:4;79178:22;:28::i;:::-;-1:-1:-1;;;;;79225:16:0;;;79221:206;;79291:26;79314:2;79291:22;:26::i;79221:206::-;79383:28;:26;:28::i;79096:465::-;79480:26;79503:2;79480:22;:26::i;61590:203::-;61740:10;;:45;;-1:-1:-1;;;61740:45:0;;-1:-1:-1;;;;;20884:15:1;;;61740:45:0;;;20866:34:1;20936:15;;;20916:18;;;20909:43;20968:18;;;20961:34;;;61716:4:0;;61740:10;;:27;;20801:18:1;;61740:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;65656:156::-;65718:7;65793:11;65803:1;65794:5;;;65793:11;:::i;:::-;65783:21;;65784:5;;;65783:21;:::i;50763:112::-;50842:25;50853:4;50859:7;50842:10;:25::i;81673:222::-;81724:12;81739:38;:36;:38::i;:::-;81724:53;-1:-1:-1;81792:8:0;;81788:100;;81817:16;:23;;;81855:21;:19;:21::i;81071:146::-;-1:-1:-1;;;;;81155:33:0;;;;;;:24;:33;;;;;;;;22408:9;:18;;;;;;;81139:70;;81155:33;81139:15;:70::i;81190:18::-;81139:15;:70::i;81225:118::-;81282:53;81298:21;81321:13;22224:12;;;22136:108;82618:534;82744:19;:26;82715:7;;82744:31;;82740:45;;-1:-1:-1;82784:1:0;;82618:534::o;82740:45::-;82796:18;82834:9;82829:288;82853:19;:26;82849:30;;82829:288;;;82949:15;82923:19;82943:1;82923:22;;;;;;;;:::i;:::-;;;;;;;;;:41;;:97;;;;;83010:10;82985:19;83005:1;82985:22;;;;;;;;:::i;:::-;;;;;;;;;:35;82923:97;82901:205;;;83068:19;83088:1;83068:22;;;;;;;;:::i;:::-;;;;;;;;;83055:35;;82901:205;82881:3;;;;:::i;:::-;;;;82829:288;;83160:298;83210:9;83234:217;83245:19;:26;83241:30;;83234:217;;;83318:15;83292:19;83312:1;83292:22;;;;;;;;:::i;:::-;;;;;;;;;:41;83288:152;;83354:23;83375:1;83354:20;:23::i;:::-;83234:217;;83288:152;83418:6;83423:1;83418:6;;:::i;:::-;;;83234:217;;81351:314;81460:15;81478:21;81992:16;;;81903:113;81478:21;81460:39;-1:-1:-1;81460:39:0;81514:28;81528:9;81514:13;:28::i;:::-;:38;81510:148;;;81569:27;;;;;;;;-1:-1:-1;81569:27:0;;;;;;;;;;;;;;81611:16;;;:35;;;;;;;;;;;;;;;81351:314::o;82024:242::-;82148:10;;82119:7;;82148:15;;82144:115;;-1:-1:-1;82187:1:0;;82024:242;-1:-1:-1;82024:242:0:o;82144:115::-;82232:10;;82228:3;;82232:14;;82245:1;;82232:14;:::i;:::-;82228:19;;;;;;;;:::i;:::-;;;;;;;;;82221:26;;82024:242;;;:::o;14:286:1:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:1;;209:43;;199:71;;266:1;263;256:12;497:250;582:1;592:113;606:6;603:1;600:13;592:113;;;682:11;;;676:18;663:11;;;656:39;628:2;621:10;592:113;;;-1:-1:-1;;739:1:1;721:16;;714:27;497:250::o;752:396::-;901:2;890:9;883:21;864:4;933:6;927:13;976:6;971:2;960:9;956:18;949:34;992:79;1064:6;1059:2;1048:9;1044:18;1039:2;1031:6;1027:15;992:79;:::i;:::-;1132:2;1111:15;-1:-1:-1;;1107:29:1;1092:45;;;;1139:2;1088:54;;752:396;-1:-1:-1;;752:396:1:o;1153:131::-;-1:-1:-1;;;;;1228:31:1;;1218:42;;1208:70;;1274:1;1271;1264:12;1289:315;1357:6;1365;1418:2;1406:9;1397:7;1393:23;1389:32;1386:52;;;1434:1;1431;1424:12;1386:52;1473:9;1460:23;1492:31;1517:5;1492:31;:::i;:::-;1542:5;1594:2;1579:18;;;;1566:32;;-1:-1:-1;;;1289:315:1:o;1791:456::-;1868:6;1876;1884;1937:2;1925:9;1916:7;1912:23;1908:32;1905:52;;;1953:1;1950;1943:12;1905:52;1992:9;1979:23;2011:31;2036:5;2011:31;:::i;:::-;2061:5;-1:-1:-1;2118:2:1;2103:18;;2090:32;2131:33;2090:32;2131:33;:::i;:::-;1791:456;;2183:7;;-1:-1:-1;;;2237:2:1;2222:18;;;;2209:32;;1791:456::o;2434:180::-;2493:6;2546:2;2534:9;2525:7;2521:23;2517:32;2514:52;;;2562:1;2559;2552:12;2514:52;-1:-1:-1;2585:23:1;;2434:180;-1:-1:-1;2434:180:1:o;2619:315::-;2687:6;2695;2748:2;2736:9;2727:7;2723:23;2719:32;2716:52;;;2764:1;2761;2754:12;2716:52;2800:9;2787:23;2777:33;;2860:2;2849:9;2845:18;2832:32;2873:31;2898:5;2873:31;:::i;:::-;2923:5;2913:15;;;2619:315;;;;;:::o;3128:383::-;3205:6;3213;3221;3274:2;3262:9;3253:7;3249:23;3245:32;3242:52;;;3290:1;3287;3280:12;3242:52;3329:9;3316:23;3348:31;3373:5;3348:31;:::i;:::-;3398:5;3450:2;3435:18;;3422:32;;-1:-1:-1;3501:2:1;3486:18;;;3473:32;;3128:383;-1:-1:-1;;;3128:383:1:o;3516:247::-;3575:6;3628:2;3616:9;3607:7;3603:23;3599:32;3596:52;;;3644:1;3641;3634:12;3596:52;3683:9;3670:23;3702:31;3727:5;3702:31;:::i;4273:127::-;4334:10;4329:3;4325:20;4322:1;4315:31;4365:4;4362:1;4355:15;4389:4;4386:1;4379:15;4405:275;4476:2;4470:9;4541:2;4522:13;;-1:-1:-1;;4518:27:1;4506:40;;4576:18;4561:34;;4597:22;;;4558:62;4555:88;;;4623:18;;:::i;:::-;4659:2;4652:22;4405:275;;-1:-1:-1;4405:275:1:o;4685:187::-;4734:4;4767:18;4759:6;4756:30;4753:56;;;4789:18;;:::i;:::-;-1:-1:-1;4855:2:1;4834:15;-1:-1:-1;;4830:29:1;4861:4;4826:40;;4685:187::o;4877:464::-;4920:5;4973:3;4966:4;4958:6;4954:17;4950:27;4940:55;;4991:1;4988;4981:12;4940:55;5027:6;5014:20;5058:49;5074:32;5103:2;5074:32;:::i;:::-;5058:49;:::i;:::-;5132:2;5123:7;5116:19;5178:3;5171:4;5166:2;5158:6;5154:15;5150:26;5147:35;5144:55;;;5195:1;5192;5185:12;5144:55;5260:2;5253:4;5245:6;5241:17;5234:4;5225:7;5221:18;5208:55;5308:1;5283:16;;;5301:4;5279:27;5272:38;;;;5287:7;4877:464;-1:-1:-1;;;4877:464:1:o;5346:322::-;5415:6;5468:2;5456:9;5447:7;5443:23;5439:32;5436:52;;;5484:1;5481;5474:12;5436:52;5524:9;5511:23;5557:18;5549:6;5546:30;5543:50;;;5589:1;5586;5579:12;5543:50;5612;5654:7;5645:6;5634:9;5630:22;5612:50;:::i;5673:114::-;5757:4;5750:5;5746:16;5739:5;5736:27;5726:55;;5777:1;5774;5767:12;5792:243;5849:6;5902:2;5890:9;5881:7;5877:23;5873:32;5870:52;;;5918:1;5915;5908:12;5870:52;5957:9;5944:23;5976:29;5999:5;5976:29;:::i;6312:1080::-;6447:6;6455;6463;6471;6479;6532:3;6520:9;6511:7;6507:23;6503:33;6500:53;;;6549:1;6546;6539:12;6500:53;6588:9;6575:23;6607:31;6632:5;6607:31;:::i;:::-;6657:5;-1:-1:-1;6713:2:1;6698:18;;6685:32;6736:18;6766:14;;;6763:34;;;6793:1;6790;6783:12;6763:34;6816:50;6858:7;6849:6;6838:9;6834:22;6816:50;:::i;:::-;6806:60;;6919:2;6908:9;6904:18;6891:32;6875:48;;6948:2;6938:8;6935:16;6932:36;;;6964:1;6961;6954:12;6932:36;6987:52;7031:7;7020:8;7009:9;7005:24;6987:52;:::i;:::-;6977:62;;7092:2;7081:9;7077:18;7064:32;7048:48;;7121:2;7111:8;7108:16;7105:36;;;7137:1;7134;7127:12;7105:36;7160:52;7204:7;7193:8;7182:9;7178:24;7160:52;:::i;:::-;7150:62;;7265:3;7254:9;7250:19;7237:33;7221:49;;7295:2;7285:8;7282:16;7279:36;;;7311:1;7308;7301:12;7279:36;;7334:52;7378:7;7367:8;7356:9;7352:24;7334:52;:::i;:::-;7324:62;;;6312:1080;;;;;;;;:::o;7397:248::-;7465:6;7473;7526:2;7514:9;7505:7;7501:23;7497:32;7494:52;;;7542:1;7539;7532:12;7494:52;-1:-1:-1;;7565:23:1;;;7635:2;7620:18;;;7607:32;;-1:-1:-1;7397:248:1:o;7650:388::-;7718:6;7726;7779:2;7767:9;7758:7;7754:23;7750:32;7747:52;;;7795:1;7792;7785:12;7747:52;7834:9;7821:23;7853:31;7878:5;7853:31;:::i;:::-;7903:5;-1:-1:-1;7960:2:1;7945:18;;7932:32;7973:33;7932:32;7973:33;:::i;8043:632::-;8214:2;8266:21;;;8336:13;;8239:18;;;8358:22;;;8185:4;;8214:2;8437:15;;;;8411:2;8396:18;;;8185:4;8480:169;8494:6;8491:1;8488:13;8480:169;;;8555:13;;8543:26;;8624:15;;;;8589:12;;;;8516:1;8509:9;8480:169;;;-1:-1:-1;8666:3:1;;8043:632;-1:-1:-1;;;;;;8043:632:1:o;8908:380::-;8987:1;8983:12;;;;9030;;;9051:61;;9105:4;9097:6;9093:17;9083:27;;9051:61;9158:2;9150:6;9147:14;9127:18;9124:38;9121:161;;9204:10;9199:3;9195:20;9192:1;9185:31;9239:4;9236:1;9229:15;9267:4;9264:1;9257:15;9709:127;9770:10;9765:3;9761:20;9758:1;9751:31;9801:4;9798:1;9791:15;9825:4;9822:1;9815:15;9841:125;9906:9;;;9927:10;;;9924:36;;;9940:18;;:::i;10503:545::-;10605:2;10600:3;10597:11;10594:448;;;10641:1;10666:5;10662:2;10655:17;10711:4;10707:2;10697:19;10781:2;10769:10;10765:19;10762:1;10758:27;10752:4;10748:38;10817:4;10805:10;10802:20;10799:47;;;-1:-1:-1;10840:4:1;10799:47;10895:2;10890:3;10886:12;10883:1;10879:20;10873:4;10869:31;10859:41;;10950:82;10968:2;10961:5;10958:13;10950:82;;;11013:17;;;10994:1;10983:13;10950:82;;11224:1352;11350:3;11344:10;11377:18;11369:6;11366:30;11363:56;;;11399:18;;:::i;:::-;11428:97;11518:6;11478:38;11510:4;11504:11;11478:38;:::i;:::-;11472:4;11428:97;:::i;:::-;11580:4;;11644:2;11633:14;;11661:1;11656:663;;;;12363:1;12380:6;12377:89;;;-1:-1:-1;12432:19:1;;;12426:26;12377:89;-1:-1:-1;;11181:1:1;11177:11;;;11173:24;11169:29;11159:40;11205:1;11201:11;;;11156:57;12479:81;;11626:944;;11656:663;10450:1;10443:14;;;10487:4;10474:18;;-1:-1:-1;;11692:20:1;;;11810:236;11824:7;11821:1;11818:14;11810:236;;;11913:19;;;11907:26;11892:42;;12005:27;;;;11973:1;11961:14;;;;11840:19;;11810:236;;;11814:3;12074:6;12065:7;12062:19;12059:201;;;12135:19;;;12129:26;-1:-1:-1;;12218:1:1;12214:14;;;12230:3;12210:24;12206:37;12202:42;12187:58;12172:74;;12059:201;-1:-1:-1;;;;;12306:1:1;12290:14;;;12286:22;12273:36;;-1:-1:-1;11224:1352:1:o;12581:289::-;12712:3;12750:6;12744:13;12766:66;12825:6;12820:3;12813:4;12805:6;12801:17;12766:66;:::i;:::-;12848:16;;;;;12581:289;-1:-1:-1;;12581:289:1:o;15808:127::-;15869:10;15864:3;15860:20;15857:1;15850:31;15900:4;15897:1;15890:15;15924:4;15921:1;15914:15;16745:128;16812:9;;;16833:11;;;16830:37;;;16847:18;;:::i;16878:649::-;16958:6;17011:2;16999:9;16990:7;16986:23;16982:32;16979:52;;;17027:1;17024;17017:12;16979:52;17060:9;17054:16;17093:18;17085:6;17082:30;17079:50;;;17125:1;17122;17115:12;17079:50;17148:22;;17201:4;17193:13;;17189:27;-1:-1:-1;17179:55:1;;17230:1;17227;17220:12;17179:55;17259:2;17253:9;17284:49;17300:32;17329:2;17300:32;:::i;17284:49::-;17356:2;17349:5;17342:17;17396:7;17391:2;17386;17382;17378:11;17374:20;17371:33;17368:53;;;17417:1;17414;17407:12;17368:53;17430:67;17494:2;17489;17482:5;17478:14;17473:2;17469;17465:11;17430:67;:::i;17891:404::-;18093:2;18075:21;;;18132:2;18112:18;;;18105:30;18171:34;18166:2;18151:18;;18144:62;-1:-1:-1;;;18237:2:1;18222:18;;18215:38;18285:3;18270:19;;17891:404::o;19517:407::-;19719:2;19701:21;;;19758:2;19738:18;;;19731:30;19797:34;19792:2;19777:18;;19770:62;-1:-1:-1;;;19863:2:1;19848:18;;19841:41;19914:3;19899:19;;19517:407::o;21006:247::-;21074:6;21127:2;21115:9;21106:7;21102:23;21098:32;21095:52;;;21143:1;21140;21133:12;21095:52;21175:9;21169:16;21194:29;21217:5;21194:29;:::i;21258:812::-;21669:25;21664:3;21657:38;21639:3;21724:6;21718:13;21740:75;21808:6;21803:2;21798:3;21794:12;21787:4;21779:6;21775:17;21740:75;:::i;:::-;-1:-1:-1;;;21874:2:1;21834:16;;;21866:11;;;21859:40;21924:13;;21946:76;21924:13;22008:2;22000:11;;21993:4;21981:17;;21946:76;:::i;:::-;22042:17;22061:2;22038:26;;21258:812;-1:-1:-1;;;;21258:812:1:o;23989:135::-;24028:3;24049:17;;;24046:43;;24069:18;;:::i;:::-;-1:-1:-1;24116:1:1;24105:13;;23989:135::o;24129:127::-;24190:10;24185:3;24181:20;24178:1;24171:31;24221:4;24218:1;24211:15;24245:4;24242:1;24235:15;24619:168;24692:9;;;24723;;24740:15;;;24734:22;;24720:37;24710:71;;24761:18;;:::i;24792:136::-;24831:3;24859:5;24849:39;;24868:18;;:::i;:::-;-1:-1:-1;;;24904:18:1;;24792:136::o;25294:277::-;25361:6;25414:2;25402:9;25393:7;25389:23;25385:32;25382:52;;;25430:1;25427;25420:12;25382:52;25462:9;25456:16;25515:5;25508:13;25501:21;25494:5;25491:32;25481:60;;25537:1;25534;25527:12;25576:217;25616:1;25642;25632:132;;25686:10;25681:3;25677:20;25674:1;25667:31;25721:4;25718:1;25711:15;25749:4;25746:1;25739:15;25632:132;-1:-1:-1;25778:9:1;;25576:217::o
Swarm Source
ipfs://a909904b22cdfda408a2defda054c455be54767f3c6f55aab9e1cc5736ee0044
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.