Source Code
Overview
S Balance
0 S
More Info
ContractCreator
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
5624128 | 17 hrs ago | 0 S | ||||
5525105 | 26 hrs ago | 0 S | ||||
5077904 | 3 days ago | 0 S | ||||
5077718 | 3 days ago | 0 S | ||||
5077639 | 3 days ago | 0 S | ||||
5077345 | 3 days ago | 0 S | ||||
5076726 | 3 days ago | 0 S | ||||
5076457 | 3 days ago | 0 S | ||||
5075987 | 3 days ago | 0 S | ||||
5043767 | 3 days ago | 0 S | ||||
5043250 | 3 days ago | 0 S | ||||
5043193 | 3 days ago | 0 S | ||||
5043121 | 3 days ago | 0 S | ||||
5037436 | 3 days ago | 0 S | ||||
5037142 | 3 days ago | 0 S | ||||
4839491 | 4 days ago | 0 S | ||||
4538913 | 5 days ago | 0 S | ||||
3206888 | 10 days ago | 0 S | ||||
3206888 | 10 days ago | 0 S | ||||
3206888 | 10 days ago | 0 S | ||||
3206888 | 10 days ago | 0 S | ||||
3206888 | 10 days ago | 0 S | ||||
3206888 | 10 days ago | 0 S | ||||
3206888 | 10 days ago | 0 S | ||||
3206888 | 10 days ago | 0 S |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Stablecoin
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; import {AggregatorV3Interface} from "chainlink-v2.7.2/src/v0.8/interfaces/AggregatorV3Interface.sol"; // solhint-disable-next-line max-line-length import {AccessControlEnumerableUpgradeable} from "openzeppelin-contracts-upgradeable-v4.9.5/contracts/access/AccessControlEnumerableUpgradeable.sol"; import {UUPSUpgradeable} from "openzeppelin-contracts-upgradeable-v4.9.5/contracts/proxy/utils/UUPSUpgradeable.sol"; // solhint-disable-next-line max-line-length import {PausableUpgradeable} from "openzeppelin-contracts-upgradeable-v4.9.5/contracts/security/PausableUpgradeable.sol"; import {ERC20Upgradeable} from "openzeppelin-contracts-upgradeable-v4.9.5/contracts/token/ERC20/ERC20Upgradeable.sol"; import {IERC20Upgradeable} from "openzeppelin-contracts-upgradeable-v4.9.5/contracts/token/ERC20/IERC20Upgradeable.sol"; // solhint-disable-next-line max-line-length import {SafeERC20Upgradeable} from "openzeppelin-contracts-upgradeable-v4.9.5/contracts/token/ERC20/utils/SafeERC20Upgradeable.sol"; import {Count} from "./library/ApprovalSet.sol"; import {MintOperations} from "./library/MintOperation.sol"; import {MintOperationArrays, OpIndices, OpIndex} from "./library/MintOperationArray.sol"; import {MintPools} from "./library/MintPool.sol"; import {MintPoolArrays, PoolIndices, PoolIndex} from "./library/MintPoolArray.sol"; import {ProofOfReserve} from "./library/ProofOfReserve.sol"; import {Redemption} from "./library/Redemption.sol"; contract Stablecoin is AccessControlEnumerableUpgradeable, UUPSUpgradeable, PausableUpgradeable, ERC20Upgradeable { using MintOperations for MintOperations.Op; using MintOperationArrays for MintOperationArrays.Array; using OpIndices for OpIndex; using MintPools for MintPools.Pool; using MintPoolArrays for MintPoolArrays.Array; using PoolIndices for PoolIndex; using ProofOfReserve for ProofOfReserve.Params; using Redemption for Redemption.Params; bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant MINT_RATIFIER_ROLE = keccak256("MINT_RATIFIER_ROLE"); bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); bytes32 public constant FROZEN_ROLE = keccak256("FROZEN_ROLE"); bytes32 public constant REDEMPTION_ADMIN_ROLE = keccak256("REDEMPTION_ADMIN_ROLE"); bytes32 public constant REDEMPTION_ADDRESS_ROLE = keccak256("REDEMPTION_ADDRESS_ROLE"); uint256 public constant CENT = 10 ** 16; address public constant MAX_REDEMPTION_ADDRESS = address(0x100000); MintOperationArrays.Array private _mintOperations; MintPoolArrays.Array private _mintPools; ProofOfReserve.Params private _proofOfReserveParams; Redemption.Params private _redemptionParams; event PushMintPool(PoolIndex poolIndex, Count signatures, uint256 threshold, uint256 limit); event PopMintPool(PoolIndex poolIndex); event SetMintSignatures(PoolIndex poolIndex, Count signatures); event SetMintThreshold(PoolIndex poolIndex, uint256 threshold); event SetMintLimit(PoolIndex poolIndex, uint256 limit); event EnableProofOfReserve(); event DisableProofOfReserve(); event SetProofOfReserveFeed(AggregatorV3Interface feed); event SetProofOfReserveHeartbeat(uint256 heartbeat); event SetRedemptionMin(uint256 min); event ApproveRefillMintPool(PoolIndex poolIndex, address approver); event FinalizeRefillMintPool(PoolIndex poolIndex); event RequestMint(OpIndex opIndex, address to, uint256 value, address requester); event RatifyMint(OpIndex opIndex, address ratifier); event FinalizeMint(OpIndex opIndex, PoolIndex poolIndex); event RevokeMint(OpIndex opIndex, address revoker); event Redeem(address redemptionAddress, uint256 amount); event Burn(address from, uint256 amount); event ReclaimEther(address admin, uint256 amount); event ReclaimToken(IERC20Upgradeable token, address admin, uint256 amount); error AccountHasFrozenRole(address account); error MintToAddressZeroOrRedemptionAddress(address to); error AmountDoesNotHaveExactCent(uint256 amount); constructor() { _disableInitializers(); } function initialize(string memory name_, string memory symbol_) public initializer { AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init(); ERC20Upgradeable.__ERC20_init(name_, symbol_); UUPSUpgradeable.__UUPSUpgradeable_init(); PausableUpgradeable.__Pausable_init(); _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); _setRoleAdmin(REDEMPTION_ADDRESS_ROLE, REDEMPTION_ADMIN_ROLE); _proofOfReserveParams.setDecimals(decimals()); assert(CENT == 10 ** (decimals() - 2)); } function _authorizeUpgrade(address) internal override onlyRole(DEFAULT_ADMIN_ROLE) {} function pause() external onlyRole(PAUSER_ROLE) { _pause(); } function unpause() external onlyRole(DEFAULT_ADMIN_ROLE) { _unpause(); } function _beforeTokenTransfer(address from, address to, uint256) internal view virtual override { if (hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) { return; } _requireNotPaused(); if (hasRole(FROZEN_ROLE, from)) { revert AccountHasFrozenRole(from); } if (hasRole(FROZEN_ROLE, to)) { revert AccountHasFrozenRole(to); } } function _afterTokenTransfer(address, address to, uint256 amount) internal virtual override { if (to != address(0) && uint160(to) <= uint160(MAX_REDEMPTION_ADDRESS)) { _checkRole(REDEMPTION_ADDRESS_ROLE, to); if (amount % CENT != 0) { revert AmountDoesNotHaveExactCent(amount); } _redemptionParams.checkRedemption(amount); _burn(to, amount); emit Redeem(to, amount); } } function _isMintRatifier(address address_) private view returns (bool) { return hasRole(MINT_RATIFIER_ROLE, address_); } function _isUnfiltered(address) private pure returns (bool) { return true; } function viewMintPoolsCount() external view returns (PoolIndex) { return _mintPools.length(); } function viewMintPool(PoolIndex poolIndex) external view returns (Count, uint256, uint256, uint256, Count, Count) { MintPools.Pool storage pool = _mintPools.at(poolIndex); return ( pool.signatures(), pool.threshold(), pool.limit(), pool.value(), pool.refillApprovalsCount(_isMintRatifier), pool.refillApprovalsCount(_isUnfiltered) ); } function viewUnfilteredMintPoolRefillApproval( PoolIndex poolIndex, Count refillApprovalIndex ) external view returns (address) { return _mintPools.at(poolIndex).refillApprovalAtIndex(refillApprovalIndex); } function viewMintOperationsCount() external view returns (OpIndex) { return _mintOperations.length(); } function viewMintOperation( OpIndex opIndex ) external view returns (MintOperations.Status, address, uint256, Count, Count) { MintOperations.Op storage operation = _mintOperations.at(opIndex); return ( operation.status(), operation.to(), operation.value(), operation.ratifierApprovals(_isMintRatifier), operation.ratifierApprovals(_isUnfiltered) ); } function viewUnfilteredMintOperationRatifierApproval( OpIndex opIndex, Count ratifierApprovalIndex ) external view returns (address) { return _mintOperations.at(opIndex).ratifierApprovalAtIndex(ratifierApprovalIndex); } function viewProofOfReserve() external view returns (bool, uint8, AggregatorV3Interface, uint256) { return ( _proofOfReserveParams.enabled(), _proofOfReserveParams.decimals(), _proofOfReserveParams.feed(), _proofOfReserveParams.heartbeat() ); } function viewMinimumRedemptionAmount() external view returns (uint256) { return _redemptionParams.min(); } function pushMintPool(Count signatures, uint256 threshold, uint256 limit) external onlyRole(DEFAULT_ADMIN_ROLE) { PoolIndex poolIndex = _mintPools.length(); _mintPools.push(); _mintPools.setSignatures(poolIndex, signatures); _mintPools.setThreshold(poolIndex, threshold); _mintPools.setLimit(poolIndex, limit); refillLastMintPoolFromAdmin(); emit PushMintPool(poolIndex, signatures, threshold, limit); } function popMintPool() external onlyRole(DEFAULT_ADMIN_ROLE) { _mintPools.pop(); emit PopMintPool(_mintPools.length()); } function setMintSignatures(PoolIndex poolIndex, Count signatures) external onlyRole(DEFAULT_ADMIN_ROLE) { _mintPools.setSignatures(poolIndex, signatures); emit SetMintSignatures(poolIndex, signatures); } function setMintThreshold(PoolIndex poolIndex, uint256 threshold) external onlyRole(DEFAULT_ADMIN_ROLE) { _mintPools.setThreshold(poolIndex, threshold); emit SetMintThreshold(poolIndex, threshold); } function setMintLimit(PoolIndex poolIndex, uint256 limit) external onlyRole(DEFAULT_ADMIN_ROLE) { _mintPools.setLimit(poolIndex, limit); emit SetMintLimit(poolIndex, limit); } function enableProofOfReserve() external onlyRole(PAUSER_ROLE) { _proofOfReserveParams.setEnabled(true); emit EnableProofOfReserve(); } function disableProofOfReserve() external onlyRole(PAUSER_ROLE) { _proofOfReserveParams.setEnabled(false); emit DisableProofOfReserve(); } function setProofOfReserveFeed(AggregatorV3Interface feed) external onlyRole(DEFAULT_ADMIN_ROLE) { _proofOfReserveParams.setFeed(feed); emit SetProofOfReserveFeed(feed); } function setProofOfReserveHeartbeat(uint256 heartbeat) external onlyRole(DEFAULT_ADMIN_ROLE) { _proofOfReserveParams.setHeartbeat(heartbeat); emit SetProofOfReserveHeartbeat(heartbeat); } function setRedemptionMin(uint256 min) external onlyRole(DEFAULT_ADMIN_ROLE) { _redemptionParams.setMin(min); emit SetRedemptionMin(min); } function approveRefillMintPoolFromNextPool(PoolIndex poolIndex) public onlyRole(MINT_RATIFIER_ROLE) { _mintPools.at(poolIndex).approveRefillFromPool(msg.sender); emit ApproveRefillMintPool(poolIndex, msg.sender); } function finalizeRefillMintPoolFromNextPool(PoolIndex poolIndex) public { _mintPools.at(poolIndex).finalizeRefillFromPool(_mintPools.at(poolIndex.next()), _isMintRatifier); emit FinalizeRefillMintPool(poolIndex); } function approveThenFinalizeRefillMintPoolFromNextPool(PoolIndex poolIndex) external { approveRefillMintPoolFromNextPool(poolIndex); finalizeRefillMintPoolFromNextPool(poolIndex); } function refillLastMintPoolFromAdmin() public onlyRole(DEFAULT_ADMIN_ROLE) { PoolIndex lastPoolIndex = _mintPools.length().prev(); _mintPools.at(lastPoolIndex).refillFromAdmin(); emit ApproveRefillMintPool(lastPoolIndex, msg.sender); emit FinalizeRefillMintPool(lastPoolIndex); } function requestMint(address to, uint256 value) public onlyRole(MINTER_ROLE) { if (uint160(to) <= uint160(MAX_REDEMPTION_ADDRESS)) { revert MintToAddressZeroOrRedemptionAddress(to); } if (value % CENT != 0) { revert AmountDoesNotHaveExactCent(value); } OpIndex opIndex = _mintOperations.length(); _mintOperations.push().request(to, value); emit RequestMint(opIndex, to, value, msg.sender); } function ratifyMint(OpIndex opIndex) public onlyRole(MINT_RATIFIER_ROLE) { _mintOperations.at(opIndex).approve(msg.sender); emit RatifyMint(opIndex, msg.sender); } function finalizeMint(OpIndex opIndex, PoolIndex poolIndex) public { MintOperations.Op storage op = _mintOperations.at(opIndex); MintPools.Pool storage pool = _mintPools.at(poolIndex); uint256 value = op.value(); _proofOfReserveParams.checkMint(value, totalSupply()); op.finalize(pool.signatures(), _isMintRatifier); pool.spend(value); _mint(op.to(), value); emit FinalizeMint(opIndex, poolIndex); } function requestThenFinalizeMint(address to, uint256 value, PoolIndex poolIndex) external { OpIndex opIndex = _mintOperations.length(); requestMint(to, value); finalizeMint(opIndex, poolIndex); } function ratifyThenFinalizeMint(OpIndex opIndex, PoolIndex poolIndex) external { ratifyMint(opIndex); finalizeMint(opIndex, poolIndex); } function revokeMint(OpIndex opIndex) external onlyRole(MINT_RATIFIER_ROLE) { _mintOperations.at(opIndex).revoke(); emit RevokeMint(opIndex, msg.sender); } function burn(address account, uint256 amount) external onlyRole(DEFAULT_ADMIN_ROLE) { if (amount % CENT != 0) { revert AmountDoesNotHaveExactCent(amount); } _burn(account, amount); emit Burn(account, amount); } function reclaimEther() external onlyRole(DEFAULT_ADMIN_ROLE) { uint256 balance = address(this).balance; payable(msg.sender).transfer(balance); emit ReclaimEther(msg.sender, balance); } function reclaimToken(IERC20Upgradeable token) external onlyRole(DEFAULT_ADMIN_ROLE) { uint256 balance = token.balanceOf(address(this)); SafeERC20Upgradeable.safeTransfer(token, msg.sender, balance); emit ReclaimToken(token, msg.sender, balance); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); function getRoundData( uint80 _roundId ) external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); function latestRoundData() external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol) pragma solidity ^0.8.0; import "./IAccessControlEnumerableUpgradeable.sol"; import "./AccessControlUpgradeable.sol"; import "../utils/structs/EnumerableSetUpgradeable.sol"; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Extension of {AccessControl} that allows enumerating the members of each role. */ abstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable { using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet; mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers; function __AccessControlEnumerable_init() internal onlyInitializing { } function __AccessControlEnumerable_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) { return _roleMembers[role].at(index); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) { return _roleMembers[role].length(); } /** * @dev Overload {_grantRole} to track enumerable memberships */ function _grantRole(bytes32 role, address account) internal virtual override { super._grantRole(role, account); _roleMembers[role].add(account); } /** * @dev Overload {_revokeRole} to track enumerable memberships */ function _revokeRole(bytes32 role, address account) internal virtual override { super._revokeRole(role, account); _roleMembers[role].remove(account); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../ERC1967/ERC1967UpgradeUpgradeable.sol"; import {Initializable} from "./Initializable.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } function __UUPSUpgradeable_init() internal onlyInitializing { } function __UUPSUpgradeable_init_unchained() internal onlyInitializing { } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate the implementation's compatibility when performing an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. * * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function upgradeTo(address newImplementation) public virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. * * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __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; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20Upgradeable.sol"; import "./extensions/IERC20MetadataUpgradeable.sol"; import "../../utils/ContextUpgradeable.sol"; import {Initializable} from "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing { __ERC20_init_unchained(name_, symbol_); } function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the default value returned by this function, unless * it's overridden. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer(address from, address to, uint256 amount) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. _balances[to] += amount; } emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _balances[account] += amount; } emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[45] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20Upgradeable.sol"; import "../extensions/IERC20PermitUpgradeable.sol"; import "../../../utils/AddressUpgradeable.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20Upgradeable { using AddressUpgradeable for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20PermitUpgradeable token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token)); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; // solhint-disable-next-line max-line-length import {EnumerableSetUpgradeable} from "openzeppelin-contracts-upgradeable-v4.9.5/contracts/utils/structs/EnumerableSetUpgradeable.sol"; type Count is uint256; using {lt as <, lte as <=, eq as ==, gte as >=, gt as >} for Count global; function lt(Count self, Count other) pure returns (bool) { return Count.unwrap(self) < Count.unwrap(other); } function lte(Count self, Count other) pure returns (bool) { return Count.unwrap(self) <= Count.unwrap(other); } function eq(Count self, Count other) pure returns (bool) { return Count.unwrap(self) == Count.unwrap(other); } function gte(Count self, Count other) pure returns (bool) { return Count.unwrap(self) >= Count.unwrap(other); } function gt(Count self, Count other) pure returns (bool) { return Count.unwrap(self) > Count.unwrap(other); } /** * [WARNING] * ==== * Trying to delete this structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/structs/EnumerableSet.sol for * more info. * * Call removeAll() in order to safely destroy this structure * ==== */ library ApprovalSets { using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet; Count internal constant MAX_COUNT = Count.wrap(8); struct Set { EnumerableSetUpgradeable.AddressSet _approvalSet; } error ApprovalsCountAboveLimit(); error ApprovalAlreadyPresentInSet(address address_); function at(Set storage self, Count index_) internal view returns (address) { return self._approvalSet.at(Count.unwrap(index_)); } function count(Set storage self, function(address) view returns (bool) filter) internal view returns (Count) { uint256 length = self._approvalSet.length(); assert(Count.wrap(length) <= MAX_COUNT); uint256 result = 0; for (uint256 i; i < length; i++) { if (filter(self._approvalSet.at(i))) { result++; } } return Count.wrap(result); } function add(Set storage self, address address_) internal { if (Count.wrap(self._approvalSet.length()) >= MAX_COUNT) { revert ApprovalsCountAboveLimit(); } if (!self._approvalSet.add(address_)) { revert ApprovalAlreadyPresentInSet(address_); } } function removeAll(Set storage self) internal { for (uint256 i = self._approvalSet.length(); i > 0; i--) { assert(self._approvalSet.remove(self._approvalSet.at(i - 1))); } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; import {ApprovalSets, Count} from "./ApprovalSet.sol"; /** * [WARNING] * ==== * Trying to delete this structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/structs/EnumerableSet.sol for * more info. * ==== */ library MintOperations { using ApprovalSets for ApprovalSets.Set; using MintOperations for MintOperations.Op; enum Status { None, Requested, Finalized, Revoked } struct Op { Status _status; address _to; uint256 _value; ApprovalSets.Set _ratifierApprovals; } error RatifierApprovalsLessThanRequiredApprovals(Count ratifierApprovals, Count requiredApprovals); error CurrentStatusIsNotRequiredStatus(Status currentStatus, Status requiredStatus); error MintRequestReceiverIsAddressZero(); error MintRequestAmountIsZero(); modifier onlyStatus(MintOperations.Op storage self, Status requiredStatus) { if (self._status != requiredStatus) { revert CurrentStatusIsNotRequiredStatus(self._status, requiredStatus); } _; } function status(MintOperations.Op storage self) internal view returns (Status) { return self._status; } function to(MintOperations.Op storage self) internal view returns (address) { return self._to; } function value(MintOperations.Op storage self) internal view returns (uint256) { return self._value; } function ratifierApprovals( MintOperations.Op storage self, function(address) view returns (bool) filter ) internal view returns (Count) { return self._ratifierApprovals.count(filter); } function ratifierApprovalAtIndex( MintOperations.Op storage self, Count ratifierApprovalIndex ) internal view returns (address) { return self._ratifierApprovals.at(ratifierApprovalIndex); } function request( MintOperations.Op storage self, address to_, uint256 value_ ) internal onlyStatus(self, Status.None) { assert(self._to == address(0)); assert(self._value == 0); if (to_ == address(0)) { revert MintRequestReceiverIsAddressZero(); } if (value_ == 0) { revert MintRequestAmountIsZero(); } self._status = Status.Requested; self._to = to_; self._value = value_; } function approve(MintOperations.Op storage self, address ratifier) internal onlyStatus(self, Status.Requested) { self._ratifierApprovals.add(ratifier); } function finalize( MintOperations.Op storage self, Count requiredApprovals, function(address) view returns (bool) filter ) internal onlyStatus(self, Status.Requested) { if (self._ratifierApprovals.count(filter) < requiredApprovals) { revert RatifierApprovalsLessThanRequiredApprovals(self._ratifierApprovals.count(filter), requiredApprovals); } self._status = MintOperations.Status.Finalized; } function revoke(MintOperations.Op storage self) internal onlyStatus(self, Status.Requested) { self._status = MintOperations.Status.Revoked; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; import {MintOperations} from "./MintOperation.sol"; type OpIndex is uint256; library OpIndices { function prev(OpIndex self) internal pure returns (OpIndex) { return OpIndex.wrap(OpIndex.unwrap(self) - 1); } function next(OpIndex self) internal pure returns (OpIndex) { return OpIndex.wrap(OpIndex.unwrap(self) + 1); } } library MintOperationArrays { struct Array { MintOperations.Op[] _array; } function at( MintOperationArrays.Array storage self, OpIndex opIndex ) internal view returns (MintOperations.Op storage) { return self._array[OpIndex.unwrap(opIndex)]; } function length(MintOperationArrays.Array storage self) internal view returns (OpIndex) { return OpIndex.wrap(self._array.length); } function push(MintOperationArrays.Array storage self) internal returns (MintOperations.Op storage) { return self._array.push(); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; import {MathUpgradeable} from "openzeppelin-contracts-upgradeable-v4.9.5/contracts/utils/math/MathUpgradeable.sol"; import {ApprovalSets, Count} from "./ApprovalSet.sol"; /** * [WARNING] * ==== * Trying to delete this structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/structs/EnumerableSet.sol for * more info. * * Call destructor() in order to safely destroy this structure * ==== */ library MintPools { using ApprovalSets for ApprovalSets.Set; using MintPools for MintPools.Pool; struct Pool { Count _signatures; uint256 _threshold; uint256 _limit; uint256 _value; ApprovalSets.Set _refillApprovals; } error SpendAmountGreaterThanMintPoolThreshold(uint256 amount, uint256 mintPoolThreshold); error SpendAmountGreaterThanMintPoolValue(uint256 amount, uint256 mintPoolValue); error RefillApprovalsLessThanOtherPoolSignatures(Count approvals, Count signatures); error RefillPoolFromItself(); error SignaturesGreaterThanMaxCount(Count signatures, Count maxCount); error ThresholdExceedsLimit(uint256 threshold, uint256 limit); function signatures(MintPools.Pool storage self) internal view returns (Count) { return self._signatures; } function threshold(MintPools.Pool storage self) internal view returns (uint256) { return self._threshold; } function limit(MintPools.Pool storage self) internal view returns (uint256) { return self._limit; } function value(MintPools.Pool storage self) internal view returns (uint256) { return self._value; } function refillApprovalsCount( MintPools.Pool storage self, function(address) view returns (bool) filter ) internal view returns (Count) { return self._refillApprovals.count(filter); } function refillApprovalAtIndex( MintPools.Pool storage self, Count refillApprovalIndex ) internal view returns (address) { return self._refillApprovals.at(refillApprovalIndex); } function setSignatures(MintPools.Pool storage self, Count signatures_) internal { if (signatures_ > ApprovalSets.MAX_COUNT) { revert SignaturesGreaterThanMaxCount(signatures_, ApprovalSets.MAX_COUNT); } self._signatures = signatures_; } function setThreshold(MintPools.Pool storage self, uint256 threshold_) internal { if (threshold_ > self.limit()) { revert ThresholdExceedsLimit(threshold_, self.limit()); } self._threshold = threshold_; } function setLimit(MintPools.Pool storage self, uint256 limit_) internal { if (limit_ < self.threshold()) { revert ThresholdExceedsLimit(self.threshold(), limit_); } self._limit = limit_; self._value = MathUpgradeable.min(self._value, limit_); } function spend(MintPools.Pool storage self, uint256 amount) internal { assert(self._value <= self._limit); if (amount > self._threshold) { revert SpendAmountGreaterThanMintPoolThreshold(amount, self._threshold); } if (amount > self._value) { revert SpendAmountGreaterThanMintPoolValue(amount, self._value); } self._value -= amount; } function approveRefillFromPool(MintPools.Pool storage self, address ratifier) internal { self._refillApprovals.add(ratifier); } function finalizeRefillFromPool( MintPools.Pool storage self, MintPools.Pool storage other, function(address) view returns (bool) filter ) internal { if (self.eq(other)) { revert RefillPoolFromItself(); } if (self._refillApprovals.count(filter) < other._signatures) { revert RefillApprovalsLessThanOtherPoolSignatures(self._refillApprovals.count(filter), other._signatures); } self._refillApprovals.removeAll(); assert(self._value <= self._limit); uint256 refillAmount = self._limit - self._value; other.spend(refillAmount); self._value += refillAmount; assert(self._value == self._limit); } function refillFromAdmin(MintPools.Pool storage self) internal { self._value = self._limit; } function destructor(MintPools.Pool storage self) internal { self._refillApprovals.removeAll(); } function eq(MintPools.Pool storage self, MintPools.Pool storage other) internal pure returns (bool) { bool slotEq; assembly { slotEq := eq(self.slot, other.slot) } return slotEq; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; import {ApprovalSets, Count} from "./ApprovalSet.sol"; import {MintPools} from "./MintPool.sol"; type PoolIndex is uint256; using {lt as <, gt as >} for PoolIndex global; function lt(PoolIndex self, PoolIndex other) pure returns (bool) { return PoolIndex.unwrap(self) < PoolIndex.unwrap(other); } function gt(PoolIndex self, PoolIndex other) pure returns (bool) { return PoolIndex.unwrap(self) > PoolIndex.unwrap(other); } library PoolIndices { PoolIndex internal constant ZERO = PoolIndex.wrap(0); function prev(PoolIndex self) internal pure returns (PoolIndex) { return PoolIndex.wrap(PoolIndex.unwrap(self) - 1); } function next(PoolIndex self) internal pure returns (PoolIndex) { return PoolIndex.wrap(PoolIndex.unwrap(self) + 1); } } library MintPoolArrays { using MintPools for MintPools.Pool; using MintPoolArrays for MintPoolArrays.Array; using PoolIndices for PoolIndex; struct Array { MintPools.Pool[] _array; } error PoolSignaturesLessThanPreviousPoolSignatures(Count signatures, Count prevSignatures); error PoolSignaturesGreaterThanNextPoolSignatures(Count signatures, Count nextSignatures); error PoolThresholdLessThanPreviousPoolThreshold(uint256 threshold, uint256 prevThreshold); error PoolThresholdGreaterThanNextPoolThreshold(uint256 threshold, uint256 nextThreshold); error PoolThresholdLessThanPreviousPoolLimit(uint256 threshold, uint256 prevLimit); error PoolLimitLessThanPreviousPoolLimit(uint256 limit, uint256 prevLimit); error PoolLimitGreaterThanNextPoolLimit(uint256 limit, uint256 nextLimit); error PoolLimitGreaterThanNextPoolThreshold(uint256 limit, uint256 nextThreshold); function at(MintPoolArrays.Array storage self, PoolIndex poolIndex) internal view returns (MintPools.Pool storage) { return self._array[PoolIndex.unwrap(poolIndex)]; } function length(MintPoolArrays.Array storage self) internal view returns (PoolIndex) { return PoolIndex.wrap(self._array.length); } function push(MintPoolArrays.Array storage self) internal { MintPools.Pool storage last = self._array.push(); last.setLimit(type(uint256).max); last.setThreshold(type(uint256).max); last.setSignatures(ApprovalSets.MAX_COUNT); } function pop(MintPoolArrays.Array storage self) internal { self._array[self._array.length - 1].destructor(); self._array.pop(); } function setSignatures(MintPoolArrays.Array storage self, PoolIndex poolIndex, Count signatures) internal { if (poolIndex > PoolIndices.ZERO && signatures < self.at(poolIndex.prev()).signatures()) { revert PoolSignaturesLessThanPreviousPoolSignatures(signatures, self.at(poolIndex.prev()).signatures()); } if (poolIndex.next() < self.length() && signatures > self.at(poolIndex.next()).signatures()) { revert PoolSignaturesGreaterThanNextPoolSignatures(signatures, self.at(poolIndex.next()).signatures()); } self.at(poolIndex).setSignatures(signatures); } function setThreshold(MintPoolArrays.Array storage self, PoolIndex poolIndex, uint256 threshold) internal { if (poolIndex > PoolIndices.ZERO && threshold < self.at(poolIndex.prev()).threshold()) { revert PoolThresholdLessThanPreviousPoolThreshold(threshold, self.at(poolIndex.prev()).threshold()); } if (poolIndex > PoolIndices.ZERO && threshold < self.at(poolIndex.prev()).limit()) { revert PoolThresholdLessThanPreviousPoolLimit(threshold, self.at(poolIndex.prev()).limit()); } if (poolIndex.next() < self.length() && threshold > self.at(poolIndex.next()).threshold()) { revert PoolThresholdGreaterThanNextPoolThreshold(threshold, self.at(poolIndex.next()).threshold()); } self.at(poolIndex).setThreshold(threshold); } function setLimit(MintPoolArrays.Array storage self, PoolIndex poolIndex, uint256 limit) internal { if (poolIndex > PoolIndices.ZERO && limit < self.at(poolIndex.prev()).limit()) { revert PoolLimitLessThanPreviousPoolLimit(limit, self.at(poolIndex.prev()).limit()); } if (poolIndex.next() < self.length() && limit > self.at(poolIndex.next()).limit()) { revert PoolLimitGreaterThanNextPoolLimit(limit, self.at(poolIndex.next()).limit()); } if (poolIndex.next() < self.length() && limit > self.at(poolIndex.next()).threshold()) { revert PoolLimitGreaterThanNextPoolThreshold(limit, self.at(poolIndex.next()).threshold()); } self.at(poolIndex).setLimit(limit); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; import {AggregatorV3Interface} from "chainlink-v2.7.2/src/v0.8/interfaces/AggregatorV3Interface.sol"; library ProofOfReserve { using ProofOfReserve for ProofOfReserve.Params; struct Params { bool _enabled; AggregatorV3Interface _feed; uint8 _decimals; uint256 _heartbeat; uint256[48] __gap; } error ProofOfReserveFeedIsAddressZero(); error ProofOfReserveHeartbeatIsZero(); error ProofOfReserveFeedDecimalsDoNotMatch(uint8 chainReserveFeedDecimals, uint8 paramsDecimals); error ProofOfReserveFeedSignedReservesLessThanOrEqualToZero(int256 signedReserves); error ProofOfReserveFeedUpdatedAfterBlockTimestamp(uint256 updatedAt, uint256 blockTimestamp); error ProofOfReserveFeedUpdatedBeforeHeartbeat(uint256 updatedAtPlusHeartbeat, uint256 blockTimestamp); error ProofOfReserveTotalSupplyAfterMintWouldExceedReserves(uint256 totalSupplyAfterMint, uint256 reserves); function enabled(ProofOfReserve.Params storage self) internal view returns (bool) { return self._enabled; } function feed(ProofOfReserve.Params storage self) internal view returns (AggregatorV3Interface) { return self._feed; } function decimals(ProofOfReserve.Params storage self) internal view returns (uint8) { return self._decimals; } function heartbeat(ProofOfReserve.Params storage self) internal view returns (uint256) { return self._heartbeat; } function checkMint(ProofOfReserve.Params storage self, uint256 amount, uint256 totalSupply) internal view { if (!self._enabled) { return; } assert(address(self._feed) != address(0)); if (self._feed.decimals() != self._decimals) { revert ProofOfReserveFeedDecimalsDoNotMatch(self._feed.decimals(), self._decimals); } // slither-disable-next-line unused-return (, int256 signedReserves, , uint256 updatedAt, ) = self._feed.latestRoundData(); if (signedReserves <= 0) { revert ProofOfReserveFeedSignedReservesLessThanOrEqualToZero(signedReserves); } uint256 reserves = uint256(signedReserves); if (updatedAt > block.timestamp) { revert ProofOfReserveFeedUpdatedAfterBlockTimestamp(updatedAt, block.timestamp); } if (updatedAt + self._heartbeat < block.timestamp) { revert ProofOfReserveFeedUpdatedBeforeHeartbeat(updatedAt + self._heartbeat, block.timestamp); } if (totalSupply + amount > reserves) { revert ProofOfReserveTotalSupplyAfterMintWouldExceedReserves(totalSupply + amount, reserves); } } function setEnabled(ProofOfReserve.Params storage self, bool enabled_) internal { if (enabled_) { if (address(self._feed) == address(0)) { revert ProofOfReserveFeedIsAddressZero(); } if (self._heartbeat == 0) { revert ProofOfReserveHeartbeatIsZero(); } } self._enabled = enabled_; } function setFeed(ProofOfReserve.Params storage self, AggregatorV3Interface feed_) internal { self._feed = feed_; if (address(feed_) == address(0)) { self.setEnabled(false); } } function setDecimals(ProofOfReserve.Params storage self, uint8 decimals_) internal { self._decimals = decimals_; } function setHeartbeat(ProofOfReserve.Params storage self, uint256 heartbeat_) internal { self._heartbeat = heartbeat_; if (heartbeat_ == 0) { self.setEnabled(false); } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; library Redemption { using Redemption for Redemption.Params; struct Params { uint256 _min; uint256[49] __gap; } error RedemptionAmountLessThanMin(uint256 amount, uint256 min); function min(Redemption.Params storage self) internal view returns (uint256) { return self._min; } function checkRedemption(Redemption.Params storage self, uint256 amount) internal view { if (amount < self._min) { revert RedemptionAmountLessThanMin(amount, self._min); } } function setMin(Redemption.Params storage self, uint256 min_) internal { self._min = min_; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol) pragma solidity ^0.8.0; import "./IAccessControlUpgradeable.sol"; /** * @dev External interface of AccessControlEnumerable declared to support ERC165 detection. */ interface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable { /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) external view returns (address); /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControlUpgradeable.sol"; import "../utils/ContextUpgradeable.sol"; import "../utils/StringsUpgradeable.sol"; import "../utils/introspection/ERC165Upgradeable.sol"; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ```solidity * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ```solidity * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable { 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); _; } function __AccessControl_init() internal onlyInitializing { } function __AccessControl_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(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(account), " 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; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ```solidity * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSetUpgradeable { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822ProxiableUpgradeable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeaconUpgradeable.sol"; import "../../interfaces/IERC1967Upgradeable.sol"; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/StorageSlotUpgradeable.sol"; import {Initializable} from "../utils/Initializable.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ */ abstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable { // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; function __ERC1967Upgrade_init() internal onlyInitializing { } function __ERC1967Upgrade_init_unchained() internal onlyInitializing { } /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { AddressUpgradeable.functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), 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; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) pragma solidity ^0.8.0; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20Upgradeable.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20MetadataUpgradeable is IERC20Upgradeable { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20PermitUpgradeable { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts 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; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/MathUpgradeable.sol"; import "./math/SignedMathUpgradeable.sol"; /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = MathUpgradeable.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMathUpgradeable.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, MathUpgradeable.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165Upgradeable.sol"; import {Initializable} from "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing { } 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; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol) pragma solidity ^0.8.0; /** * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. * * _Available since v4.8.3._ */ interface IERC1967Upgradeable { /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Emitted when the beacon is changed. */ event BeaconUpgraded(address indexed beacon); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMathUpgradeable { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts 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); }
{ "remappings": [ "ERC4626/=lib/properties/lib/ERC4626/contracts/", "chainlink-v2.7.2/=lib/chainlink-v2.7.2/contracts/", "ds-test/=lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts-upgradeable-v4.9.5/lib/erc4626-tests/", "forge-deploy/=lib/forge-deploy/src/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts-upgradeable-v4.9.5/=lib/openzeppelin-contracts-upgradeable-v4.9.5/", "openzeppelin-contracts-v4.9.5/=lib/openzeppelin-contracts-v4.9.5/", "properties/=lib/properties/contracts/", "solmate/=lib/properties/lib/solmate/src/", "surl/=lib/surl/src/", "openzeppelin-contracts/=lib/properties/lib/openzeppelin-contracts/", "openzeppelin/=lib/openzeppelin-contracts-upgradeable-v4.9.5/contracts/", "solidity-stringutils/=lib/surl/lib/solidity-stringutils/" ], "optimizer": { "enabled": true, "runs": 20000 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "evmVersion": "paris", "viaIR": false, "libraries": {} }
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AccountHasFrozenRole","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AmountDoesNotHaveExactCent","type":"error"},{"inputs":[{"internalType":"address","name":"address_","type":"address"}],"name":"ApprovalAlreadyPresentInSet","type":"error"},{"inputs":[],"name":"ApprovalsCountAboveLimit","type":"error"},{"inputs":[{"internalType":"enum MintOperations.Status","name":"currentStatus","type":"uint8"},{"internalType":"enum MintOperations.Status","name":"requiredStatus","type":"uint8"}],"name":"CurrentStatusIsNotRequiredStatus","type":"error"},{"inputs":[],"name":"MintRequestAmountIsZero","type":"error"},{"inputs":[],"name":"MintRequestReceiverIsAddressZero","type":"error"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"MintToAddressZeroOrRedemptionAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"limit","type":"uint256"},{"internalType":"uint256","name":"nextLimit","type":"uint256"}],"name":"PoolLimitGreaterThanNextPoolLimit","type":"error"},{"inputs":[{"internalType":"uint256","name":"limit","type":"uint256"},{"internalType":"uint256","name":"nextThreshold","type":"uint256"}],"name":"PoolLimitGreaterThanNextPoolThreshold","type":"error"},{"inputs":[{"internalType":"uint256","name":"limit","type":"uint256"},{"internalType":"uint256","name":"prevLimit","type":"uint256"}],"name":"PoolLimitLessThanPreviousPoolLimit","type":"error"},{"inputs":[{"internalType":"Count","name":"signatures","type":"uint256"},{"internalType":"Count","name":"nextSignatures","type":"uint256"}],"name":"PoolSignaturesGreaterThanNextPoolSignatures","type":"error"},{"inputs":[{"internalType":"Count","name":"signatures","type":"uint256"},{"internalType":"Count","name":"prevSignatures","type":"uint256"}],"name":"PoolSignaturesLessThanPreviousPoolSignatures","type":"error"},{"inputs":[{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"uint256","name":"nextThreshold","type":"uint256"}],"name":"PoolThresholdGreaterThanNextPoolThreshold","type":"error"},{"inputs":[{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"uint256","name":"prevLimit","type":"uint256"}],"name":"PoolThresholdLessThanPreviousPoolLimit","type":"error"},{"inputs":[{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"uint256","name":"prevThreshold","type":"uint256"}],"name":"PoolThresholdLessThanPreviousPoolThreshold","type":"error"},{"inputs":[{"internalType":"uint8","name":"chainReserveFeedDecimals","type":"uint8"},{"internalType":"uint8","name":"paramsDecimals","type":"uint8"}],"name":"ProofOfReserveFeedDecimalsDoNotMatch","type":"error"},{"inputs":[],"name":"ProofOfReserveFeedIsAddressZero","type":"error"},{"inputs":[{"internalType":"int256","name":"signedReserves","type":"int256"}],"name":"ProofOfReserveFeedSignedReservesLessThanOrEqualToZero","type":"error"},{"inputs":[{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint256","name":"blockTimestamp","type":"uint256"}],"name":"ProofOfReserveFeedUpdatedAfterBlockTimestamp","type":"error"},{"inputs":[{"internalType":"uint256","name":"updatedAtPlusHeartbeat","type":"uint256"},{"internalType":"uint256","name":"blockTimestamp","type":"uint256"}],"name":"ProofOfReserveFeedUpdatedBeforeHeartbeat","type":"error"},{"inputs":[],"name":"ProofOfReserveHeartbeatIsZero","type":"error"},{"inputs":[{"internalType":"uint256","name":"totalSupplyAfterMint","type":"uint256"},{"internalType":"uint256","name":"reserves","type":"uint256"}],"name":"ProofOfReserveTotalSupplyAfterMintWouldExceedReserves","type":"error"},{"inputs":[{"internalType":"Count","name":"ratifierApprovals","type":"uint256"},{"internalType":"Count","name":"requiredApprovals","type":"uint256"}],"name":"RatifierApprovalsLessThanRequiredApprovals","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"min","type":"uint256"}],"name":"RedemptionAmountLessThanMin","type":"error"},{"inputs":[{"internalType":"Count","name":"approvals","type":"uint256"},{"internalType":"Count","name":"signatures","type":"uint256"}],"name":"RefillApprovalsLessThanOtherPoolSignatures","type":"error"},{"inputs":[],"name":"RefillPoolFromItself","type":"error"},{"inputs":[{"internalType":"Count","name":"signatures","type":"uint256"},{"internalType":"Count","name":"maxCount","type":"uint256"}],"name":"SignaturesGreaterThanMaxCount","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"mintPoolThreshold","type":"uint256"}],"name":"SpendAmountGreaterThanMintPoolThreshold","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"mintPoolValue","type":"uint256"}],"name":"SpendAmountGreaterThanMintPoolValue","type":"error"},{"inputs":[{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"ThresholdExceedsLimit","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"PoolIndex","name":"poolIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"approver","type":"address"}],"name":"ApproveRefillMintPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[],"name":"DisableProofOfReserve","type":"event"},{"anonymous":false,"inputs":[],"name":"EnableProofOfReserve","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"OpIndex","name":"opIndex","type":"uint256"},{"indexed":false,"internalType":"PoolIndex","name":"poolIndex","type":"uint256"}],"name":"FinalizeMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"PoolIndex","name":"poolIndex","type":"uint256"}],"name":"FinalizeRefillMintPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"PoolIndex","name":"poolIndex","type":"uint256"}],"name":"PopMintPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"PoolIndex","name":"poolIndex","type":"uint256"},{"indexed":false,"internalType":"Count","name":"signatures","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"threshold","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"limit","type":"uint256"}],"name":"PushMintPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"OpIndex","name":"opIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"ratifier","type":"address"}],"name":"RatifyMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReclaimEther","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IERC20Upgradeable","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReclaimToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"redemptionAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"OpIndex","name":"opIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"address","name":"requester","type":"address"}],"name":"RequestMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"OpIndex","name":"opIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"revoker","type":"address"}],"name":"RevokeMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"PoolIndex","name":"poolIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"limit","type":"uint256"}],"name":"SetMintLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"PoolIndex","name":"poolIndex","type":"uint256"},{"indexed":false,"internalType":"Count","name":"signatures","type":"uint256"}],"name":"SetMintSignatures","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"PoolIndex","name":"poolIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"threshold","type":"uint256"}],"name":"SetMintThreshold","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract AggregatorV3Interface","name":"feed","type":"address"}],"name":"SetProofOfReserveFeed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"heartbeat","type":"uint256"}],"name":"SetProofOfReserveHeartbeat","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"min","type":"uint256"}],"name":"SetRedemptionMin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"CENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FROZEN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_REDEMPTION_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_RATIFIER_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":"REDEMPTION_ADDRESS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REDEMPTION_ADMIN_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":"PoolIndex","name":"poolIndex","type":"uint256"}],"name":"approveRefillMintPoolFromNextPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"PoolIndex","name":"poolIndex","type":"uint256"}],"name":"approveThenFinalizeRefillMintPoolFromNextPool","outputs":[],"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":"burn","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":[],"name":"disableProofOfReserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableProofOfReserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"OpIndex","name":"opIndex","type":"uint256"},{"internalType":"PoolIndex","name":"poolIndex","type":"uint256"}],"name":"finalizeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"PoolIndex","name":"poolIndex","type":"uint256"}],"name":"finalizeRefillMintPoolFromNextPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"}],"name":"initialize","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":[],"name":"popMintPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"Count","name":"signatures","type":"uint256"},{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"pushMintPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"OpIndex","name":"opIndex","type":"uint256"}],"name":"ratifyMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"OpIndex","name":"opIndex","type":"uint256"},{"internalType":"PoolIndex","name":"poolIndex","type":"uint256"}],"name":"ratifyThenFinalizeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reclaimEther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Upgradeable","name":"token","type":"address"}],"name":"reclaimToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"refillLastMintPoolFromAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"requestMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"PoolIndex","name":"poolIndex","type":"uint256"}],"name":"requestThenFinalizeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"OpIndex","name":"opIndex","type":"uint256"}],"name":"revokeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"PoolIndex","name":"poolIndex","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"setMintLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"PoolIndex","name":"poolIndex","type":"uint256"},{"internalType":"Count","name":"signatures","type":"uint256"}],"name":"setMintSignatures","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"PoolIndex","name":"poolIndex","type":"uint256"},{"internalType":"uint256","name":"threshold","type":"uint256"}],"name":"setMintThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract AggregatorV3Interface","name":"feed","type":"address"}],"name":"setProofOfReserveFeed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"heartbeat","type":"uint256"}],"name":"setProofOfReserveHeartbeat","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"min","type":"uint256"}],"name":"setRedemptionMin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"viewMinimumRedemptionAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"OpIndex","name":"opIndex","type":"uint256"}],"name":"viewMintOperation","outputs":[{"internalType":"enum MintOperations.Status","name":"","type":"uint8"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"Count","name":"","type":"uint256"},{"internalType":"Count","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"viewMintOperationsCount","outputs":[{"internalType":"OpIndex","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"PoolIndex","name":"poolIndex","type":"uint256"}],"name":"viewMintPool","outputs":[{"internalType":"Count","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"Count","name":"","type":"uint256"},{"internalType":"Count","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"viewMintPoolsCount","outputs":[{"internalType":"PoolIndex","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"viewProofOfReserve","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"contract AggregatorV3Interface","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"OpIndex","name":"opIndex","type":"uint256"},{"internalType":"Count","name":"ratifierApprovalIndex","type":"uint256"}],"name":"viewUnfilteredMintOperationRatifierApproval","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"PoolIndex","name":"poolIndex","type":"uint256"},{"internalType":"Count","name":"refillApprovalIndex","type":"uint256"}],"name":"viewUnfilteredMintPoolRefillApproval","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e7565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e5576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051615f286200011f6000396000818161134a015281816113e0015281816118aa015281816119400152611a6b0152615f286000f3fe6080604052600436106103f95760003560e01c806367933be11161020d5780639dc29fac11610128578063c647c572116100bb578063d53913931161008a578063da7ab3331161006f578063da7ab33314610c6f578063dd62ed3e14610cc3578063e63ab1e914610d1757600080fd5b8063d539139314610c1b578063d547741f14610c4f57600080fd5b8063c647c57214610bb1578063c94a65dd14610bc6578063ca15c87314610be6578063cb4136c714610c0657600080fd5b8063a457c2d7116100f7578063a457c2d714610b20578063a6bcc5ba14610b40578063a9059cbb14610b60578063af76cd7614610b8057600080fd5b80639dc29fac14610aa25780639e0b531514610ac25780639f727c2714610af6578063a217fddf14610b0b57600080fd5b80638475a604116101a057806391d148541161016f57806391d14854146109fa5780639276809a14610a4d57806395d89b4114610a6d578063994c257b14610a8257600080fd5b80638475a6041461096657806388e8dd751461099a5780638cc2c08e146109ba5780639010d07c146109da57600080fd5b80637739820f116101dc5780637739820f146109055780637ef7ce921461091a57806383b952681461093a5780638456cb591461095157600080fd5b806367933be11461086c5780636a7435191461088c5780636fad40d5146108a157806370a08231146108c157600080fd5b80633659cfe61161031857806346865c5a116102ab57806358edd3951161027a5780635bdfaf8b1161025f5780635bdfaf8b146108135780635c975abb1461083357806364b3e5d51461084c57600080fd5b806358edd395146107bf5780635add18af146107df57600080fd5b806346865c5a1461075c5780634cd88b76146107775780634f1ef2861461079757806352d1902d146107aa57600080fd5b80633d53c8c7116102e75780633d53c8c7146106fd5780633f4ba83a1461071257806341e92edc1461072757806345075f4e1461073c57600080fd5b80633659cfe61461066a5780633885a0d71461068a57806339509351146106aa5780633b1f9de4146106ca57600080fd5b8063200615bf116103905780632f2ff15d1161035f5780632f2ff15d146105ee578063313ce5671461060e57806331a02bce1461062a57806336568abe1461064a57600080fd5b8063200615bf1461053157806323b872dd1461057e57806323fdc5911461059e578063248a9ca3146105be57600080fd5b806317ffc320116103cc57806317ffc320146104ba57806318160ddd146104dc578063195ee2a0146104fc5780631ac3eb9c1461051157600080fd5b806301ffc9a7146103fe57806306fdde0314610433578063095ea7b31461045557806315d90e7314610475575b600080fd5b34801561040a57600080fd5b5061041e6104193660046153fc565b610d4b565b60405190151581526020015b60405180910390f35b34801561043f57600080fd5b50610448610da7565b60405161042a9190615462565b34801561046157600080fd5b5061041e6104703660046154d5565b610e3a565b34801561048157600080fd5b50610495610490366004615501565b610e52565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161042a565b3480156104c657600080fd5b506104da6104d5366004615523565b610e71565b005b3480156104e857600080fd5b50610161545b60405190815260200161042a565b34801561050857600080fd5b506104da610f76565b34801561051d57600080fd5b506104da61052c366004615501565b610fcc565b34801561053d57600080fd5b5061055161054c366004615540565b610fe3565b604080519687526020870195909552938501929092526060840152608083015260a082015260c00161042a565b34801561058a57600080fd5b5061041e610599366004615559565b61103d565b3480156105aa57600080fd5b506104da6105b9366004615540565b611061565b3480156105ca57600080fd5b506104ee6105d9366004615540565b60009081526065602052604090206001015490565b3480156105fa57600080fd5b506104da61060936600461559a565b6110de565b34801561061a57600080fd5b506040516012815260200161042a565b34801561063657600080fd5b506104da6106453660046154d5565b611108565b34801561065657600080fd5b506104da61066536600461559a565b61129e565b34801561067657600080fd5b506104da610685366004615523565b611333565b34801561069657600080fd5b506104da6106a5366004615540565b611504565b3480156106b657600080fd5b5061041e6106c53660046154d5565b61154b565b3480156106d657600080fd5b506104ee7efc2d686fa04c73d9010c440266d7edf4fc9634ba060d3fcce2280634f9998e81565b34801561070957600080fd5b506104ee611598565b34801561071e57600080fd5b506104da6115a9565b34801561073357600080fd5b506104da6115bc565b34801561074857600080fd5b506104da6107573660046155ca565b61161f565b34801561076857600080fd5b506104ee662386f26fc1000081565b34801561078357600080fd5b506104da6107923660046156e2565b611647565b6104da6107a5366004615746565b611893565b3480156107b657600080fd5b506104ee611a51565b3480156107cb57600080fd5b506104da6107da366004615501565b611b23565b3480156107eb57600080fd5b506104ee7fd0aeb7b93be3b51a84ef63e0abb79b32e3ca9c5200c315110bf8808662f5151b81565b34801561081f57600080fd5b506104da61082e366004615540565b611bf1565b34801561083f57600080fd5b5061012d5460ff1661041e565b34801561085857600080fd5b506104da610867366004615523565b611c66565b34801561087857600080fd5b506104da610887366004615540565b611cc3565b34801561089857600080fd5b506104da611cd5565b3480156108ad57600080fd5b506104da6108bc366004615501565b611d7a565b3480156108cd57600080fd5b506104ee6108dc366004615523565b73ffffffffffffffffffffffffffffffffffffffff16600090815261015f602052604090205490565b34801561091157600080fd5b506104ee611dc8565b34801561092657600080fd5b506104da610935366004615540565b611dd4565b34801561094657600080fd5b506104956210000081565b34801561095d57600080fd5b506104da611e47565b34801561097257600080fd5b506104ee7f692fe418ed64ac7ff16f79ea7dade91c969e167ccb96f56f1a4cc50061b6005c81565b3480156109a657600080fd5b506104da6109b5366004615501565b611e79565b3480156109c657600080fd5b506104956109d5366004615501565b611ec7565b3480156109e657600080fd5b506104956109f5366004615501565b611edf565b348015610a0657600080fd5b5061041e610a1536600461559a565b600091825260656020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b348015610a5957600080fd5b506104da610a683660046157a0565b611ef7565b348015610a7957600080fd5b50610448611f8f565b348015610a8e57600080fd5b506104da610a9d366004615540565b611f9f565b348015610aae57600080fd5b506104da610abd3660046154d5565b611ffd565b348015610ace57600080fd5b506104ee7f7cd6f1a239a00c62e8815cb6a9b8149b13733d4f681b2e2ebeceddf933a69bcf81565b348015610b0257600080fd5b506104da6120a9565b348015610b1757600080fd5b506104ee600081565b348015610b2c57600080fd5b5061041e610b3b3660046154d5565b61211a565b348015610b4c57600080fd5b506104da610b5b366004615501565b6121d2565b348015610b6c57600080fd5b5061041e610b7b3660046154d5565b612220565b348015610b8c57600080fd5b50610ba0610b9b366004615540565b61222e565b60405161042a959493929190615836565b348015610bbd57600080fd5b506104ee61229b565b348015610bd257600080fd5b506104da610be1366004615540565b6122a7565b348015610bf257600080fd5b506104ee610c01366004615540565b6122ed565b348015610c1257600080fd5b506104da612304565b348015610c2757600080fd5b506104ee7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b348015610c5b57600080fd5b506104da610c6a36600461559a565b612367565b348015610c7b57600080fd5b50610c8461238c565b60408051941515855260ff909316602085015273ffffffffffffffffffffffffffffffffffffffff90911691830191909152606082015260800161042a565b348015610ccf57600080fd5b506104ee610cde36600461587c565b73ffffffffffffffffffffffffffffffffffffffff91821660009081526101606020908152604080832093909416825291909152205490565b348015610d2357600080fd5b506104ee7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f5a05180f000000000000000000000000000000000000000000000000000000001480610da15750610da1826123f0565b92915050565b60606101628054610db7906158aa565b80601f0160208091040260200160405190810160405280929190818152602001828054610de3906158aa565b8015610e305780601f10610e0557610100808354040283529160200191610e30565b820191906000526020600020905b815481529060010190602001808311610e1357829003601f168201915b5050505050905090565b600033610e48818585612487565b5060019392505050565b6000610e6a82610e6461019286612607565b90612634565b9392505050565b6000610e7c81612643565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610ee9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0d91906158fd565b9050610f1a83338361264d565b6040805173ffffffffffffffffffffffffffffffffffffffff851681523360208201529081018290527fc016730911d66378b481a7db6a27b66ee03f202be57a4ba7f7a839b6f2f45f3b906060015b60405180910390a1505050565b6000610f8181612643565b610f8c6101926126da565b7f1b004ac9d472f664ff777258f04f174a7570edfa370992949106da80e4b1676e610fb76101925490565b6040519081526020015b60405180910390a150565b610fd582611bf1565b610fdf8282611b23565b5050565b6000808080808080610ff761019289612607565b9050611001815490565b60018201546002830154600384015461101c8561278e6127db565b611028866127ea6127db565b949d939c50919a509850965090945092505050565b60003361104b8582856127f0565b6110568585856128a8565b506001949350505050565b7fd0aeb7b93be3b51a84ef63e0abb79b32e3ca9c5200c315110bf8808662f5151b61108b81612643565b6110a13361109b61019285612607565b90612ae3565b604080518381523360208201527f600574a7b9be83162c89cebf12e8deb5c80a4121ec49f68ccd53d9de62add9b891015b60405180910390a15050565b6000828152606560205260409020600101546110f981612643565b6111038383612af0565b505050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661113281612643565b6210000073ffffffffffffffffffffffffffffffffffffffff8416116111a1576040517f4f60823e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024015b60405180910390fd5b6111b2662386f26fc1000083615916565b156111ec576040517fb3eb388200000000000000000000000000000000000000000000000000000000815260048101839052602401611198565b60006111f86101915490565b610191805460018101825560009190915290915061123c906004027ffb4a0ff48df6de8777afc824e4cbf267beb8602db7c5a7456c954593226c1fd5018585612b12565b6040805182815273ffffffffffffffffffffffffffffffffffffffff861660208201529081018490523360608201527ff6ca74d9e3652a13a33695a264ac70cb0be02e0fb69151b1f116ab2b7dec14309060800160405180910390a150505050565b73ffffffffffffffffffffffffffffffffffffffff811633146113295760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401611198565b610fdf8282612c7f565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001630036113de5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152608401611198565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166114537f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16146114dc5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152608401611198565b6114e581612ca1565b6040805160008082526020820190925261150191839190612cac565b50565b600061150f81612643565b61151b61019383612e77565b6040518281527f44b8da35fe9864ef485c963703bc19d7c09d7a43d0cd7fd617c534a3f7ecb632906020016110d2565b3360008181526101606020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909190610e489082908690611593908790615980565b612487565b60006115a46101915490565b905090565b60006115b481612643565b611501612e92565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6115e681612643565b6115f36101936000612f10565b6040517fc4bb11a07d256b7a620fa9e8a22b3bf983c882812189246f3d86f0e4facbfbbf90600090a150565b600061162b6101915490565b90506116378484611108565b6116418183611b23565b50505050565b600054610100900460ff16158080156116675750600054600160ff909116105b806116815750303b158015611681575060005460ff166001145b6116f35760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611198565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561175157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b611759612fd3565b6117638383613052565b61176b612fd3565b6117736130d9565b61177e600033612af0565b6117c77efc2d686fa04c73d9010c440266d7edf4fc9634ba060d3fcce2280634f9998e7f7cd6f1a239a00c62e8815cb6a9b8149b13733d4f681b2e2ebeceddf933a69bcf61315e565b61019380547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16751200000000000000000000000000000000000000000017905561181460026012615993565b61181f90600a615acc565b662386f26fc100001461183457611834615adb565b801561110357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602001610f69565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016300361193e5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152608401611198565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166119b37f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1614611a3c5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152608401611198565b611a4582612ca1565b610fdf82826001612cac565b60003073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611afe5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401611198565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b6000611b31610191846131a9565b90506000611b4161019284612607565b90506000611b50836001015490565b9050611b6a81611b606101615490565b61019391906131d6565b611b7f611b75835490565b849061278e613596565b611b898282613683565b8254611bb090610100900473ffffffffffffffffffffffffffffffffffffffff1682613754565b60408051868152602081018690527f9e99bd6d4d1403b864d1e59fe417505ed9ad57300a7c62cd38436ab0857a56f991015b60405180910390a15050505050565b7fd0aeb7b93be3b51a84ef63e0abb79b32e3ca9c5200c315110bf8808662f5151b611c1b81612643565b611c3133611c2b610191856131a9565b90613845565b604080518381523360208201527fd73a150d677a06417ad5492867423fbeea1d4725d948735d751f4eb2f007361391016110d2565b6000611c7181612643565b611c7d610193836138ab565b60405173ffffffffffffffffffffffffffffffffffffffff831681527f200cfa7a0a16b05b66a5b25811b7460eada8b17a5781e3fd60450f1a844a1bf8906020016110d2565b611ccc81611061565b61150181611f9f565b6000611ce081612643565b6000611cf4611cef6101925490565b613901565b9050611d12611d0561019283612607565b6002810154600390910155565b604080518281523360208201527f600574a7b9be83162c89cebf12e8deb5c80a4121ec49f68ccd53d9de62add9b8910160405180910390a16040518181527f029ef4ddd14f777ffc2dc3e6b7193bc9fa2ff68a603ef378893d5fd60f589e21906020016110d2565b6000611d8581612643565b611d92610192848461390e565b60408051848152602081018490527fbec9fa51a19118a74ef477f3ec3be93e6d3d286d642e803907752aa8f48fd1719101610f69565b60006115a46101c55490565b7fd0aeb7b93be3b51a84ef63e0abb79b32e3ca9c5200c315110bf8808662f5151b611dfe81612643565b611e12611e0d610191846131a9565b613a9b565b604080518381523360208201527fae20b7107fac37bd8a6bd1699b45de51875917b048b8277994540c405bcceb5f91016110d2565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a611e7181612643565b611501613b21565b6000611e8481612643565b611e916101928484613b7d565b60408051848152602081018490527f55e125071c1ed92017657913f05c436509606565df0eadb787d078f53e350d2a9101610f69565b6000610e6a82611ed9610191866131a9565b90613c83565b6000828152609760205260408120610e6a9083613c92565b6000611f0281612643565b6000611f0e6101925490565b9050611f1b610192613c9e565b611f286101928287613b7d565b611f356101928286613d14565b611f42610192828561390e565b611f4a611cd5565b6040805182815260208101879052908101859052606081018490527f864ac6374d57584a6126b3250d1715c7e265cae3116cca3b97aae45dff8b8ac790608001611be2565b60606101638054610db7906158aa565b611fcd611fb7611fae83613e75565b61019290612607565b61278e611fc661019285612607565b9190613e82565b6040518181527f029ef4ddd14f777ffc2dc3e6b7193bc9fa2ff68a603ef378893d5fd60f589e2190602001610fc1565b600061200881612643565b612019662386f26fc1000083615916565b15612053576040517fb3eb388200000000000000000000000000000000000000000000000000000000815260048101839052602401611198565b61205d8383613f96565b6040805173ffffffffffffffffffffffffffffffffffffffff85168152602081018490527fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca59101610f69565b60006120b481612643565b6040514790339082156108fc029083906000818181858888f193505050501580156120e3573d6000803e3d6000fd5b5060408051338152602081018390527fb54913b2b58b2e96ea9b4e96ba2353cf13426af9d3f252e0c17899a93c4ce12591016110d2565b3360008181526101606020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909190838110156121c55760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401611198565b6110568286868403612487565b60006121dd81612643565b6121ea6101928484613d14565b60408051848152602081018490527f2758a36d588bf0eac3a7bc34b5bda0b05b1bdba15ab93e782f30f0c8807ae1d39101610f69565b600033610e488185856128a8565b60008080808080612241610191886131a9565b905061224e815460ff1690565b8154610100900473ffffffffffffffffffffffffffffffffffffffff16600183015461227c8461278e61413e565b612288856127ea61413e565b939b929a50909850965090945092505050565b60006115a46101925490565b60006122b281612643565b6122bd6101c5839055565b6040518281527f45afadbf69edc89bc6b1decea51aa7bd5fb5db0aecee33854dc7a683140e07d7906020016110d2565b6000818152609760205260408120610da190614151565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a61232e81612643565b61233b6101936001612f10565b6040517f0bcc813f2e83d9562e28e666ff81377a4b6951c9d66b1cf5ae43f3f809775a2790600090a150565b60008281526065602052604090206001015461238281612643565b6111038383612c7f565b60008060008061239f6101935460ff1690565b610193547501000000000000000000000000000000000000000000900460ff1661019354610100900473ffffffffffffffffffffffffffffffffffffffff1661019454935093509350935090919293565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610da157507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610da1565b73ffffffffffffffffffffffffffffffffffffffff831661250f5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401611198565b73ffffffffffffffffffffffffffffffffffffffff82166125985760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401611198565b73ffffffffffffffffffffffffffffffffffffffff8381166000818152610160602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b600082600001828154811061261e5761261e615b0a565b9060005260206000209060060201905092915050565b6000610e6a600484018361415b565b6115018133614167565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611103908490614207565b80546127119082906126ee90600190615b39565b815481106126fe576126fe615b0a565b90600052602060002090600602016142fc565b805481908061272257612722615b4c565b60008281526020812060067fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909301928302018181556001810182905560028101829055600381018290559060048201818181818161278182826153ca565b5050505050505050905550565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f887de0ec048f3aee6a161c3b9047f946719bdfa5e0d00244ac1983fe500e57b8602052604081205460ff16610da1565b6000610e6a6004840183614308565b50600190565b73ffffffffffffffffffffffffffffffffffffffff838116600090815261016060209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611641578181101561289b5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401611198565b6116418484848403612487565b73ffffffffffffffffffffffffffffffffffffffff83166129315760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401611198565b73ffffffffffffffffffffffffffffffffffffffff82166129ba5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401611198565b6129c583838361437d565b73ffffffffffffffffffffffffffffffffffffffff8316600090815261015f602052604090205481811015612a625760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401611198565b73ffffffffffffffffffffffffffffffffffffffff808516600081815261015f602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90612ad09086815260200190565b60405180910390a36116418484846144ef565b610fdf6004830182614608565b612afa82826146aa565b6000828152609760205260409020611103908261479e565b82600080825460ff166003811115612b2c57612b2c6157cc565b14612b6b5781546040517fc3f69e640000000000000000000000000000000000000000000000000000000081526111989160ff16908390600401615b7b565b8454610100900473ffffffffffffffffffffffffffffffffffffffff1615612b9557612b95615adb565b600185015415612ba757612ba7615adb565b73ffffffffffffffffffffffffffffffffffffffff8416612bf4576040517f24debe8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003612c2e576040517f18e236f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50508254600173ffffffffffffffffffffffffffffffffffffffff93909316610100027fffffffffffffffffffffff0000000000000000000000000000000000000000009091161782178355910155565b612c8982826147c0565b6000828152609760205260409020611103908261487b565b6000610fdf81612643565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612cdf576111038361489d565b8273ffffffffffffffffffffffffffffffffffffffff166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612d64575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252612d61918101906158fd565b60015b612dd65760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f7420555550530000000000000000000000000000000000006064820152608401611198565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8114612e6b5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c655555494400000000000000000000000000000000000000000000006064820152608401611198565b5061110383838361498d565b600182018190556000819003610fdf57610fdf826000612f10565b612e9a6149b2565b61012d80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b8015612fa7578154610100900473ffffffffffffffffffffffffffffffffffffffff16612f69576040517fbebe015b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160010154600003612fa7576040517fe66e3ac500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016901515179055565b600054610100900460ff166130505760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611198565b565b600054610100900460ff166130cf5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611198565b610fdf8282614a05565b600054610100900460ff166131565760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611198565b613050614a9d565b600082815260656020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b60008260000182815481106131c0576131c0615b0a565b9060005260206000209060040201905092915050565b825460ff166131e457505050565b8254610100900473ffffffffffffffffffffffffffffffffffffffff1661320d5761320d615adb565b8254604080517f313ce56700000000000000000000000000000000000000000000000000000000815290517501000000000000000000000000000000000000000000830460ff1692610100900473ffffffffffffffffffffffffffffffffffffffff169163313ce5679160048083019260209291908290030181865afa15801561329b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132bf9190615b96565b60ff16146133b6578260000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613336573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061335a9190615b96565b83546040517f2f25b3c800000000000000000000000000000000000000000000000000000000815260ff928316600482015275010000000000000000000000000000000000000000009091049091166024820152604401611198565b6000808460000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613428573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061344c9190615bd8565b5093505092505060008213613490576040517f62cf7c3d00000000000000000000000000000000000000000000000000000000815260048101839052602401611198565b81428211156134d4576040517f72a8b06500000000000000000000000000000000000000000000000000000000815260048101839052426024820152604401611198565b428660010154836134e59190615980565b10156135365760018601546134fa9083615980565b6040517f21339e450000000000000000000000000000000000000000000000000000000081526004810191909152426024820152604401611198565b806135418686615980565b111561358e576135518585615980565b6040517fca546cd8000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401611198565b505050505050565b82600180825460ff1660038111156135b0576135b06157cc565b146135ef5781546040517fc3f69e640000000000000000000000000000000000000000000000000000000081526111989160ff16908390600401615b7b565b6136046135ff6002870185614308565b851190565b15613653576136166002860184614308565b6040517fb0ed4a80000000000000000000000000000000000000000000000000000000008152600481019190915260248101859052604401611198565b505082547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166002179092555050565b81600201548260030154111561369b5761369b615adb565b81600101548111156136e95760018201546040517f1e5375dc000000000000000000000000000000000000000000000000000000008152611198918391600401918252602082015260400190565b81600301548111156137375760038201546040517f4d70d8d2000000000000000000000000000000000000000000000000000000008152611198918391600401918252602082015260400190565b8082600301600082825461374b9190615b39565b90915550505050565b73ffffffffffffffffffffffffffffffffffffffff82166137b75760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401611198565b6137c36000838361437d565b8061016160008282546137d69190615980565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815261015f60209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610fdf600083836144ef565b81600180825460ff16600381111561385f5761385f6157cc565b1461389e5781546040517fc3f69e640000000000000000000000000000000000000000000000000000000081526111989160ff16908390600401615b7b565b6116416002850184614608565b81547fffffffffffffffffffffff0000000000000000000000000000000000000000ff1661010073ffffffffffffffffffffffffffffffffffffffff8316908102919091178355610fdf57610fdf826000612f10565b6000610da1600183615b39565b8115158015613938575061393561392e61392784613901565b8590612607565b6002015490565b81105b1561398f578061395461392e61394d85613901565b8690612607565b6040517f4dbdd58600000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b6139a261399b83613e75565b84545b1190565b80156139bb57506139b861392e61392784613e75565b81115b15613a0b57806139d061392e61394d85613e75565b6040517f4b033f0600000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b613a1761399b83613e75565b8015613a375750613a34613a2d61392784613e75565b6001015490565b81115b15613a875780613a4c613a2d61394d85613e75565b6040517f3b9a7f9e00000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b61110381613a958585612607565b90614b45565b80600180825460ff166003811115613ab557613ab56157cc565b14613af45781546040517fc3f69e640000000000000000000000000000000000000000000000000000000081526111989160ff16908390600401615b7b565b505080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166003179055565b613b29614bb5565b61012d80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612ee63390565b8115158015613ba55750613ba58161399e613ba1613b9a86613901565b8790612607565b5490565b15613bf55780613bba613ba161394d85613901565b6040517fb9a81cd000000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b613c0161399b83613e75565b8015613c1f5750613c1f81613c1b613ba1613b9a86613e75565b1090565b15613c6f5780613c34613ba161394d85613e75565b6040517fac0f679300000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b61110381613c7d8585612607565b90614c09565b6000610e6a600284018361415b565b6000610e6a8383614c54565b8054600181018255600082815260209020600690910201613cdf817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff614b45565b613d09817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff614c7e565b610fdf816008614c09565b8115158015613d305750613d2d613a2d61392784613901565b81105b15613d805780613d45613a2d61394d85613901565b6040517f11a3a53700000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b8115158015613d9c5750613d9961392e61392784613901565b81105b15613dec5780613db161392e61394d85613901565b6040517f0ea95e9e00000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b613df861399b83613e75565b8015613e115750613e0e613a2d61392784613e75565b81115b15613e615780613e26613a2d61394d85613e75565b6040517f94459c3400000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b61110381613e6f8585612607565b90614c7e565b6000610da1826001615980565b818303613ebb576040517f39cb906e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613ed1613ecb6004850183614308565b83541190565b15613f2057613ee36004840182614308565b82546040517f0dfbd73200000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b613f2c83600401614cd9565b826002015483600301541115613f4457613f44615adb565b600083600301548460020154613f5a9190615b39565b9050613f668382613683565b80846003016000828254613f7a9190615980565b9091555050600284015460038501541461164157611641615adb565b73ffffffffffffffffffffffffffffffffffffffff821661401f5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401611198565b61402b8260008361437d565b73ffffffffffffffffffffffffffffffffffffffff8216600090815261015f6020526040902054818110156140c85760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401611198565b73ffffffffffffffffffffffffffffffffffffffff8316600081815261015f60209081526040808320868603905561016180548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3611103836000846144ef565b6000610e6a6002840183614308565b9055565b6000610da1825490565b6000610e6a8383613c92565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610fdf576141a781614d2a565b6141b2836020614d49565b6040516020016141c3929190615c28565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905262461bcd60e51b825261119891600401615462565b6000614269826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614f729092919063ffffffff16565b905080516000148061428a57508080602001905181019061428a9190615ca9565b6111035760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611198565b61150181600401614cd9565b60008061431484614151565b9050614321816008101590565b61432d5761432d615adb565b6000805b828110156143745761434f6143468783613c92565b8663ffffffff16565b15614362578161435e81615ccb565b9250505b8061436c81615ccb565b915050614331565b50949350505050565b3360009081527fffdfc1249c027f9191656349feb0761381bb32c9f557e01f419fd08754bf5a1b602052604090205460ff16156143b957505050565b6143c1614bb5565b73ffffffffffffffffffffffffffffffffffffffff831660009081527f09c52666ba87d2e41727af01aa8497c97e949bf87354a8ac7a6d0ecdc58a4bc0602052604090205460ff1615614458576040517f76a772de00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401611198565b73ffffffffffffffffffffffffffffffffffffffff821660009081527f09c52666ba87d2e41727af01aa8497c97e949bf87354a8ac7a6d0ecdc58a4bc0602052604090205460ff1615611103576040517f76a772de00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401611198565b73ffffffffffffffffffffffffffffffffffffffff82161580159061452d57506210000073ffffffffffffffffffffffffffffffffffffffff831611155b156111035761455b7efc2d686fa04c73d9010c440266d7edf4fc9634ba060d3fcce2280634f9998e83614167565b61456c662386f26fc1000082615916565b156145a6576040517fb3eb388200000000000000000000000000000000000000000000000000000000815260048101829052602401611198565b6145b26101c582614f89565b6145bc8282613f96565b6040805173ffffffffffffffffffffffffffffffffffffffff84168152602081018390527f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a69101610f69565b61461b61461483614151565b6008111590565b15614652576040517f04290ffa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61465c828261479e565b610fdf576040517fab7c05b700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401611198565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610fdf57600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556147403390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610e6a8373ffffffffffffffffffffffffffffffffffffffff8416614fd1565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1615610fdf57600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610e6a8373ffffffffffffffffffffffffffffffffffffffff8416615020565b73ffffffffffffffffffffffffffffffffffffffff81163b6149275760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152608401611198565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61499683615113565b6000825111806149a35750805b15611103576116418383615160565b61012d5460ff166130505760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401611198565b600054610100900460ff16614a825760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611198565b610162614a8f8382615d49565b506101636111038282615d49565b600054610100900460ff16614b1a5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611198565b61012d80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6001820154811015614b935760018201546040517f6e9ee463000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401611198565b600282018190556003820154614ba99082615185565b82600301819055505050565b61012d5460ff16156130505760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401611198565b614c138160081090565b1561414d576040517f446867d80000000000000000000000000000000000000000000000000000000081526004810182905260086024820152604401611198565b6000826000018281548110614c6b57614c6b615b0a565b9060005260206000200154905092915050565b6002820154811115614cd15780614c96836002015490565b6040517f6e9ee46300000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b600190910155565b6000614ce482614151565b90505b8015610fdf57614d0c614d05614cfe600184615b39565b8490613c92565b839061487b565b614d1857614d18615adb565b80614d2281615e63565b915050614ce7565b6060610da173ffffffffffffffffffffffffffffffffffffffff831660145b60606000614d58836002615e98565b614d63906002615980565b67ffffffffffffffff811115614d7b57614d7b6155ff565b6040519080825280601f01601f191660200182016040528015614da5576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110614ddc57614ddc615b0a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110614e3f57614e3f615b0a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000614e7b846002615e98565b614e86906001615980565b90505b6001811115614f23577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110614ec757614ec7615b0a565b1a60f81b828281518110614edd57614edd615b0a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93614f1c81615e63565b9050614e89565b508315610e6a5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401611198565b6060614f81848460008561519b565b949350505050565b8154811015610fdf5781546040517fa969824c000000000000000000000000000000000000000000000000000000008152611198918391600401918252602082015260400190565b600081815260018301602052604081205461501857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610da1565b506000610da1565b60008181526001830160205260408120548015615109576000615044600183615b39565b855490915060009061505890600190615b39565b90508181146150bd57600086600001828154811061507857615078615b0a565b906000526020600020015490508087600001848154811061509b5761509b615b0a565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806150ce576150ce615b4c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610da1565b6000915050610da1565b61511c8161489d565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060610e6a8383604051806060016040528060278152602001615ecc6027913961529a565b60008183106151945781610e6a565b5090919050565b6060824710156152135760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611198565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161523c9190615eaf565b60006040518083038185875af1925050503d8060008114615279576040519150601f19603f3d011682016040523d82523d6000602084013e61527e565b606091505b509150915061528f8783838761531f565b979650505050505050565b60606000808573ffffffffffffffffffffffffffffffffffffffff16856040516152c49190615eaf565b600060405180830381855af49150503d80600081146152ff576040519150601f19603f3d011682016040523d82523d6000602084013e615304565b606091505b50915091506153158683838761531f565b9695505050505050565b6060831561539b5782516000036153945773ffffffffffffffffffffffffffffffffffffffff85163b6153945760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611198565b5081614f81565b614f8183838151156153b05781518083602001fd5b8060405162461bcd60e51b81526004016111989190615462565b508054600082559060005260206000209081019061150191905b808211156153f857600081556001016153e4565b5090565b60006020828403121561540e57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610e6a57600080fd5b60005b83811015615459578181015183820152602001615441565b50506000910152565b602081526000825180602084015261548181604085016020870161543e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461150157600080fd5b600080604083850312156154e857600080fd5b82356154f3816154b3565b946020939093013593505050565b6000806040838503121561551457600080fd5b50508035926020909101359150565b60006020828403121561553557600080fd5b8135610e6a816154b3565b60006020828403121561555257600080fd5b5035919050565b60008060006060848603121561556e57600080fd5b8335615579816154b3565b92506020840135615589816154b3565b929592945050506040919091013590565b600080604083850312156155ad57600080fd5b8235915060208301356155bf816154b3565b809150509250929050565b6000806000606084860312156155df57600080fd5b83356155ea816154b3565b95602085013595506040909401359392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600067ffffffffffffffff80841115615649576156496155ff565b604051601f85017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561568f5761568f6155ff565b816040528093508581528686860111156156a857600080fd5b858560208301376000602087830101525050509392505050565b600082601f8301126156d357600080fd5b610e6a8383356020850161562e565b600080604083850312156156f557600080fd5b823567ffffffffffffffff8082111561570d57600080fd5b615719868387016156c2565b9350602085013591508082111561572f57600080fd5b5061573c858286016156c2565b9150509250929050565b6000806040838503121561575957600080fd5b8235615764816154b3565b9150602083013567ffffffffffffffff81111561578057600080fd5b8301601f8101851361579157600080fd5b61573c8582356020840161562e565b6000806000606084860312156157b557600080fd5b505081359360208301359350604090920135919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110615832577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60a0810161584482886157fb565b73ffffffffffffffffffffffffffffffffffffffff861660208301528460408301528360608301528260808301529695505050505050565b6000806040838503121561588f57600080fd5b823561589a816154b3565b915060208301356155bf816154b3565b600181811c908216806158be57607f821691505b6020821081036158f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60006020828403121561590f57600080fd5b5051919050565b60008261594c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610da157610da1615951565b60ff8281168282160390811115610da157610da1615951565b600181815b80851115615a0557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156159eb576159eb615951565b808516156159f857918102915b93841c93908002906159b1565b509250929050565b600082615a1c57506001610da1565b81615a2957506000610da1565b8160018114615a3f5760028114615a4957615a65565b6001915050610da1565b60ff841115615a5a57615a5a615951565b50506001821b610da1565b5060208310610133831016604e8410600b8410161715615a88575081810a610da1565b615a9283836159ac565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615ac457615ac4615951565b029392505050565b6000610e6a60ff841683615a0d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b81810381811115610da157610da1615951565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60408101615b8982856157fb565b610e6a60208301846157fb565b600060208284031215615ba857600080fd5b815160ff81168114610e6a57600080fd5b805169ffffffffffffffffffff81168114615bd357600080fd5b919050565b600080600080600060a08688031215615bf057600080fd5b615bf986615bb9565b9450602086015193506040860151925060608601519150615c1c60808701615bb9565b90509295509295909350565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351615c6081601785016020880161543e565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351615c9d81602884016020880161543e565b01602801949350505050565b600060208284031215615cbb57600080fd5b81518015158114610e6a57600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615cfc57615cfc615951565b5060010190565b601f82111561110357600081815260208120601f850160051c81016020861015615d2a5750805b601f850160051c820191505b8181101561358e57828155600101615d36565b815167ffffffffffffffff811115615d6357615d636155ff565b615d7781615d7184546158aa565b84615d03565b602080601f831160018114615dca5760008415615d945750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561358e565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015615e1757888601518255948401946001909101908401615df8565b5085821015615e5357878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600081615e7257615e72615951565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610da157610da1615951565b60008251615ec181846020870161543e565b919091019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212203877674babd5c024ccfa7d86146e70d83be05618fdc2777994acd17b685af26f64736f6c63430008130033
Deployed Bytecode
0x6080604052600436106103f95760003560e01c806367933be11161020d5780639dc29fac11610128578063c647c572116100bb578063d53913931161008a578063da7ab3331161006f578063da7ab33314610c6f578063dd62ed3e14610cc3578063e63ab1e914610d1757600080fd5b8063d539139314610c1b578063d547741f14610c4f57600080fd5b8063c647c57214610bb1578063c94a65dd14610bc6578063ca15c87314610be6578063cb4136c714610c0657600080fd5b8063a457c2d7116100f7578063a457c2d714610b20578063a6bcc5ba14610b40578063a9059cbb14610b60578063af76cd7614610b8057600080fd5b80639dc29fac14610aa25780639e0b531514610ac25780639f727c2714610af6578063a217fddf14610b0b57600080fd5b80638475a604116101a057806391d148541161016f57806391d14854146109fa5780639276809a14610a4d57806395d89b4114610a6d578063994c257b14610a8257600080fd5b80638475a6041461096657806388e8dd751461099a5780638cc2c08e146109ba5780639010d07c146109da57600080fd5b80637739820f116101dc5780637739820f146109055780637ef7ce921461091a57806383b952681461093a5780638456cb591461095157600080fd5b806367933be11461086c5780636a7435191461088c5780636fad40d5146108a157806370a08231146108c157600080fd5b80633659cfe61161031857806346865c5a116102ab57806358edd3951161027a5780635bdfaf8b1161025f5780635bdfaf8b146108135780635c975abb1461083357806364b3e5d51461084c57600080fd5b806358edd395146107bf5780635add18af146107df57600080fd5b806346865c5a1461075c5780634cd88b76146107775780634f1ef2861461079757806352d1902d146107aa57600080fd5b80633d53c8c7116102e75780633d53c8c7146106fd5780633f4ba83a1461071257806341e92edc1461072757806345075f4e1461073c57600080fd5b80633659cfe61461066a5780633885a0d71461068a57806339509351146106aa5780633b1f9de4146106ca57600080fd5b8063200615bf116103905780632f2ff15d1161035f5780632f2ff15d146105ee578063313ce5671461060e57806331a02bce1461062a57806336568abe1461064a57600080fd5b8063200615bf1461053157806323b872dd1461057e57806323fdc5911461059e578063248a9ca3146105be57600080fd5b806317ffc320116103cc57806317ffc320146104ba57806318160ddd146104dc578063195ee2a0146104fc5780631ac3eb9c1461051157600080fd5b806301ffc9a7146103fe57806306fdde0314610433578063095ea7b31461045557806315d90e7314610475575b600080fd5b34801561040a57600080fd5b5061041e6104193660046153fc565b610d4b565b60405190151581526020015b60405180910390f35b34801561043f57600080fd5b50610448610da7565b60405161042a9190615462565b34801561046157600080fd5b5061041e6104703660046154d5565b610e3a565b34801561048157600080fd5b50610495610490366004615501565b610e52565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161042a565b3480156104c657600080fd5b506104da6104d5366004615523565b610e71565b005b3480156104e857600080fd5b50610161545b60405190815260200161042a565b34801561050857600080fd5b506104da610f76565b34801561051d57600080fd5b506104da61052c366004615501565b610fcc565b34801561053d57600080fd5b5061055161054c366004615540565b610fe3565b604080519687526020870195909552938501929092526060840152608083015260a082015260c00161042a565b34801561058a57600080fd5b5061041e610599366004615559565b61103d565b3480156105aa57600080fd5b506104da6105b9366004615540565b611061565b3480156105ca57600080fd5b506104ee6105d9366004615540565b60009081526065602052604090206001015490565b3480156105fa57600080fd5b506104da61060936600461559a565b6110de565b34801561061a57600080fd5b506040516012815260200161042a565b34801561063657600080fd5b506104da6106453660046154d5565b611108565b34801561065657600080fd5b506104da61066536600461559a565b61129e565b34801561067657600080fd5b506104da610685366004615523565b611333565b34801561069657600080fd5b506104da6106a5366004615540565b611504565b3480156106b657600080fd5b5061041e6106c53660046154d5565b61154b565b3480156106d657600080fd5b506104ee7efc2d686fa04c73d9010c440266d7edf4fc9634ba060d3fcce2280634f9998e81565b34801561070957600080fd5b506104ee611598565b34801561071e57600080fd5b506104da6115a9565b34801561073357600080fd5b506104da6115bc565b34801561074857600080fd5b506104da6107573660046155ca565b61161f565b34801561076857600080fd5b506104ee662386f26fc1000081565b34801561078357600080fd5b506104da6107923660046156e2565b611647565b6104da6107a5366004615746565b611893565b3480156107b657600080fd5b506104ee611a51565b3480156107cb57600080fd5b506104da6107da366004615501565b611b23565b3480156107eb57600080fd5b506104ee7fd0aeb7b93be3b51a84ef63e0abb79b32e3ca9c5200c315110bf8808662f5151b81565b34801561081f57600080fd5b506104da61082e366004615540565b611bf1565b34801561083f57600080fd5b5061012d5460ff1661041e565b34801561085857600080fd5b506104da610867366004615523565b611c66565b34801561087857600080fd5b506104da610887366004615540565b611cc3565b34801561089857600080fd5b506104da611cd5565b3480156108ad57600080fd5b506104da6108bc366004615501565b611d7a565b3480156108cd57600080fd5b506104ee6108dc366004615523565b73ffffffffffffffffffffffffffffffffffffffff16600090815261015f602052604090205490565b34801561091157600080fd5b506104ee611dc8565b34801561092657600080fd5b506104da610935366004615540565b611dd4565b34801561094657600080fd5b506104956210000081565b34801561095d57600080fd5b506104da611e47565b34801561097257600080fd5b506104ee7f692fe418ed64ac7ff16f79ea7dade91c969e167ccb96f56f1a4cc50061b6005c81565b3480156109a657600080fd5b506104da6109b5366004615501565b611e79565b3480156109c657600080fd5b506104956109d5366004615501565b611ec7565b3480156109e657600080fd5b506104956109f5366004615501565b611edf565b348015610a0657600080fd5b5061041e610a1536600461559a565b600091825260656020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b348015610a5957600080fd5b506104da610a683660046157a0565b611ef7565b348015610a7957600080fd5b50610448611f8f565b348015610a8e57600080fd5b506104da610a9d366004615540565b611f9f565b348015610aae57600080fd5b506104da610abd3660046154d5565b611ffd565b348015610ace57600080fd5b506104ee7f7cd6f1a239a00c62e8815cb6a9b8149b13733d4f681b2e2ebeceddf933a69bcf81565b348015610b0257600080fd5b506104da6120a9565b348015610b1757600080fd5b506104ee600081565b348015610b2c57600080fd5b5061041e610b3b3660046154d5565b61211a565b348015610b4c57600080fd5b506104da610b5b366004615501565b6121d2565b348015610b6c57600080fd5b5061041e610b7b3660046154d5565b612220565b348015610b8c57600080fd5b50610ba0610b9b366004615540565b61222e565b60405161042a959493929190615836565b348015610bbd57600080fd5b506104ee61229b565b348015610bd257600080fd5b506104da610be1366004615540565b6122a7565b348015610bf257600080fd5b506104ee610c01366004615540565b6122ed565b348015610c1257600080fd5b506104da612304565b348015610c2757600080fd5b506104ee7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b348015610c5b57600080fd5b506104da610c6a36600461559a565b612367565b348015610c7b57600080fd5b50610c8461238c565b60408051941515855260ff909316602085015273ffffffffffffffffffffffffffffffffffffffff90911691830191909152606082015260800161042a565b348015610ccf57600080fd5b506104ee610cde36600461587c565b73ffffffffffffffffffffffffffffffffffffffff91821660009081526101606020908152604080832093909416825291909152205490565b348015610d2357600080fd5b506104ee7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f5a05180f000000000000000000000000000000000000000000000000000000001480610da15750610da1826123f0565b92915050565b60606101628054610db7906158aa565b80601f0160208091040260200160405190810160405280929190818152602001828054610de3906158aa565b8015610e305780601f10610e0557610100808354040283529160200191610e30565b820191906000526020600020905b815481529060010190602001808311610e1357829003601f168201915b5050505050905090565b600033610e48818585612487565b5060019392505050565b6000610e6a82610e6461019286612607565b90612634565b9392505050565b6000610e7c81612643565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610ee9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0d91906158fd565b9050610f1a83338361264d565b6040805173ffffffffffffffffffffffffffffffffffffffff851681523360208201529081018290527fc016730911d66378b481a7db6a27b66ee03f202be57a4ba7f7a839b6f2f45f3b906060015b60405180910390a1505050565b6000610f8181612643565b610f8c6101926126da565b7f1b004ac9d472f664ff777258f04f174a7570edfa370992949106da80e4b1676e610fb76101925490565b6040519081526020015b60405180910390a150565b610fd582611bf1565b610fdf8282611b23565b5050565b6000808080808080610ff761019289612607565b9050611001815490565b60018201546002830154600384015461101c8561278e6127db565b611028866127ea6127db565b949d939c50919a509850965090945092505050565b60003361104b8582856127f0565b6110568585856128a8565b506001949350505050565b7fd0aeb7b93be3b51a84ef63e0abb79b32e3ca9c5200c315110bf8808662f5151b61108b81612643565b6110a13361109b61019285612607565b90612ae3565b604080518381523360208201527f600574a7b9be83162c89cebf12e8deb5c80a4121ec49f68ccd53d9de62add9b891015b60405180910390a15050565b6000828152606560205260409020600101546110f981612643565b6111038383612af0565b505050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661113281612643565b6210000073ffffffffffffffffffffffffffffffffffffffff8416116111a1576040517f4f60823e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024015b60405180910390fd5b6111b2662386f26fc1000083615916565b156111ec576040517fb3eb388200000000000000000000000000000000000000000000000000000000815260048101839052602401611198565b60006111f86101915490565b610191805460018101825560009190915290915061123c906004027ffb4a0ff48df6de8777afc824e4cbf267beb8602db7c5a7456c954593226c1fd5018585612b12565b6040805182815273ffffffffffffffffffffffffffffffffffffffff861660208201529081018490523360608201527ff6ca74d9e3652a13a33695a264ac70cb0be02e0fb69151b1f116ab2b7dec14309060800160405180910390a150505050565b73ffffffffffffffffffffffffffffffffffffffff811633146113295760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401611198565b610fdf8282612c7f565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000002c534389284807868fdf275d4e19596285c6048c1630036113de5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152608401611198565b7f0000000000000000000000002c534389284807868fdf275d4e19596285c6048c73ffffffffffffffffffffffffffffffffffffffff166114537f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16146114dc5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152608401611198565b6114e581612ca1565b6040805160008082526020820190925261150191839190612cac565b50565b600061150f81612643565b61151b61019383612e77565b6040518281527f44b8da35fe9864ef485c963703bc19d7c09d7a43d0cd7fd617c534a3f7ecb632906020016110d2565b3360008181526101606020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909190610e489082908690611593908790615980565b612487565b60006115a46101915490565b905090565b60006115b481612643565b611501612e92565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6115e681612643565b6115f36101936000612f10565b6040517fc4bb11a07d256b7a620fa9e8a22b3bf983c882812189246f3d86f0e4facbfbbf90600090a150565b600061162b6101915490565b90506116378484611108565b6116418183611b23565b50505050565b600054610100900460ff16158080156116675750600054600160ff909116105b806116815750303b158015611681575060005460ff166001145b6116f35760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611198565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561175157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b611759612fd3565b6117638383613052565b61176b612fd3565b6117736130d9565b61177e600033612af0565b6117c77efc2d686fa04c73d9010c440266d7edf4fc9634ba060d3fcce2280634f9998e7f7cd6f1a239a00c62e8815cb6a9b8149b13733d4f681b2e2ebeceddf933a69bcf61315e565b61019380547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16751200000000000000000000000000000000000000000017905561181460026012615993565b61181f90600a615acc565b662386f26fc100001461183457611834615adb565b801561110357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602001610f69565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000002c534389284807868fdf275d4e19596285c6048c16300361193e5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152608401611198565b7f0000000000000000000000002c534389284807868fdf275d4e19596285c6048c73ffffffffffffffffffffffffffffffffffffffff166119b37f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1614611a3c5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152608401611198565b611a4582612ca1565b610fdf82826001612cac565b60003073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000002c534389284807868fdf275d4e19596285c6048c1614611afe5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401611198565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b6000611b31610191846131a9565b90506000611b4161019284612607565b90506000611b50836001015490565b9050611b6a81611b606101615490565b61019391906131d6565b611b7f611b75835490565b849061278e613596565b611b898282613683565b8254611bb090610100900473ffffffffffffffffffffffffffffffffffffffff1682613754565b60408051868152602081018690527f9e99bd6d4d1403b864d1e59fe417505ed9ad57300a7c62cd38436ab0857a56f991015b60405180910390a15050505050565b7fd0aeb7b93be3b51a84ef63e0abb79b32e3ca9c5200c315110bf8808662f5151b611c1b81612643565b611c3133611c2b610191856131a9565b90613845565b604080518381523360208201527fd73a150d677a06417ad5492867423fbeea1d4725d948735d751f4eb2f007361391016110d2565b6000611c7181612643565b611c7d610193836138ab565b60405173ffffffffffffffffffffffffffffffffffffffff831681527f200cfa7a0a16b05b66a5b25811b7460eada8b17a5781e3fd60450f1a844a1bf8906020016110d2565b611ccc81611061565b61150181611f9f565b6000611ce081612643565b6000611cf4611cef6101925490565b613901565b9050611d12611d0561019283612607565b6002810154600390910155565b604080518281523360208201527f600574a7b9be83162c89cebf12e8deb5c80a4121ec49f68ccd53d9de62add9b8910160405180910390a16040518181527f029ef4ddd14f777ffc2dc3e6b7193bc9fa2ff68a603ef378893d5fd60f589e21906020016110d2565b6000611d8581612643565b611d92610192848461390e565b60408051848152602081018490527fbec9fa51a19118a74ef477f3ec3be93e6d3d286d642e803907752aa8f48fd1719101610f69565b60006115a46101c55490565b7fd0aeb7b93be3b51a84ef63e0abb79b32e3ca9c5200c315110bf8808662f5151b611dfe81612643565b611e12611e0d610191846131a9565b613a9b565b604080518381523360208201527fae20b7107fac37bd8a6bd1699b45de51875917b048b8277994540c405bcceb5f91016110d2565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a611e7181612643565b611501613b21565b6000611e8481612643565b611e916101928484613b7d565b60408051848152602081018490527f55e125071c1ed92017657913f05c436509606565df0eadb787d078f53e350d2a9101610f69565b6000610e6a82611ed9610191866131a9565b90613c83565b6000828152609760205260408120610e6a9083613c92565b6000611f0281612643565b6000611f0e6101925490565b9050611f1b610192613c9e565b611f286101928287613b7d565b611f356101928286613d14565b611f42610192828561390e565b611f4a611cd5565b6040805182815260208101879052908101859052606081018490527f864ac6374d57584a6126b3250d1715c7e265cae3116cca3b97aae45dff8b8ac790608001611be2565b60606101638054610db7906158aa565b611fcd611fb7611fae83613e75565b61019290612607565b61278e611fc661019285612607565b9190613e82565b6040518181527f029ef4ddd14f777ffc2dc3e6b7193bc9fa2ff68a603ef378893d5fd60f589e2190602001610fc1565b600061200881612643565b612019662386f26fc1000083615916565b15612053576040517fb3eb388200000000000000000000000000000000000000000000000000000000815260048101839052602401611198565b61205d8383613f96565b6040805173ffffffffffffffffffffffffffffffffffffffff85168152602081018490527fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca59101610f69565b60006120b481612643565b6040514790339082156108fc029083906000818181858888f193505050501580156120e3573d6000803e3d6000fd5b5060408051338152602081018390527fb54913b2b58b2e96ea9b4e96ba2353cf13426af9d3f252e0c17899a93c4ce12591016110d2565b3360008181526101606020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909190838110156121c55760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401611198565b6110568286868403612487565b60006121dd81612643565b6121ea6101928484613d14565b60408051848152602081018490527f2758a36d588bf0eac3a7bc34b5bda0b05b1bdba15ab93e782f30f0c8807ae1d39101610f69565b600033610e488185856128a8565b60008080808080612241610191886131a9565b905061224e815460ff1690565b8154610100900473ffffffffffffffffffffffffffffffffffffffff16600183015461227c8461278e61413e565b612288856127ea61413e565b939b929a50909850965090945092505050565b60006115a46101925490565b60006122b281612643565b6122bd6101c5839055565b6040518281527f45afadbf69edc89bc6b1decea51aa7bd5fb5db0aecee33854dc7a683140e07d7906020016110d2565b6000818152609760205260408120610da190614151565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a61232e81612643565b61233b6101936001612f10565b6040517f0bcc813f2e83d9562e28e666ff81377a4b6951c9d66b1cf5ae43f3f809775a2790600090a150565b60008281526065602052604090206001015461238281612643565b6111038383612c7f565b60008060008061239f6101935460ff1690565b610193547501000000000000000000000000000000000000000000900460ff1661019354610100900473ffffffffffffffffffffffffffffffffffffffff1661019454935093509350935090919293565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610da157507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610da1565b73ffffffffffffffffffffffffffffffffffffffff831661250f5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401611198565b73ffffffffffffffffffffffffffffffffffffffff82166125985760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401611198565b73ffffffffffffffffffffffffffffffffffffffff8381166000818152610160602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b600082600001828154811061261e5761261e615b0a565b9060005260206000209060060201905092915050565b6000610e6a600484018361415b565b6115018133614167565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611103908490614207565b80546127119082906126ee90600190615b39565b815481106126fe576126fe615b0a565b90600052602060002090600602016142fc565b805481908061272257612722615b4c565b60008281526020812060067fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909301928302018181556001810182905560028101829055600381018290559060048201818181818161278182826153ca565b5050505050505050905550565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f887de0ec048f3aee6a161c3b9047f946719bdfa5e0d00244ac1983fe500e57b8602052604081205460ff16610da1565b6000610e6a6004840183614308565b50600190565b73ffffffffffffffffffffffffffffffffffffffff838116600090815261016060209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611641578181101561289b5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401611198565b6116418484848403612487565b73ffffffffffffffffffffffffffffffffffffffff83166129315760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401611198565b73ffffffffffffffffffffffffffffffffffffffff82166129ba5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401611198565b6129c583838361437d565b73ffffffffffffffffffffffffffffffffffffffff8316600090815261015f602052604090205481811015612a625760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401611198565b73ffffffffffffffffffffffffffffffffffffffff808516600081815261015f602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90612ad09086815260200190565b60405180910390a36116418484846144ef565b610fdf6004830182614608565b612afa82826146aa565b6000828152609760205260409020611103908261479e565b82600080825460ff166003811115612b2c57612b2c6157cc565b14612b6b5781546040517fc3f69e640000000000000000000000000000000000000000000000000000000081526111989160ff16908390600401615b7b565b8454610100900473ffffffffffffffffffffffffffffffffffffffff1615612b9557612b95615adb565b600185015415612ba757612ba7615adb565b73ffffffffffffffffffffffffffffffffffffffff8416612bf4576040517f24debe8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003612c2e576040517f18e236f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50508254600173ffffffffffffffffffffffffffffffffffffffff93909316610100027fffffffffffffffffffffff0000000000000000000000000000000000000000009091161782178355910155565b612c8982826147c0565b6000828152609760205260409020611103908261487b565b6000610fdf81612643565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612cdf576111038361489d565b8273ffffffffffffffffffffffffffffffffffffffff166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612d64575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252612d61918101906158fd565b60015b612dd65760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f7420555550530000000000000000000000000000000000006064820152608401611198565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8114612e6b5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c655555494400000000000000000000000000000000000000000000006064820152608401611198565b5061110383838361498d565b600182018190556000819003610fdf57610fdf826000612f10565b612e9a6149b2565b61012d80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b8015612fa7578154610100900473ffffffffffffffffffffffffffffffffffffffff16612f69576040517fbebe015b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160010154600003612fa7576040517fe66e3ac500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016901515179055565b600054610100900460ff166130505760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611198565b565b600054610100900460ff166130cf5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611198565b610fdf8282614a05565b600054610100900460ff166131565760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611198565b613050614a9d565b600082815260656020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b60008260000182815481106131c0576131c0615b0a565b9060005260206000209060040201905092915050565b825460ff166131e457505050565b8254610100900473ffffffffffffffffffffffffffffffffffffffff1661320d5761320d615adb565b8254604080517f313ce56700000000000000000000000000000000000000000000000000000000815290517501000000000000000000000000000000000000000000830460ff1692610100900473ffffffffffffffffffffffffffffffffffffffff169163313ce5679160048083019260209291908290030181865afa15801561329b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132bf9190615b96565b60ff16146133b6578260000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613336573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061335a9190615b96565b83546040517f2f25b3c800000000000000000000000000000000000000000000000000000000815260ff928316600482015275010000000000000000000000000000000000000000009091049091166024820152604401611198565b6000808460000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613428573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061344c9190615bd8565b5093505092505060008213613490576040517f62cf7c3d00000000000000000000000000000000000000000000000000000000815260048101839052602401611198565b81428211156134d4576040517f72a8b06500000000000000000000000000000000000000000000000000000000815260048101839052426024820152604401611198565b428660010154836134e59190615980565b10156135365760018601546134fa9083615980565b6040517f21339e450000000000000000000000000000000000000000000000000000000081526004810191909152426024820152604401611198565b806135418686615980565b111561358e576135518585615980565b6040517fca546cd8000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401611198565b505050505050565b82600180825460ff1660038111156135b0576135b06157cc565b146135ef5781546040517fc3f69e640000000000000000000000000000000000000000000000000000000081526111989160ff16908390600401615b7b565b6136046135ff6002870185614308565b851190565b15613653576136166002860184614308565b6040517fb0ed4a80000000000000000000000000000000000000000000000000000000008152600481019190915260248101859052604401611198565b505082547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166002179092555050565b81600201548260030154111561369b5761369b615adb565b81600101548111156136e95760018201546040517f1e5375dc000000000000000000000000000000000000000000000000000000008152611198918391600401918252602082015260400190565b81600301548111156137375760038201546040517f4d70d8d2000000000000000000000000000000000000000000000000000000008152611198918391600401918252602082015260400190565b8082600301600082825461374b9190615b39565b90915550505050565b73ffffffffffffffffffffffffffffffffffffffff82166137b75760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401611198565b6137c36000838361437d565b8061016160008282546137d69190615980565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815261015f60209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610fdf600083836144ef565b81600180825460ff16600381111561385f5761385f6157cc565b1461389e5781546040517fc3f69e640000000000000000000000000000000000000000000000000000000081526111989160ff16908390600401615b7b565b6116416002850184614608565b81547fffffffffffffffffffffff0000000000000000000000000000000000000000ff1661010073ffffffffffffffffffffffffffffffffffffffff8316908102919091178355610fdf57610fdf826000612f10565b6000610da1600183615b39565b8115158015613938575061393561392e61392784613901565b8590612607565b6002015490565b81105b1561398f578061395461392e61394d85613901565b8690612607565b6040517f4dbdd58600000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b6139a261399b83613e75565b84545b1190565b80156139bb57506139b861392e61392784613e75565b81115b15613a0b57806139d061392e61394d85613e75565b6040517f4b033f0600000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b613a1761399b83613e75565b8015613a375750613a34613a2d61392784613e75565b6001015490565b81115b15613a875780613a4c613a2d61394d85613e75565b6040517f3b9a7f9e00000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b61110381613a958585612607565b90614b45565b80600180825460ff166003811115613ab557613ab56157cc565b14613af45781546040517fc3f69e640000000000000000000000000000000000000000000000000000000081526111989160ff16908390600401615b7b565b505080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166003179055565b613b29614bb5565b61012d80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612ee63390565b8115158015613ba55750613ba58161399e613ba1613b9a86613901565b8790612607565b5490565b15613bf55780613bba613ba161394d85613901565b6040517fb9a81cd000000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b613c0161399b83613e75565b8015613c1f5750613c1f81613c1b613ba1613b9a86613e75565b1090565b15613c6f5780613c34613ba161394d85613e75565b6040517fac0f679300000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b61110381613c7d8585612607565b90614c09565b6000610e6a600284018361415b565b6000610e6a8383614c54565b8054600181018255600082815260209020600690910201613cdf817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff614b45565b613d09817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff614c7e565b610fdf816008614c09565b8115158015613d305750613d2d613a2d61392784613901565b81105b15613d805780613d45613a2d61394d85613901565b6040517f11a3a53700000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b8115158015613d9c5750613d9961392e61392784613901565b81105b15613dec5780613db161392e61394d85613901565b6040517f0ea95e9e00000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b613df861399b83613e75565b8015613e115750613e0e613a2d61392784613e75565b81115b15613e615780613e26613a2d61394d85613e75565b6040517f94459c3400000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b61110381613e6f8585612607565b90614c7e565b6000610da1826001615980565b818303613ebb576040517f39cb906e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613ed1613ecb6004850183614308565b83541190565b15613f2057613ee36004840182614308565b82546040517f0dfbd73200000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b613f2c83600401614cd9565b826002015483600301541115613f4457613f44615adb565b600083600301548460020154613f5a9190615b39565b9050613f668382613683565b80846003016000828254613f7a9190615980565b9091555050600284015460038501541461164157611641615adb565b73ffffffffffffffffffffffffffffffffffffffff821661401f5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401611198565b61402b8260008361437d565b73ffffffffffffffffffffffffffffffffffffffff8216600090815261015f6020526040902054818110156140c85760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401611198565b73ffffffffffffffffffffffffffffffffffffffff8316600081815261015f60209081526040808320868603905561016180548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3611103836000846144ef565b6000610e6a6002840183614308565b9055565b6000610da1825490565b6000610e6a8383613c92565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610fdf576141a781614d2a565b6141b2836020614d49565b6040516020016141c3929190615c28565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905262461bcd60e51b825261119891600401615462565b6000614269826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614f729092919063ffffffff16565b905080516000148061428a57508080602001905181019061428a9190615ca9565b6111035760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611198565b61150181600401614cd9565b60008061431484614151565b9050614321816008101590565b61432d5761432d615adb565b6000805b828110156143745761434f6143468783613c92565b8663ffffffff16565b15614362578161435e81615ccb565b9250505b8061436c81615ccb565b915050614331565b50949350505050565b3360009081527fffdfc1249c027f9191656349feb0761381bb32c9f557e01f419fd08754bf5a1b602052604090205460ff16156143b957505050565b6143c1614bb5565b73ffffffffffffffffffffffffffffffffffffffff831660009081527f09c52666ba87d2e41727af01aa8497c97e949bf87354a8ac7a6d0ecdc58a4bc0602052604090205460ff1615614458576040517f76a772de00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401611198565b73ffffffffffffffffffffffffffffffffffffffff821660009081527f09c52666ba87d2e41727af01aa8497c97e949bf87354a8ac7a6d0ecdc58a4bc0602052604090205460ff1615611103576040517f76a772de00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401611198565b73ffffffffffffffffffffffffffffffffffffffff82161580159061452d57506210000073ffffffffffffffffffffffffffffffffffffffff831611155b156111035761455b7efc2d686fa04c73d9010c440266d7edf4fc9634ba060d3fcce2280634f9998e83614167565b61456c662386f26fc1000082615916565b156145a6576040517fb3eb388200000000000000000000000000000000000000000000000000000000815260048101829052602401611198565b6145b26101c582614f89565b6145bc8282613f96565b6040805173ffffffffffffffffffffffffffffffffffffffff84168152602081018390527f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a69101610f69565b61461b61461483614151565b6008111590565b15614652576040517f04290ffa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61465c828261479e565b610fdf576040517fab7c05b700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401611198565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610fdf57600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556147403390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610e6a8373ffffffffffffffffffffffffffffffffffffffff8416614fd1565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1615610fdf57600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610e6a8373ffffffffffffffffffffffffffffffffffffffff8416615020565b73ffffffffffffffffffffffffffffffffffffffff81163b6149275760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152608401611198565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61499683615113565b6000825111806149a35750805b15611103576116418383615160565b61012d5460ff166130505760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401611198565b600054610100900460ff16614a825760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611198565b610162614a8f8382615d49565b506101636111038282615d49565b600054610100900460ff16614b1a5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611198565b61012d80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6001820154811015614b935760018201546040517f6e9ee463000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401611198565b600282018190556003820154614ba99082615185565b82600301819055505050565b61012d5460ff16156130505760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401611198565b614c138160081090565b1561414d576040517f446867d80000000000000000000000000000000000000000000000000000000081526004810182905260086024820152604401611198565b6000826000018281548110614c6b57614c6b615b0a565b9060005260206000200154905092915050565b6002820154811115614cd15780614c96836002015490565b6040517f6e9ee46300000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401611198565b600190910155565b6000614ce482614151565b90505b8015610fdf57614d0c614d05614cfe600184615b39565b8490613c92565b839061487b565b614d1857614d18615adb565b80614d2281615e63565b915050614ce7565b6060610da173ffffffffffffffffffffffffffffffffffffffff831660145b60606000614d58836002615e98565b614d63906002615980565b67ffffffffffffffff811115614d7b57614d7b6155ff565b6040519080825280601f01601f191660200182016040528015614da5576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110614ddc57614ddc615b0a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110614e3f57614e3f615b0a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000614e7b846002615e98565b614e86906001615980565b90505b6001811115614f23577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110614ec757614ec7615b0a565b1a60f81b828281518110614edd57614edd615b0a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93614f1c81615e63565b9050614e89565b508315610e6a5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401611198565b6060614f81848460008561519b565b949350505050565b8154811015610fdf5781546040517fa969824c000000000000000000000000000000000000000000000000000000008152611198918391600401918252602082015260400190565b600081815260018301602052604081205461501857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610da1565b506000610da1565b60008181526001830160205260408120548015615109576000615044600183615b39565b855490915060009061505890600190615b39565b90508181146150bd57600086600001828154811061507857615078615b0a565b906000526020600020015490508087600001848154811061509b5761509b615b0a565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806150ce576150ce615b4c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610da1565b6000915050610da1565b61511c8161489d565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060610e6a8383604051806060016040528060278152602001615ecc6027913961529a565b60008183106151945781610e6a565b5090919050565b6060824710156152135760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611198565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161523c9190615eaf565b60006040518083038185875af1925050503d8060008114615279576040519150601f19603f3d011682016040523d82523d6000602084013e61527e565b606091505b509150915061528f8783838761531f565b979650505050505050565b60606000808573ffffffffffffffffffffffffffffffffffffffff16856040516152c49190615eaf565b600060405180830381855af49150503d80600081146152ff576040519150601f19603f3d011682016040523d82523d6000602084013e615304565b606091505b50915091506153158683838761531f565b9695505050505050565b6060831561539b5782516000036153945773ffffffffffffffffffffffffffffffffffffffff85163b6153945760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611198565b5081614f81565b614f8183838151156153b05781518083602001fd5b8060405162461bcd60e51b81526004016111989190615462565b508054600082559060005260206000209081019061150191905b808211156153f857600081556001016153e4565b5090565b60006020828403121561540e57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610e6a57600080fd5b60005b83811015615459578181015183820152602001615441565b50506000910152565b602081526000825180602084015261548181604085016020870161543e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461150157600080fd5b600080604083850312156154e857600080fd5b82356154f3816154b3565b946020939093013593505050565b6000806040838503121561551457600080fd5b50508035926020909101359150565b60006020828403121561553557600080fd5b8135610e6a816154b3565b60006020828403121561555257600080fd5b5035919050565b60008060006060848603121561556e57600080fd5b8335615579816154b3565b92506020840135615589816154b3565b929592945050506040919091013590565b600080604083850312156155ad57600080fd5b8235915060208301356155bf816154b3565b809150509250929050565b6000806000606084860312156155df57600080fd5b83356155ea816154b3565b95602085013595506040909401359392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600067ffffffffffffffff80841115615649576156496155ff565b604051601f85017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561568f5761568f6155ff565b816040528093508581528686860111156156a857600080fd5b858560208301376000602087830101525050509392505050565b600082601f8301126156d357600080fd5b610e6a8383356020850161562e565b600080604083850312156156f557600080fd5b823567ffffffffffffffff8082111561570d57600080fd5b615719868387016156c2565b9350602085013591508082111561572f57600080fd5b5061573c858286016156c2565b9150509250929050565b6000806040838503121561575957600080fd5b8235615764816154b3565b9150602083013567ffffffffffffffff81111561578057600080fd5b8301601f8101851361579157600080fd5b61573c8582356020840161562e565b6000806000606084860312156157b557600080fd5b505081359360208301359350604090920135919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110615832577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60a0810161584482886157fb565b73ffffffffffffffffffffffffffffffffffffffff861660208301528460408301528360608301528260808301529695505050505050565b6000806040838503121561588f57600080fd5b823561589a816154b3565b915060208301356155bf816154b3565b600181811c908216806158be57607f821691505b6020821081036158f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60006020828403121561590f57600080fd5b5051919050565b60008261594c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610da157610da1615951565b60ff8281168282160390811115610da157610da1615951565b600181815b80851115615a0557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156159eb576159eb615951565b808516156159f857918102915b93841c93908002906159b1565b509250929050565b600082615a1c57506001610da1565b81615a2957506000610da1565b8160018114615a3f5760028114615a4957615a65565b6001915050610da1565b60ff841115615a5a57615a5a615951565b50506001821b610da1565b5060208310610133831016604e8410600b8410161715615a88575081810a610da1565b615a9283836159ac565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615ac457615ac4615951565b029392505050565b6000610e6a60ff841683615a0d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b81810381811115610da157610da1615951565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60408101615b8982856157fb565b610e6a60208301846157fb565b600060208284031215615ba857600080fd5b815160ff81168114610e6a57600080fd5b805169ffffffffffffffffffff81168114615bd357600080fd5b919050565b600080600080600060a08688031215615bf057600080fd5b615bf986615bb9565b9450602086015193506040860151925060608601519150615c1c60808701615bb9565b90509295509295909350565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351615c6081601785016020880161543e565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351615c9d81602884016020880161543e565b01602801949350505050565b600060208284031215615cbb57600080fd5b81518015158114610e6a57600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615cfc57615cfc615951565b5060010190565b601f82111561110357600081815260208120601f850160051c81016020861015615d2a5750805b601f850160051c820191505b8181101561358e57828155600101615d36565b815167ffffffffffffffff811115615d6357615d636155ff565b615d7781615d7184546158aa565b84615d03565b602080601f831160018114615dca5760008415615d945750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561358e565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015615e1757888601518255948401946001909101908401615df8565b5085821015615e5357878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600081615e7257615e72615951565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8082028115828204841417610da157610da1615951565b60008251615ec181846020870161543e565b919091019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212203877674babd5c024ccfa7d86146e70d83be05618fdc2777994acd17b685af26f64736f6c63430008130033
Deployed Bytecode Sourcemap
1505:12383:26:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;983:223:1;;;;;;;;;;-1:-1:-1;983:223:1;;;;;:::i;:::-;;:::i;:::-;;;516:14:34;;509:22;491:41;;479:2;464:18;983:223:1;;;;;;;;2516:98:12;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;4802:197::-;;;;;;;;;;-1:-1:-1;4802:197:12;;;;;:::i;:::-;;:::i;6709:239:26:-;;;;;;;;;;-1:-1:-1;6709:239:26;;;;;:::i;:::-;;:::i;:::-;;;2222:42:34;2210:55;;;2192:74;;2180:2;2165:18;6709:239:26;2046:226:34;13610:276:26;;;;;;;;;;-1:-1:-1;13610:276:26;;;;;:::i;:::-;;:::i;:::-;;3613:106:12;;;;;;;;;;-1:-1:-1;3700:12:12;;3613:106;;;2701:25:34;;;2689:2;2674:18;3613:106:12;2555:177:34;8699:141:26;;;;;;;;;;;;;:::i;12783:157::-;;;;;;;;;;-1:-1:-1;12783:157:26;;;;;:::i;:::-;;:::i;6268:435::-;;;;;;;;;;-1:-1:-1;6268:435:26;;;;;:::i;:::-;;:::i;:::-;;;;3628:25:34;;;3684:2;3669:18;;3662:34;;;;3712:18;;;3705:34;;;;3770:2;3755:18;;3748:34;3813:3;3798:19;;3791:35;3857:3;3842:19;;3835:35;3615:3;3600:19;6268:435:26;3263:613:34;5561:256:12;;;;;;;;;;-1:-1:-1;5561:256:12;;;;;:::i;:::-;;:::i;10401:234:26:-;;;;;;;;;;-1:-1:-1;10401:234:26;;;;;:::i;:::-;;:::i;4855:129:2:-;;;;;;;;;;-1:-1:-1;4855:129:2;;;;;:::i;:::-;4929:7;4955:12;;;:6;:12;;;;;:22;;;;4855:129;5280:145;;;;;;;;;;-1:-1:-1;5280:145:2;;;;;:::i;:::-;;:::i;3462:91:12:-;;;;;;;;;;-1:-1:-1;3462:91:12;;3544:2;5171:36:34;;5159:2;5144:18;3462:91:12;5029:184:34;11409:475:26;;;;;;;;;;-1:-1:-1;11409:475:26;;;;;:::i;:::-;;:::i;6389:214:2:-;;;;;;;;;;-1:-1:-1;6389:214:2;;;;;:::i;:::-;;:::i;3408:195:10:-;;;;;;;;;;-1:-1:-1;3408:195:10;;;;;:::i;:::-;;:::i;10023:207:26:-;;;;;;;;;;-1:-1:-1;10023:207:26;;;;;:::i;:::-;;:::i;6212:234:12:-;;;;;;;;;;-1:-1:-1;6212:234:12;;;;;:::i;:::-;;:::i;2366:86:26:-;;;;;;;;;;;;2416:36;2366:86;;6954:115;;;;;;;;;;;;;:::i;4931:84::-;;;;;;;;;;;;;:::i;9662:158::-;;;;;;;;;;;;;:::i;12554:223::-;;;;;;;;;;-1:-1:-1;12554:223:26;;;;;:::i;:::-;;:::i;2459:39::-;;;;;;;;;;;;2490:8;2459:39;;4210:545;;;;;;;;;;-1:-1:-1;4210:545:26;;;;;:::i;:::-;;:::i;3922:220:10:-;;;;;;:::i;:::-;;:::i;3027:131::-;;;;;;;;;;;;;:::i;12079:469:26:-;;;;;;;;;;-1:-1:-1;12079:469:26;;;;;:::i;:::-;;:::i;2060:76::-;;;;;;;;;;;;2105:31;2060:76;;11890:183;;;;;;;;;;-1:-1:-1;11890:183:26;;;;;:::i;:::-;;:::i;1879:84:11:-;;;;;;;;;;-1:-1:-1;1949:7:11;;;;1879:84;;9826:191:26;;;;;;;;;;-1:-1:-1;9826:191:26;;;;;:::i;:::-;;:::i;10881:201::-;;;;;;;;;;-1:-1:-1;10881:201:26;;;;;:::i;:::-;;:::i;11088:315::-;;;;;;;;;;;;;:::i;9300:195::-;;;;;;;;;;-1:-1:-1;9300:195:26;;;;;:::i;:::-;;:::i;3777:125:12:-;;;;;;;;;;-1:-1:-1;3777:125:12;;;;;:::i;:::-;3877:18;;3851:7;3877:18;;;:9;:18;;;;;;;3777:125;8106:118:26;;;;;;;;;;;;;:::i;12946:174::-;;;;;;;;;;-1:-1:-1;12946:174:26;;;;;:::i;:::-;;:::i;2504:66::-;;;;;;;;;;;;2561:8;2504:66;;4852:73;;;;;;;;;;;;;:::i;2210:62::-;;;;;;;;;;;;2248:24;2210:62;;8846:223;;;;;;;;;;-1:-1:-1;8846:223:26;;;;;:::i;:::-;;:::i;7531:251::-;;;;;;;;;;-1:-1:-1;7531:251:26;;;;;:::i;:::-;;:::i;1791:151:1:-;;;;;;;;;;-1:-1:-1;1791:151:1;;;;;:::i;:::-;;:::i;3350:145:2:-;;;;;;;;;;-1:-1:-1;3350:145:2;;;;;:::i;:::-;3436:4;3459:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;;;;3350:145;8230:463:26;;;;;;;;;;-1:-1:-1;8230:463:26;;;;;:::i;:::-;;:::i;2727:102:12:-;;;;;;;;;;;;;:::i;10641:234:26:-;;;;;;;;;;-1:-1:-1;10641:234:26;;;;;:::i;:::-;;:::i;13126:259::-;;;;;;;;;;-1:-1:-1;13126:259:26;;;;;:::i;:::-;;:::i;2278:82::-;;;;;;;;;;;;2326:34;2278:82;;13391:213;;;;;;;;;;;;;:::i;2320:49:2:-;;;;;;;;;;-1:-1:-1;2320:49:2;2365:4;2320:49;;6933:427:12;;;;;;;;;;-1:-1:-1;6933:427:12;;;;;:::i;:::-;;:::i;9075:219:26:-;;;;;;;;;;-1:-1:-1;9075:219:26;;;;;:::i;:::-;;:::i;4098:189:12:-;;;;;;;;;;-1:-1:-1;4098:189:12;;;;;:::i;:::-;;:::i;7075:450:26:-;;;;;;;;;;-1:-1:-1;7075:450:26;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;6155:107::-;;;;;;;;;;;;;:::i;10236:159::-;;;;;;;;;;-1:-1:-1;10236:159:26;;;;;:::i;:::-;;:::i;2110:140:1:-;;;;;;;;;;-1:-1:-1;2110:140:1;;;;;:::i;:::-;;:::i;9501:155:26:-;;;;;;;;;;;;;:::i;1992:62::-;;;;;;;;;;;;2030:24;1992:62;;5705:147:2;;;;;;;;;;-1:-1:-1;5705:147:2;;;;;:::i;:::-;;:::i;7788:312:26:-;;;;;;;;;;;;;:::i;:::-;;;;11781:14:34;;11774:22;11756:41;;11845:4;11833:17;;;11828:2;11813:18;;11806:45;11899:42;11887:55;;;11867:18;;;11860:83;;;;11974:2;11959:18;;11952:34;11743:3;11728:19;7788:312:26;11507:485:34;4345:149:12;;;;;;;;;;-1:-1:-1;4345:149:12;;;;;:::i;:::-;4460:18;;;;4434:7;4460:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;4345:149;2142:62:26;;;;;;;;;;;;2180:24;2142:62;;983:223:1;1068:4;1091:68;;;1106:53;1091:68;;:108;;;1163:36;1187:11;1163:23;:36::i;:::-;1084:115;983:223;-1:-1:-1;;983:223:1:o;2516:98:12:-;2570:13;2602:5;2595:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2516:98;:::o;4802:197::-;4885:4;965:10:18;4939:32:12;965:10:18;4955:7:12;4964:6;4939:8;:32::i;:::-;-1:-1:-1;4988:4:12;;4802:197;-1:-1:-1;;;4802:197:12:o;6709:239:26:-;6848:7;6874:67;6921:19;6874:24;:10;6888:9;6874:13;:24::i;:::-;:46;;:67::i;:::-;6867:74;6709:239;-1:-1:-1;;;6709:239:26:o;13610:276::-;2365:4:2;2798:16;2365:4;2798:10;:16::i;:::-;13723:30:26::1;::::0;;;;13747:4:::1;13723:30;::::0;::::1;2192:74:34::0;13705:15:26::1;::::0;13723::::1;::::0;::::1;::::0;::::1;::::0;2165:18:34;;13723:30:26::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13705:48;;13763:61;13797:5;13804:10;13816:7;13763:33;:61::i;:::-;13839:40;::::0;;13259:42:34;13328:15;;13310:34;;13859:10:26::1;13375:2:34::0;13360:18;;13353:43;13412:18;;;13405:34;;;13839:40:26::1;::::0;13237:2:34;13222:18;13839:40:26::1;;;;;;;;13695:191;13610:276:::0;;:::o;8699:141::-;2365:4:2;2798:16;2365:4;2798:10;:16::i;:::-;8770::26::1;:10;:14;:16::i;:::-;8801:32;8813:19;:10;2084:18:31::0;;1967:143;8813:19:26::1;8801:32;::::0;2701:25:34;;;2689:2;2674:18;8801:32:26::1;;;;;;;;8699:141:::0;:::o;12783:157::-;12872:19;12883:7;12872:10;:19::i;:::-;12901:32;12914:7;12923:9;12901:12;:32::i;:::-;12783:157;;:::o;6268:435::-;6334:5;;;;;;;6422:24;:10;6436:9;6422:13;:24::i;:::-;6392:54;;6477:17;:4;1509:16:30;;1413:119;6477:17:26;1635:15:30;;;;1756:11;;;;1873;;;;6590:42:26;:4;6616:15;6590:25;:42::i;:::-;6646:40;:4;6672:13;6646:25;:40::i;:::-;6456:240;;;;-1:-1:-1;6456:240:26;;-1:-1:-1;6456:240:26;-1:-1:-1;6456:240:26;-1:-1:-1;6456:240:26;;-1:-1:-1;6268:435:26;-1:-1:-1;;;6268:435:26:o;5561:256:12:-;5658:4;965:10:18;5714:38:12;5730:4;965:10:18;5745:6:12;5714:15;:38::i;:::-;5762:27;5772:4;5778:2;5782:6;5762:9;:27::i;:::-;-1:-1:-1;5806:4:12;;5561:256;-1:-1:-1;;;;5561:256:12:o;10401:234:26:-;2105:31;2798:16:2;2809:4;2798:10;:16::i;:::-;10511:58:26::1;10558:10;10511:24;:10;10525:9:::0;10511:13:::1;:24::i;:::-;:46:::0;::::1;:58::i;:::-;10584:44;::::0;;13654:25:34;;;10617:10:26::1;13710:2:34::0;13695:18;;13688:83;10584:44:26::1;::::0;13627:18:34;10584:44:26::1;;;;;;;;10401:234:::0;;:::o;5280:145:2:-;4929:7;4955:12;;;:6;:12;;;;;:22;;;2798:16;2809:4;2798:10;:16::i;:::-;5393:25:::1;5404:4;5410:7;5393:10;:25::i;:::-;5280:145:::0;;;:::o;11409:475:26:-;2030:24;2798:16:2;2809:4;2798:10;:16::i;:::-;2561:8:26::1;11500:46;::::0;::::1;;11496:124;;11569:40;::::0;::::1;::::0;;2222:42:34;2210:55;;11569:40:26::1;::::0;::::1;2192:74:34::0;2165:18;;11569:40:26::1;;;;;;;;11496:124;11633:12;2490:8;11633:5:::0;:12:::1;:::i;:::-;:17:::0;11629:88:::1;;11673:33;::::0;::::1;::::0;;::::1;::::0;::::1;2701:25:34::0;;;2674:18;;11673:33:26::1;2555:177:34::0;11629:88:26::1;11726:15;11744:24;:15;2084:18:31::0;;1967:143;11744:24:26::1;11778:15;983:18:29::0;;;;;;;-1:-1:-1;983:18:29;;;;11726:42:26;;-1:-1:-1;11778:41:26::1;::::0;983:18:29;;;;11809:2:26;11813:5;11778:30:::1;:41::i;:::-;11834:43;::::0;;14312:25:34;;;14356:42;14434:15;;14429:2;14414:18;;14407:43;14466:18;;;14459:34;;;11866:10:26::1;14524:2:34::0;14509:18;;14502:43;11834::26::1;::::0;14299:3:34;14284:19;11834:43:26::1;;;;;;;11486:398;11409:475:::0;;;:::o;6389:214:2:-;6484:23;;;965:10:18;6484:23:2;6476:83;;;;-1:-1:-1;;;6476:83:2;;14758:2:34;6476:83:2;;;14740:21:34;14797:2;14777:18;;;14770:30;14836:34;14816:18;;;14809:62;14907:17;14887:18;;;14880:45;14942:19;;6476:83:2;14556:411:34;6476:83:2;6570:26;6582:4;6588:7;6570:11;:26::i;3408:195:10:-;1747:23;1764:6;1747:23;1755:4;1747:23;1739:80;;;;-1:-1:-1;;;1739:80:10;;15174:2:34;1739:80:10;;;15156:21:34;15213:2;15193:18;;;15186:30;15252:34;15232:18;;;15225:62;15323:14;15303:18;;;15296:42;15355:19;;1739:80:10;14972:408:34;1739:80:10;1861:6;1837:30;;:20;1180:66:7;1557:65;;;;1478:151;1837:20:10;:30;;;1829:87;;;;-1:-1:-1;;;1829:87:10;;15587:2:34;1829:87:10;;;15569:21:34;15626:2;15606:18;;;15599:30;15665:34;15645:18;;;15638:62;15736:14;15716:18;;;15709:42;15768:19;;1829:87:10;15385:408:34;1829:87:10;3489:36:::1;3507:17;3489;:36::i;:::-;3576:12;::::0;;3586:1:::1;3576:12:::0;;;::::1;::::0;::::1;::::0;;;3535:61:::1;::::0;3557:17;;3576:12;3535:21:::1;:61::i;:::-;3408:195:::0;:::o;10023:207:26:-;2365:4:2;2798:16;2365:4;2798:10;:16::i;:::-;10126:45:26::1;:21;10161:9:::0;10126:34:::1;:45::i;:::-;10186:37;::::0;2701:25:34;;;10186:37:26::1;::::0;2689:2:34;2674:18;10186:37:26::1;2555:177:34::0;6212:234:12;965:10:18;6300:4:12;4460:18;;;:11;:18;;;;;;;;;:27;;;;;;;;;;6300:4;;965:10:18;6354:64:12;;965:10:18;;4460:27:12;;6379:38;;6407:10;;6379:38;:::i;:::-;6354:8;:64::i;6954:115:26:-;7012:7;7038:24;:15;2084:18:31;;1967:143;7038:24:26;7031:31;;6954:115;:::o;4931:84::-;2365:4:2;2798:16;2365:4;2798:10;:16::i;:::-;4998:10:26::1;:8;:10::i;9662:158::-:0;2180:24;2798:16:2;2809:4;2798:10;:16::i;:::-;9736:39:26::1;:21;9769:5;9736:32;:39::i;:::-;9790:23;::::0;::::1;::::0;;;::::1;9662:158:::0;:::o;12554:223::-;12654:15;12672:24;:15;2084:18:31;;1967:143;12672:24:26;12654:42;;12706:22;12718:2;12722:5;12706:11;:22::i;:::-;12738:32;12751:7;12760:9;12738:12;:32::i;:::-;12644:133;12554:223;;;:::o;4210:545::-;3279:19:9;3302:13;;;;;;3301:14;;3347:34;;;;-1:-1:-1;3365:12:9;;3380:1;3365:12;;;;:16;3347:34;3346:108;;;-1:-1:-1;3426:4:9;1713:19:17;:23;;;3387:66:9;;-1:-1:-1;3436:12:9;;;;;:17;3387:66;3325:201;;;;-1:-1:-1;;;3325:201:9;;16319:2:34;3325:201:9;;;16301:21:34;16358:2;16338:18;;;16331:30;16397:34;16377:18;;;16370:62;16468:16;16448:18;;;16441:44;16502:19;;3325:201:9;16117:410:34;3325:201:9;3536:12;:16;;;;3551:1;3536:16;;;3562:65;;;;3596:13;:20;;;;;;;;3562:65;4303:67:26::1;:65;:67::i;:::-;4380:45;4410:5;4417:7;4380:29;:45::i;:::-;4435:40;:38;:40::i;:::-;4485:37;:35;:37::i;:::-;4532:42;2365:4:2;4563:10:26;4532;:42::i;:::-;4584:61;2416:36;2326:34;4584:13;:61::i;:::-;4655:21;3446:26:32::0;;;;;;;;4732:14:26::1;4745:1;3544:2:12::0;4732:14:26::1;:::i;:::-;4725:22;::::0;:2:::1;:22;:::i;:::-;2490:8;4717:30;4710:38;;;;:::i;:::-;3651:14:9::0;3647:99;;;3697:5;3681:21;;;;;;3721:14;;-1:-1:-1;5171:36:34;;3721:14:9;;5159:2:34;5144:18;3721:14:9;5029:184:34;3922:220:10;1747:23;1764:6;1747:23;1755:4;1747:23;1739:80;;;;-1:-1:-1;;;1739:80:10;;15174:2:34;1739:80:10;;;15156:21:34;15213:2;15193:18;;;15186:30;15252:34;15232:18;;;15225:62;15323:14;15303:18;;;15296:42;15355:19;;1739:80:10;14972:408:34;1739:80:10;1861:6;1837:30;;:20;1180:66:7;1557:65;;;;1478:151;1837:20:10;:30;;;1829:87;;;;-1:-1:-1;;;1829:87:10;;15587:2:34;1829:87:10;;;15569:21:34;15626:2;15606:18;;;15599:30;15665:34;15645:18;;;15638:62;15736:14;15716:18;;;15709:42;15768:19;;1829:87:10;15385:408:34;1829:87:10;4037:36:::1;4055:17;4037;:36::i;:::-;4083:52;4105:17;4124:4;4130;4083:21;:52::i;3027:131::-:0;3105:7;2190:4;2182:23;2199:6;2182:23;;2174:92;;;;-1:-1:-1;;;2174:92:10;;18781:2:34;2174:92:10;;;18763:21:34;18820:2;18800:18;;;18793:30;18859:34;18839:18;;;18832:62;18930:26;18910:18;;;18903:54;18974:19;;2174:92:10;18579:420:34;2174:92:10;-1:-1:-1;1180:66:7::1;3027:131:10::0;:::o;12079:469:26:-;12156:28;12187:27;:15;12206:7;12187:18;:27::i;:::-;12156:58;-1:-1:-1;12224:27:26;12254:24;:10;12268:9;12254:13;:24::i;:::-;12224:54;;12288:13;12304:10;:2;1635:15:30;;;;1538:119;12304:10:26;12288:26;;12325:53;12357:5;12364:13;3700:12:12;;;3613:106;12364:13:26;12325:21;;:53;:31;:53::i;:::-;12389:47;12401:17;:4;1509:16:30;;1413:119;12401:17:26;12389:2;;12420:15;12389:11;:47::i;:::-;12446:17;:4;12457:5;12446:10;:17::i;:::-;1585:8:28;;12473:21:26;;1585:8:28;;;;;12488:5:26;12473;:21::i;:::-;12509:32;;;19236:25:34;;;19292:2;19277:18;;19270:34;;;12509:32:26;;19209:18:34;12509:32:26;;;;;;;;12146:402;;;12079:469;;:::o;11890:183::-;2105:31;2798:16:2;2809:4;2798:10;:16::i;:::-;11973:47:26::1;12009:10;11973:27;:15;11992:7:::0;11973:18:::1;:27::i;:::-;:35:::0;::::1;:47::i;:::-;12035:31;::::0;;13654:25:34;;;12055:10:26::1;13710:2:34::0;13695:18;;13688:83;12035:31:26::1;::::0;13627:18:34;12035:31:26::1;13450:327:34::0;9826:191:26;2365:4:2;2798:16;2365:4;2798:10;:16::i;:::-;9933:35:26::1;:21;9963:4:::0;9933:29:::1;:35::i;:::-;9983:27;::::0;2222:42:34;2210:55;;2192:74;;9983:27:26::1;::::0;2180:2:34;2165:18;9983:27:26::1;2046:226:34::0;10881:201:26;10976:44;11010:9;10976:33;:44::i;:::-;11030:45;11065:9;11030:34;:45::i;11088:315::-;2365:4:2;2798:16;2365:4;2798:10;:16::i;:::-;11173:23:26::1;11199:26;:19;:10;2084:18:31::0;;1967:143;11199:19:26::1;:24;:26::i;:::-;11173:52:::0;-1:-1:-1;11235:46:26::1;:28;:10;11173:52:::0;11235:13:::1;:28::i;:::-;4546:11:30::0;;;;4532;;;;:25;4459:105;11235:46:26::1;11296:48;::::0;;13654:25:34;;;11333:10:26::1;13710:2:34::0;13695:18;;13688:83;11296:48:26::1;::::0;13627:18:34;11296:48:26::1;;;;;;;11359:37;::::0;2701:25:34;;;11359:37:26::1;::::0;2689:2:34;2674:18;11359:37:26::1;2555:177:34::0;9300:195:26;2365:4:2;2798:16;2365:4;2798:10;:16::i;:::-;9406:37:26::1;:10;9426:9:::0;9437:5;9406:19:::1;:37::i;:::-;9458:30;::::0;;19236:25:34;;;19292:2;19277:18;;19270:34;;;9458:30:26::1;::::0;19209:18:34;9458:30:26::1;19004:306:34::0;8106:118:26;8168:7;8194:23;:17;1509:16:30;;1413:119;12946:174:26;2105:31;2798:16:2;2809:4;2798:10;:16::i;:::-;13031:36:26::1;:27;:15;13050:7:::0;13031:18:::1;:27::i;:::-;:34;:36::i;:::-;13082:31;::::0;;13654:25:34;;;13102:10:26::1;13710:2:34::0;13695:18;;13688:83;13082:31:26::1;::::0;13627:18:34;13082:31:26::1;13450:327:34::0;4852:73:26;2180:24;2798:16:2;2809:4;2798:10;:16::i;:::-;4910:8:26::1;:6;:8::i;8846:223::-:0;2365:4:2;2798:16;2365:4;2798:10;:16::i;:::-;8960:47:26::1;:10;8985:9:::0;8996:10;8960:24:::1;:47::i;:::-;9022:40;::::0;;19236:25:34;;;19292:2;19277:18;;19270:34;;;9022:40:26::1;::::0;19209:18:34;9022:40:26::1;19004:306:34::0;7531:251:26;7675:7;7701:74;7753:21;7701:27;:15;7720:7;7701:18;:27::i;:::-;:51;;:74::i;1791:151:1:-;1881:7;1907:18;;;:12;:18;;;;;:28;;1929:5;1907:21;:28::i;8230:463:26:-;2365:4:2;2798:16;2365:4;2798:10;:16::i;:::-;8352:19:26::1;8374;:10;2084:18:31::0;;1967:143;8374:19:26::1;8352:41;;8403:17;:10;:15;:17::i;:::-;8430:47;:10;8455:9:::0;8466:10;8430:24:::1;:47::i;:::-;8487:45;:10;8511:9:::0;8522;8487:23:::1;:45::i;:::-;8542:37;:10;8562:9:::0;8573:5;8542:19:::1;:37::i;:::-;8589:29;:27;:29::i;:::-;8633:53;::::0;;20783:25:34;;;20839:2;20824:18;;20817:34;;;20867:18;;;20860:34;;;20925:2;20910:18;;20903:34;;;8633:53:26::1;::::0;20770:3:34;20755:19;8633:53:26::1;20496:447:34::0;2727:102:12;2783:13;2815:7;2808:14;;;;;:::i;10641:234:26:-;10723:97;10771:31;10785:16;:9;:14;:16::i;:::-;10771:10;;:13;:31::i;:::-;10804:15;10723:24;:10;10737:9;10723:13;:24::i;:::-;:47;:97;:47;:97::i;:::-;10835:33;;2701:25:34;;;10835:33:26;;2689:2:34;2674:18;10835:33:26;2555:177:34;13126:259:26;2365:4:2;2798:16;2365:4;2798:10;:16::i;:::-;13225:13:26::1;2490:8;13225:6:::0;:13:::1;:::i;:::-;:18:::0;13221:90:::1;;13266:34;::::0;::::1;::::0;;::::1;::::0;::::1;2701:25:34::0;;;2674:18;;13266:34:26::1;2555:177:34::0;13221:90:26::1;13320:22;13326:7;13335:6;13320:5;:22::i;:::-;13357:21;::::0;;21152:42:34;21140:55;;21122:74;;21227:2;21212:18;;21205:34;;;13357:21:26::1;::::0;21095:18:34;13357:21:26::1;20948:297:34::0;13391:213:26;2365:4:2;2798:16;2365:4;2798:10;:16::i;:::-;13512:37:26::1;::::0;13481:21:::1;::::0;13520:10:::1;::::0;13512:37;::::1;;;::::0;13481:21;;13463:15:::1;13512:37:::0;13463:15;13512:37;13481:21;13520:10;13512:37;::::1;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;13564:33:26::1;::::0;;13577:10:::1;21122:74:34::0;;21227:2;21212:18;;21205:34;;;13564:33:26::1;::::0;21095:18:34;13564:33:26::1;20948:297:34::0;6933:427:12;965:10:18;7026:4:12;4460:18;;;:11;:18;;;;;;;;;:27;;;;;;;;;;7026:4;;965:10:18;7170:15:12;7150:16;:35;;7142:85;;;;-1:-1:-1;;;7142:85:12;;21452:2:34;7142:85:12;;;21434:21:34;21491:2;21471:18;;;21464:30;21530:34;21510:18;;;21503:62;21601:7;21581:18;;;21574:35;21626:19;;7142:85:12;21250:401:34;7142:85:12;7261:60;7270:5;7277:7;7305:15;7286:16;:34;7261:8;:60::i;9075:219:26:-;2365:4:2;2798:16;2365:4;2798:10;:16::i;:::-;9189:45:26::1;:10;9213:9:::0;9224;9189:23:::1;:45::i;:::-;9249:38;::::0;;19236:25:34;;;19292:2;19277:18;;19270:34;;;9249:38:26::1;::::0;19209:18:34;9249:38:26::1;19004:306:34::0;4098:189:12;4177:4;965:10:18;4231:28:12;965:10:18;4248:2:12;4252:6;4231:9;:28::i;7075:450:26:-;7156:21;;;;;;7259:27;:15;7278:7;7259:18;:27::i;:::-;7221:65;;7317:18;:9;1467:12:28;;;;1371:115;7317:18:26;1585:8:28;;;;;;;1635:15:30;;;;7408:44:26;:9;7436:15;7408:27;:44::i;:::-;7466:42;:9;7494:13;7466:27;:42::i;:::-;7296:222;;;;-1:-1:-1;7296:222:26;;-1:-1:-1;7296:222:26;-1:-1:-1;7296:222:26;;-1:-1:-1;7075:450:26;-1:-1:-1;;;7075:450:26:o;6155:107::-;6208:9;6236:19;:10;2084:18:31;;1967:143;10236:159:26;2365:4:2;2798:16;2365:4;2798:10;:16::i;:::-;10323:29:26::1;:17;10348:3:::0;680:16:33;;599:104;10323:29:26::1;10367:21;::::0;2701:25:34;;;10367:21:26::1;::::0;2689:2:34;2674:18;10367:21:26::1;2555:177:34::0;2110:140:1;2190:7;2216:18;;;:12;:18;;;;;:27;;:25;:27::i;9501:155:26:-;2180:24;2798:16:2;2809:4;2798:10;:16::i;:::-;9574:38:26::1;:21;9607:4;9574:32;:38::i;:::-;9627:22;::::0;::::1;::::0;;;::::1;9501:155:::0;:::o;5705:147:2:-;4929:7;4955:12;;;:6;:12;;;;;:22;;;2798:16;2809:4;2798:10;:16::i;:::-;5819:26:::1;5831:4;5837:7;5819:11;:26::i;7788:312:26:-:0;7841:4;7847:5;7854:21;7877:7;7917:31;:21;1467:12:28;;;;1371:115;7917:31:26;7962:21;1371:14:32;;;;;;8008:21:26;1585:8:28;;;;;;1635:15:30;;7896:197:26;;;;;;;;7788:312;;;;:::o;3050:213:2:-;3135:4;3158:58;;;3173:43;3158:58;;:98;;-1:-1:-1;1204:36:21;1189:51;;;;3220:36:2;1081:166:21;10815:340:12;10916:19;;;10908:68;;;;-1:-1:-1;;;10908:68:12;;21858:2:34;10908:68:12;;;21840:21:34;21897:2;21877:18;;;21870:30;21936:34;21916:18;;;21909:62;22007:6;21987:18;;;21980:34;22031:19;;10908:68:12;21656:400:34;10908:68:12;10994:21;;;10986:68;;;;-1:-1:-1;;;10986:68:12;;22263:2:34;10986:68:12;;;22245:21:34;22302:2;22282:18;;;22275:30;22341:34;22321:18;;;22314:62;22412:4;22392:18;;;22385:32;22434:19;;10986:68:12;22061:398:34;10986:68:12;11065:18;;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;11116:32;;2701:25:34;;;11116:32:12;;2674:18:34;11116:32:12;;;;;;;10815:340;;;:::o;1782:179:31:-;1873:22;1914:4;:11;;1943:9;1914:40;;;;;;;;:::i;:::-;;;;;;;;;;;1907:47;;1782:179;;;;:::o;2119:210:30:-;2251:7;2277:45;:21;;;2302:19;2277:24;:45::i;3789:103:2:-;3855:30;3866:4;965:10:18;3855::2;:30::i;996:186:16:-;1116:58;;;21152:42:34;21140:55;;1116:58:16;;;21122:74:34;21212:18;;;;21205:34;;;1116:58:16;;;;;;;;;;21095:18:34;;;;1116:58:16;;;;;;;;;;1139:23;1116:58;;;1089:86;;1109:5;;1089:19;:86::i;2385:149:31:-;2464:18;;2452:48;;:4;;2464:22;;2485:1;;2464:22;:::i;:::-;2452:35;;;;;;;;:::i;:::-;;;;;;;;;;;:46;:48::i;:::-;2510:17;;:4;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;2385:149;:::o;5923:132:26:-;3459:29:2;;;5988:4:26;3459:29:2;;;:12;;:29;:12;:29;;;;;6011:37:26;3350:145:2;1897:216:30;2047:5;2071:35;:21;;;2099:6;2071:27;:35::i;6061:88:26:-;-1:-1:-1;6138:4:26;;6061:88::o;11436:411:12:-;4460:18;;;;11536:24;4460:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;11622:17;11602:37;;11598:243;;11683:6;11663:16;:26;;11655:68;;;;-1:-1:-1;;;11655:68:12;;23177:2:34;11655:68:12;;;23159:21:34;23216:2;23196:18;;;23189:30;23255:31;23235:18;;;23228:59;23304:18;;11655:68:12;22975:353:34;11655:68:12;11765:51;11774:5;11781:7;11809:6;11790:16;:25;11765:8;:51::i;7814:788::-;7910:18;;;7902:68;;;;-1:-1:-1;;;7902:68:12;;23535:2:34;7902:68:12;;;23517:21:34;23574:2;23554:18;;;23547:30;23613:34;23593:18;;;23586:62;23684:7;23664:18;;;23657:35;23709:19;;7902:68:12;23333:401:34;7902:68:12;7988:16;;;7980:64;;;;-1:-1:-1;;;7980:64:12;;23941:2:34;7980:64:12;;;23923:21:34;23980:2;23960:18;;;23953:30;24019:34;23999:18;;;23992:62;24090:5;24070:18;;;24063:33;24113:19;;7980:64:12;23739:399:34;7980:64:12;8055:38;8076:4;8082:2;8086:6;8055:20;:38::i;:::-;8126:15;;;8104:19;8126:15;;;:9;:15;;;;;;8159:21;;;;8151:72;;;;-1:-1:-1;;;8151:72:12;;24345:2:34;8151:72:12;;;24327:21:34;24384:2;24364:18;;;24357:30;24423:34;24403:18;;;24396:62;24494:8;24474:18;;;24467:36;24520:19;;8151:72:12;24143:402:34;8151:72:12;8257:15;;;;;;;;:9;:15;;;;;;8275:20;;;8257:38;;8472:13;;;;;;;;;;:23;;;;;;8521:26;;;;;;8289:6;2701:25:34;;2689:2;2674:18;;2555:177;8521:26:12;;;;;;;;8558:37;8578:4;8584:2;8588:6;8558:19;:37::i;3580:139:30:-;3677:35;:21;;;3703:8;3677:25;:35::i;2338:166:1:-;2425:31;2442:4;2448:7;2425:16;:31::i;:::-;2466:18;;;;:12;:18;;;;;:31;;2489:7;2466:22;:31::i;2177:504:28:-;2305:4;2311:11;;1222:12;;;;:30;;;;;;;;:::i;:::-;;1218:130;;1308:12;;1275:62;;;;;;;1308:12;;;1322:14;;1275:62;;;:::i;1218:130::-;2341:8;;::::1;::::0;::::1;:22;:8;:22:::0;2334:30:::1;;;;:::i;:::-;2381:11;::::0;::::1;::::0;:16;2374:24:::1;;;;:::i;:::-;2412:17;::::0;::::1;2408:89;;2452:34;;;;;;;;;;;;;;2408:89;2510:6;2520:1;2510:11:::0;2506:74:::1;;2544:25;;;;;;;;;;;;;;2506:74;-1:-1:-1::0;;2589:31:28;;2604:16:::1;2630:14;::::0;;;::::1;;;::::0;;;;;;;;;2654:11;::::1;:20:::0;2177:504::o;2593:171:1:-;2681:32;2699:4;2705:7;2681:17;:32::i;:::-;2723:18;;;;:12;:18;;;;;:34;;2749:7;2723:25;:34::i;4761:85:26:-;2365:4:2;2798:16;2365:4;2798:10;:16::i;2841:944:7:-;839:66;3257:59;;;3253:526;;;3332:37;3351:17;3332:18;:37::i;3253:526::-;3433:17;3404:61;;;:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3404:63:7;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;3400:302;;3631:56;;-1:-1:-1;;;3631:56:7;;25244:2:34;3631:56:7;;;25226:21:34;25283:2;25263:18;;;25256:30;25322:34;25302:18;;;25295:62;25393:16;25373:18;;;25366:44;25427:19;;3631:56:7;25042:410:34;3400:302:7;1180:66;3517:28;;3509:82;;;;-1:-1:-1;;;3509:82:7;;25659:2:34;3509:82:7;;;25641:21:34;25698:2;25678:18;;;25671:30;25737:34;25717:18;;;25710:62;25808:11;25788:18;;;25781:39;25837:19;;3509:82:7;25457:405:34;3509:82:7;3468:138;3715:53;3733:17;3752:4;3758:9;3715:17;:53::i;3485:209:32:-;3582:15;;;:28;;;3638:1;3624:15;;;3620:68;;3655:22;:4;3671:5;3655:15;:22::i;2697:117:11:-;1750:16;:14;:16::i;:::-;2755:7:::1;:15:::0;;;::::1;::::0;;2785:22:::1;965:10:18::0;2794:12:11::1;2785:22;::::0;2222:42:34;2210:55;;;2192:74;;2180:2;2165:18;2785:22:11::1;;;;;;;2697:117::o:0;2735:390:32:-;2829:8;2825:260;;;2865:10;;;;;2857:33;2865:10;2853:112;;2917:33;;;;;;;;;;;;;;2853:112;2982:4;:15;;;3001:1;2982:20;2978:97;;3029:31;;;;;;;;;;;;;;2978:97;3094:24;;;;;;;;;;2735:390::o;751:75:1:-;5374:13:9;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:9;;26069:2:34;5366:69:9;;;26051:21:34;26108:2;26088:18;;;26081:30;26147:34;26127:18;;;26120:62;26218:13;26198:18;;;26191:41;26249:19;;5366:69:9;25867:407:34;5366:69:9;751:75:1:o;2139:147:12:-;5374:13:9;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:9;;26069:2:34;5366:69:9;;;26051:21:34;26108:2;26088:18;;;26081:30;26147:34;26127:18;;;26120:62;26218:13;26198:18;;;26191:41;26249:19;;5366:69:9;25867:407:34;5366:69:9;2241:38:12::1;2264:5;2271:7;2241:22;:38::i;1084:97:11:-:0;5374:13:9;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:9;;26069:2:34;5366:69:9;;;26051:21:34;26108:2;26088:18;;;26081:30;26147:34;26127:18;;;26120:62;26218:13;26198:18;;;26191:41;26249:19;;5366:69:9;25867:407:34;5366:69:9;1147:27:11::1;:25;:27::i;7523:247:2:-:0;7606:25;4955:12;;;:6;:12;;;;;;:22;;;;7662:34;;;;7711:52;;4955:22;;7662:34;;4955:22;;:12;;7711:52;;7606:25;7711:52;7596:174;7523:247;;:::o;510:201:29:-;624:25;668:4;:11;;695:7;668:36;;;;;;;;:::i;:::-;;;;;;;;;;;661:43;;510:201;;;;:::o;1530:1199:32:-;1651:13;;;;1646:51;;1530:1199;;;:::o;1646:51::-;1721:10;;;;;1713:33;1721:10;1706:41;;;;:::i;:::-;1786:14;;1761:21;;;;;;;;1786:14;;;;;;;1761:10;;;;;:19;;:21;;;;;;;;;;;;;;:10;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:39;;;1757:152;;1860:4;:10;;;;;;;;;;;;:19;;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1883:14;;1823:75;;;;;1883:14;26741:17:34;;;1823:75:32;;;26723:36:34;1883:14:32;;;;;;;26775:18:34;;;26768:45;26696:18;;1823:75:32;26557:262:34;1757:152:32;1972:21;1997:17;2020:4;:10;;;;;;;;;;;;:26;;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1969:79;;;;;;;2080:1;2062:14;:19;2058:126;;2104:69;;;;;;;;2701:25:34;;;2674:18;;2104:69:32;2555:177:34;2058:126:32;2220:14;2261:15;2249:27;;2245:137;;;2299:72;;;;;;;;19236:25:34;;;2355:15:32;19277:18:34;;;19270:34;19209:18;;2299:72:32;19004:306:34;2245:137:32;2425:15;2407:4;:15;;;2395:9;:27;;;;:::i;:::-;:45;2391:169;;;2516:15;;;;2504:27;;:9;:27;:::i;:::-;2463:86;;;;;;;;19236:25:34;;;;2533:15:32;19277:18:34;;;19270:34;19209:18;;2463:86:32;19004:306:34;2391:169:32;2596:8;2573:20;2587:6;2573:11;:20;:::i;:::-;:31;2569:154;;;2681:20;2695:6;2681:11;:20;:::i;:::-;2627:85;;;;;;;;19236:25:34;;;;19277:18;;;19270:34;;;19209:18;;2627:85:32;19004:306:34;2569:154:32;1636:1093;;;1530:1199;;;:::o;2858:462:28:-;3029:4;3035:16;;1222:12;;;;:30;;;;;;;;:::i;:::-;;1218:130;;1308:12;;1275:62;;;;;;;1308:12;;;1322:14;;1275:62;;;:::i;1218:130::-;3067:57:::1;:37;:23;::::0;::::1;3097:6:::0;3067:29:::1;:37::i;:::-;3107:17;-1:-1:-1::0;410:40:27;340:113;3067:57:28::1;3063:195;;;3190:37;:23;::::0;::::1;3220:6:::0;3190:29:::1;:37::i;:::-;3147:100;::::0;::::1;::::0;;::::1;::::0;::::1;19236:25:34::0;;;;19277:18;;;19270:34;;;19209:18;;3147:100:28::1;19004:306:34::0;3063:195:28::1;-1:-1:-1::0;;3267:46:28;;;::::1;3282:31;3267:46;::::0;;;-1:-1:-1;;2858:462:28:o;3165:409:30:-;3266:4;:11;;;3251:4;:11;;;:26;;3244:34;;;;:::i;:::-;3301:4;:15;;;3292:6;:24;3288:126;;;3387:15;;;;3339:64;;;;;;;3379:6;;3339:64;;19236:25:34;;;19292:2;19277:18;;19270:34;19224:2;19209:18;;19004:306;3288:126:30;3436:4;:11;;;3427:6;:20;3423:114;;;3514:11;;;;3470:56;;;;;;;3506:6;;3470:56;;19236:25:34;;;19292:2;19277:18;;19270:34;19224:2;19209:18;;19004:306;3423:114:30;3561:6;3546:4;:11;;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;3165:409:30:o;8878:535:12:-;8961:21;;;8953:65;;;;-1:-1:-1;;;8953:65:12;;28426:2:34;8953:65:12;;;28408:21:34;28465:2;28445:18;;;28438:30;28504:33;28484:18;;;28477:61;28555:18;;8953:65:12;28224:355:34;8953:65:12;9029:49;9058:1;9062:7;9071:6;9029:20;:49::i;:::-;9105:6;9089:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;9257:18:12;;;;;;;:9;:18;;;;;;;;:28;;;;;;9310:37;2701:25:34;;;9310:37:12;;2674:18:34;9310:37:12;;;;;;;9358:48;9386:1;9390:7;9399:6;9358:19;:48::i;2687:165:28:-;2774:4;2780:16;;1222:12;;;;:30;;;;;;;;:::i;:::-;;1218:130;;1308:12;;1275:62;;;;;;;1308:12;;;1322:14;;1275:62;;;:::i;1218:130::-;2808:37:::1;:23;::::0;::::1;2836:8:::0;2808:27:::1;:37::i;3131:216:32:-:0;3232:18;;;;;;;;;;;;;;;;;3260:81;;3308:22;:4;3324:5;3308:15;:22::i;578:130:31:-;631:9;674:26;699:1;691:4;674:26;:::i;3990:755::-;-1:-1:-1;;;4102:73:31;;;;;4142:33;:25;4150:16;:9;:14;:16::i;:::-;4142:4;;:7;:25::i;:::-;1756:11:30;;;;1663:111;4142:33:31;4134:5;:41;4102:73;4098:187;;;4233:5;4240:33;:25;4248:16;:9;:14;:16::i;:::-;4240:4;;:7;:25::i;:33::-;4198:76;;;;;;;;19236:25:34;;;;19277:18;;;19270:34;19209:18;;4198:76:31;19004:306:34;4098:187:31;4298:32;:16;:9;:14;:16::i;:::-;2084:18;;4317:13;-1:-1:-1;410:40:27;340:113;4298:32:31;:77;;;;;4342:33;:25;4350:16;:9;:14;:16::i;4342:33::-;4334:5;:41;4298:77;4294:190;;;4432:5;4439:33;:25;4447:16;:9;:14;:16::i;4439:33::-;4398:75;;;;;;;;19236:25:34;;;;19277:18;;;19270:34;19209:18;;4398:75:31;19004:306:34;4294:190:31;4497:32;:16;:9;:14;:16::i;:32::-;:81;;;;;4541:37;:25;4549:16;:9;:14;:16::i;4541:25::-;1635:15:30;;;;1538:119;4541:37:31;4533:5;:45;4497:81;4493:202;;;4639:5;4646:37;:25;4654:16;:9;:14;:16::i;4646:37::-;4601:83;;;;;;;;19236:25:34;;;;19277:18;;;19270:34;19209:18;;4601:83:31;19004:306:34;4493:202:31;4704:34;4732:5;4704:18;:4;4712:9;4704:7;:18::i;:::-;:27;;:34::i;3326:153:28:-;3394:4;3400:16;;1222:12;;;;:30;;;;;;;;:::i;:::-;;1218:130;;1308:12;;1275:62;;;;;;;1308:12;;;1322:14;;1275:62;;;:::i;1218:130::-;-1:-1:-1;;3428:44:28;;;::::1;3443:29;3428:44;::::0;;3326:153::o;2450:115:11:-;1503:19;:17;:19::i;:::-;2509:7:::1;:14:::0;;;::::1;2519:4;2509:14;::::0;;2538:20:::1;2545:12;965:10:18::0;;886:96;2540:622:31;-1:-1:-1;;;2660:83:31;;;;;2692:51;:10;2705:38;:25;2713:16;:9;:14;:16::i;:::-;2705:4;;:7;:25::i;:::-;1509:16:30;;1413:119;2692:51:31;2656:217;;;2811:10;2823:38;:25;2831:16;:9;:14;:16::i;2823:38::-;2766:96;;;;;;;;19236:25:34;;;;19277:18;;;19270:34;19209:18;;2766:96:31;19004:306:34;2656:217:31;2886:32;:16;:9;:14;:16::i;:32::-;:87;;;;;2922:51;:10;2935:38;:25;2943:16;:9;:14;:16::i;2935:38::-;-1:-1:-1;440:48:31;362:129;2922:51;2882:220;;;3040:10;3052:38;:25;3060:16;:9;:14;:16::i;3052:38::-;2996:95;;;;;;;;19236:25:34;;;;19277:18;;;19270:34;19209:18;;2996:95:31;19004:306:34;2882:220:31;3111:44;3144:10;3111:18;:4;3119:9;3111:7;:18::i;:::-;:32;;:44::i;1950:221:28:-;2089:7;2115:49;:23;;;2142:21;2115:26;:49::i;9574:156:25:-;9648:7;9698:22;9702:3;9714:5;9698:3;:22::i;2116:263:31:-;2214:18;;;;;;;2184:27;2214:18;;;;;;;;;;;2242:32;2214:18;;2242:13;:32::i;:::-;2284:36;:4;2302:17;2284;:36::i;:::-;2330:42;:4;1526:1:27;2330:18:31;:42::i;3168:816::-;-1:-1:-1;;;3288:81:31;;;;;3332:37;:25;3340:16;:9;:14;:16::i;3332:37::-;3320:9;:49;3288:81;3284:211;;;3435:9;3446:37;:25;3454:16;:9;:14;:16::i;3446:37::-;3392:92;;;;;;;;19236:25:34;;;;19277:18;;;19270:34;19209:18;;3392:92:31;19004:306:34;3284:211:31;-1:-1:-1;;;3508:77:31;;;;;3552:33;:25;3560:16;:9;:14;:16::i;3552:33::-;3540:9;:45;3508:77;3504:199;;;3647:9;3658:33;:25;3666:16;:9;:14;:16::i;3658:33::-;3608:84;;;;;;;;19236:25:34;;;;19277:18;;;19270:34;19209:18;;3608:84:31;19004:306:34;3504:199:31;3716:32;:16;:9;:14;:16::i;:32::-;:85;;;;;3764:37;:25;3772:16;:9;:14;:16::i;3764:37::-;3752:9;:49;3716:85;3712:214;;;3866:9;3877:37;:25;3885:16;:9;:14;:16::i;3877:37::-;3824:91;;;;;;;;19236:25:34;;;;19277:18;;;19270:34;19209:18;;3824:91:31;19004:306:34;3712:214:31;3935:42;3967:9;3935:18;:4;3943:9;3935:7;:18::i;:::-;:31;;:42::i;714:130::-;767:9;810:26;827:4;835:1;810:26;:::i;3725:728:30:-;4848:25;;;3911:74;;3952:22;;;;;;;;;;;;;;3911:74;3998:55;:35;:21;;;4026:6;3998:27;:35::i;:::-;4036:17;;-1:-1:-1;410:40:27;340:113;3998:55:30;3994:191;;;4119:35;:21;;;4147:6;4119:27;:35::i;:::-;4156:17;;4076:98;;;;;;;;19236:25:34;;;;19277:18;;;19270:34;19209:18;;4076:98:30;19004:306:34;3994:191:30;4194:33;:4;:21;;:31;:33::i;:::-;4260:4;:11;;;4245:4;:11;;;:26;;4238:34;;;;:::i;:::-;4282:20;4319:4;:11;;;4305:4;:11;;;:25;;;;:::i;:::-;4282:48;-1:-1:-1;4340:25:30;:5;4282:48;4340:11;:25::i;:::-;4390:12;4375:4;:11;;;:27;;;;;;;:::i;:::-;;;;-1:-1:-1;;4434:11:30;;;;4419;;;;:26;4412:34;;;;:::i;9733:659:12:-;9816:21;;;9808:67;;;;-1:-1:-1;;;9808:67:12;;28786:2:34;9808:67:12;;;28768:21:34;28825:2;28805:18;;;28798:30;28864:34;28844:18;;;28837:62;28935:3;28915:18;;;28908:31;28956:19;;9808:67:12;28584:397:34;9808:67:12;9886:49;9907:7;9924:1;9928:6;9886:20;:49::i;:::-;9971:18;;;9946:22;9971:18;;;:9;:18;;;;;;10007:24;;;;9999:71;;;;-1:-1:-1;;;9999:71:12;;29188:2:34;9999:71:12;;;29170:21:34;29227:2;29207:18;;;29200:30;29266:34;29246:18;;;29239:62;29337:4;29317:18;;;29310:32;29359:19;;9999:71:12;28986:398:34;9999:71:12;10104:18;;;;;;;:9;:18;;;;;;;;10125:23;;;10104:44;;10241:12;:22;;;;;;;10289:37;2701:25:34;;;10104:18:12;;;10289:37;;2674:18:34;10289:37:12;;;;;;;10337:48;10357:7;10374:1;10378:6;10337:19;:48::i;1726:218:28:-;1876:5;1900:37;:23;;;1930:6;1900:29;:37::i;599:104:33:-;680:16;;599:104::o;9117:115:25:-;9180:7;9206:19;9214:3;2084:18:31;;1967:143;1713:142:27;1780:7;1806:42;:4;1840:6;1806:20;:42::i;4173:501:2:-;3436:4;3459:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;4256:412;;4444:39;4475:7;4444:30;:39::i;:::-;4554:49;4593:4;4600:2;4554:30;:49::i;:::-;4351:274;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;-1:-1:-1;;;4299:358:2;;;;;;;:::i;5328:653:16:-;5758:23;5784:69;5812:4;5784:69;;;;;;;;;;;;;;;;;5792:5;5784:27;;;;:69;;;;;:::i;:::-;5758:95;;5871:10;:17;5892:1;5871:22;:56;;;;5908:10;5897:30;;;;;;;;;;;;:::i;:::-;5863:111;;;;-1:-1:-1;;;5863:111:16;;30690:2:34;5863:111:16;;;30672:21:34;30729:2;30709:18;;;30702:30;30768:34;30748:18;;;30741:62;30839:12;30819:18;;;30812:40;30869:19;;5863:111:16;30488:406:34;4570:108:30;4638:33;:4;:21;;:31;:33::i;1861:425:27:-;1963:5;;1997:26;:4;:24;:26::i;:::-;1980:43;;2040:31;2051:6;1526:1;-1:-1:-1;526:41:27;;455:115;2040:31;2033:39;;;;:::i;:::-;2082:14;2115:9;2110:135;2130:6;2126:1;:10;2110:135;;;2161:31;2168:23;:4;2189:1;2168:20;:23::i;:::-;2161:6;:31;;:::i;:::-;2157:78;;;2212:8;;;;:::i;:::-;;;;2157:78;2138:3;;;;:::i;:::-;;;;2110:135;;;-1:-1:-1;2272:6:27;1861:425;-1:-1:-1;;;;1861:425:27:o;5021:411:26:-;5159:10;2365:4:2;3459:29;;;:12;;:29;:12;:29;;;;;5127:76:26;;;5021:411;;;:::o;5127:76::-;5212:19;:17;:19::i;:::-;3459:29:2;;;3436:4;3459:29;;;:12;;:29;:12;:29;;;;;5241:90:26;;;5294:26;;;;;2222:42:34;2210:55;;5294:26:26;;;2192:74:34;2165:18;;5294:26:26;2046:226:34;5241:90:26;3459:29:2;;;3436:4;3459:29;;;:12;;:29;:12;:29;;;;;5340:86:26;;;5391:24;;;;;2222:42:34;2210:55;;5391:24:26;;;2192:74:34;2165:18;;5391:24:26;2046:226:34;5438:479:26;5544:16;;;;;;;:66;;-1:-1:-1;2561:8:26;5564:46;;;;;5544:66;5540:371;;;5626:39;2416:36;5662:2;5626:10;:39::i;:::-;5683:13;2490:8;5683:6;:13;:::i;:::-;:18;5679:98;;5728:34;;;;;;;;2701:25:34;;;2674:18;;5728:34:26;2555:177:34;5679:98:26;5790:41;:17;5824:6;5790:33;:41::i;:::-;5846:17;5852:2;5856:6;5846:5;:17::i;:::-;5882:18;;;21152:42:34;21140:55;;21122:74;;21227:2;21212:18;;21205:34;;;5882:18:26;;21095::34;5882::26;20948:297:34;2292:305:27;2364:51;2375:26;:4;:24;:26::i;:::-;1526:1;-1:-1:-1;759:41:27;;688:115;2364:51;2360:115;;;2438:26;;;;;;;;;;;;;;2360:115;2489:31;:4;2511:8;2489:21;:31::i;:::-;2484:107;;2543:37;;;;;2222:42:34;2210:55;;2543:37:27;;;2192:74:34;2165:18;;2543:37:27;2046:226:34;7938:233:2;3436:4;3459:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;8016:149;;8059:12;;;;:6;:12;;;;;;;;:29;;;;;;;;;;:36;;;;8091:4;8059:36;;;8141:12;965:10:18;;886:96;8141:12:2;8114:40;;8132:7;8114:40;;8126:4;8114:40;;;;;;;;;;7938:233;;:::o;8316:150:25:-;8386:4;8409:50;8414:3;8434:23;;;8409:4;:50::i;8342:234:2:-;3436:4;3459:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;8421:149;;;8495:5;8463:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;:37;;;;;;8519:40;965:10:18;;8463:12:2;;8519:40;;8495:5;8519:40;8342:234;;:::o;8634:156:25:-;8707:4;8730:53;8738:3;8758:23;;;8730:7;:53::i;1720:281:7:-;1713:19:17;;;;1793:106:7;;;;-1:-1:-1;;;1793:106:7;;31301:2:34;1793:106:7;;;31283:21:34;31340:2;31320:18;;;31313:30;31379:34;31359:18;;;31352:62;31450:15;31430:18;;;31423:43;31483:19;;1793:106:7;31099:409:34;1793:106:7;1180:66;1909:85;;;;;;;;;;;;;;;1720:281::o;2393:276::-;2501:29;2512:17;2501:10;:29::i;:::-;2558:1;2544:4;:11;:15;:28;;;;2563:9;2544:28;2540:123;;;2588:64;2628:17;2647:4;2588:39;:64::i;2209:106:11:-;1949:7;;;;2267:41;;;;-1:-1:-1;;;2267:41:11;;31715:2:34;2267:41:11;;;31697:21:34;31754:2;31734:18;;;31727:30;31793:22;31773:18;;;31766:50;31833:18;;2267:41:11;31513:344:34;2292:159:12;5374:13:9;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:9;;26069:2:34;5366:69:9;;;26051:21:34;26108:2;26088:18;;;26081:30;26147:34;26127:18;;;26120:62;26218:13;26198:18;;;26191:41;26249:19;;5366:69:9;25867:407:34;5366:69:9;2404:5:12::1;:13;2412:5:::0;2404;:13:::1;:::i;:::-;-1:-1:-1::0;2427:7:12::1;:17;2437:7:::0;2427;:17:::1;:::i;1187:95:11:-:0;5374:13:9;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:9;;26069:2:34;5366:69:9;;;26051:21:34;26108:2;26088:18;;;26081:30;26147:34;26127:18;;;26120:62;26218:13;26198:18;;;26191:41;26249:19;;5366:69:9;25867:407:34;5366:69:9;1260:7:11::1;:15:::0;;;::::1;::::0;;1187:95::o;2867:292:30:-;1635:15;;;;2953:6;:25;2949:110;;;1635:15;;;;3001:47;;;;;;;;19236:25:34;;;;19277:18;;;19270:34;;;19209:18;;3001:47:30;19004:306:34;2949:110:30;3068:11;;;:20;;;3132:11;;;;3112:40;;3082:6;3112:19;:40::i;:::-;3098:4;:11;;:54;;;;2867:292;;:::o;2031:106:11:-;1949:7;;;;2100:9;2092:38;;;;-1:-1:-1;;;2092:38:11;;34447:2:34;2092:38:11;;;34429:21:34;34486:2;34466:18;;;34459:30;34525:18;34505;;;34498:46;34561:18;;2092:38:11;34245:340:34;2335:276:30;2429:36;:11;1526:1:27;-1:-1:-1;440:48:31;362:129;2429:36:30;2425:140;;;2488:66;;;;;;;;19236:25:34;;;1526:1:27;19277:18:34;;;19270:34;19209:18;;2488:66:30;19004:306:34;4923:118:25;4990:7;5016:3;:11;;5028:5;5016:18;;;;;;;;:::i;:::-;;;;;;;;;5009:25;;4923:118;;;;:::o;2617:244:30:-;1756:11;;;;2711:10;:25;2707:110;;;2781:10;2793:12;:4;1756:11;;;;1663:111;2793:12;2759:47;;;;;;;;19236:25:34;;;;19277:18;;;19270:34;19209:18;;2759:47:30;19004:306:34;2707:110:30;2826:15;;;;:28;2617:244::o;2603:205:27:-;2664:9;2676:26;:4;:24;:26::i;:::-;2664:38;;2659:143;2704:5;;2659:143;;2737:53;2762:27;2783:5;2787:1;2783;:5;:::i;:::-;2762:4;;:20;:27::i;:::-;2737:4;;:24;:53::i;:::-;2730:61;;;;:::i;:::-;2711:3;;;;:::i;:::-;;;;2659:143;;2473:149:20;2531:13;2563:52;2575:22;;;376:2;1884:437;1959:13;1984:19;2016:10;2020:6;2016:1;:10;:::i;:::-;:14;;2029:1;2016:14;:::i;:::-;2006:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2006:25:20;;1984:47;;2041:15;:6;2048:1;2041:9;;;;;;;;:::i;:::-;;;;:15;;;;;;;;;;;2066;:6;2073:1;2066:9;;;;;;;;:::i;:::-;;;;:15;;;;;;;;;;-1:-1:-1;2096:9:20;2108:10;2112:6;2108:1;:10;:::i;:::-;:14;;2121:1;2108:14;:::i;:::-;2096:26;;2091:128;2128:1;2124;:5;2091:128;;;2162:8;2171:5;2179:3;2171:11;2162:21;;;;;;;:::i;:::-;;;;2150:6;2157:1;2150:9;;;;;;;;:::i;:::-;;;;:33;;;;;;;;;;-1:-1:-1;2207:1:20;2197:11;;;;;2131:3;;;:::i;:::-;;;2091:128;;;-1:-1:-1;2236:10:20;;2228:55;;;;-1:-1:-1;;;2228:55:20;;35166:2:34;2228:55:20;;;35148:21:34;;;35185:18;;;35178:30;35244:34;35224:18;;;35217:62;35296:18;;2228:55:20;34964:356:34;4119:223:17;4252:12;4283:52;4305:6;4313:4;4319:1;4322:12;4283:21;:52::i;:::-;4276:59;4119:223;-1:-1:-1;;;;4119:223:17:o;388:205:33:-;498:9;;489:18;;485:102;;;566:9;;530:46;;;;;;;558:6;;530:46;;19236:25:34;;;19292:2;19277:18;;19270:34;19224:2;19209:18;;19004:306;2225:404:25;2288:4;4362:19;;;:12;;;:19;;;;;;2304:319;;-1:-1:-1;2346:23:25;;;;;;;;:11;:23;;;;;;;;;;;;;2526:18;;2504:19;;;:12;;;:19;;;;;;:40;;;;2558:11;;2304:319;-1:-1:-1;2607:5:25;2600:12;;2797:1388;2863:4;3000:19;;;:12;;;:19;;;;;;3034:15;;3030:1149;;3403:21;3427:14;3440:1;3427:10;:14;:::i;:::-;3475:18;;3403:38;;-1:-1:-1;3455:17:25;;3475:22;;3496:1;;3475:22;:::i;:::-;3455:42;;3529:13;3516:9;:26;3512:398;;3562:17;3582:3;:11;;3594:9;3582:22;;;;;;;;:::i;:::-;;;;;;;;;3562:42;;3733:9;3704:3;:11;;3716:13;3704:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;3816:23;;;:12;;;:23;;;;;:36;;;3512:398;3988:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;4080:3;:12;;:19;4093:5;4080:19;;;;;;;;;;;4073:26;;;4121:4;4114:11;;;;;;;3030:1149;4163:5;4156:12;;;;;2107:152:7;2173:37;2192:17;2173:18;:37::i;:::-;2225:27;;;;;;;;;;;2107:152;:::o;6685:198:17:-;6768:12;6799:77;6820:6;6828:4;6799:77;;;;;;;;;;;;;;;;;:20;:77::i;599:104:23:-;657:7;687:1;683;:5;:13;;695:1;683:13;;;-1:-1:-1;691:1:23;;599:104;-1:-1:-1;599:104:23:o;5176:446:17:-;5341:12;5398:5;5373:21;:30;;5365:81;;;;-1:-1:-1;;;5365:81:17;;35527:2:34;5365:81:17;;;35509:21:34;35566:2;35546:18;;;35539:30;35605:34;35585:18;;;35578:62;35676:8;35656:18;;;35649:36;35702:19;;5365:81:17;35325:402:34;5365:81:17;5457:12;5471:23;5498:6;:11;;5517:5;5524:4;5498:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5456:73;;;;5546:69;5573:6;5581:7;5590:10;5602:12;5546:26;:69::i;:::-;5539:76;5176:446;-1:-1:-1;;;;;;;5176:446:17:o;7069:325::-;7210:12;7235;7249:23;7276:6;:19;;7296:4;7276:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7234:67;;;;7318:69;7345:6;7353:7;7362:10;7374:12;7318:26;:69::i;:::-;7311:76;7069:325;-1:-1:-1;;;;;;7069:325:17:o;7682:628::-;7862:12;7890:7;7886:418;;;7917:10;:17;7938:1;7917:22;7913:286;;1713:19;;;;8124:60;;;;-1:-1:-1;;;8124:60:17;;36226:2:34;8124:60:17;;;36208:21:34;36265:2;36245:18;;;36238:30;36304:31;36284:18;;;36277:59;36353:18;;8124:60:17;36024:353:34;8124:60:17;-1:-1:-1;8219:10:17;8212:17;;7886:418;8260:33;8268:10;8280:12;8991:17;;:21;8987:379;;9219:10;9213:17;9275:15;9262:10;9258:2;9254:19;9247:44;8987:379;9342:12;9335:20;;-1:-1:-1;;;9335:20:17;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:332:34:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;180:9;167:23;230:66;223:5;219:78;212:5;209:89;199:117;;312:1;309;302:12;543:250;628:1;638:113;652:6;649:1;646:13;638:113;;;728:11;;;722:18;709:11;;;702:39;674:2;667:10;638:113;;;-1:-1:-1;;785:1:34;767:16;;760:27;543:250::o;798:455::-;947:2;936:9;929:21;910:4;979:6;973:13;1022:6;1017:2;1006:9;1002:18;995:34;1038:79;1110:6;1105:2;1094:9;1090:18;1085:2;1077:6;1073:15;1038:79;:::i;:::-;1169:2;1157:15;1174:66;1153:88;1138:104;;;;1244:2;1134:113;;798:455;-1:-1:-1;;798:455:34:o;1258:154::-;1344:42;1337:5;1333:54;1326:5;1323:65;1313:93;;1402:1;1399;1392:12;1417:315;1485:6;1493;1546:2;1534:9;1525:7;1521:23;1517:32;1514:52;;;1562:1;1559;1552:12;1514:52;1601:9;1588:23;1620:31;1645:5;1620:31;:::i;:::-;1670:5;1722:2;1707:18;;;;1694:32;;-1:-1:-1;;;1417:315:34:o;1737:304::-;1861:6;1869;1922:2;1910:9;1901:7;1897:23;1893:32;1890:52;;;1938:1;1935;1928:12;1890:52;-1:-1:-1;;1961:23:34;;;2031:2;2016:18;;;2003:32;;-1:-1:-1;1737:304:34:o;2277:273::-;2362:6;2415:2;2403:9;2394:7;2390:23;2386:32;2383:52;;;2431:1;2428;2421:12;2383:52;2470:9;2457:23;2489:31;2514:5;2489:31;:::i;3048:210::-;3137:6;3190:2;3178:9;3169:7;3165:23;3161:32;3158:52;;;3206:1;3203;3196:12;3158:52;-1:-1:-1;3229:23:34;;3048:210;-1:-1:-1;3048:210:34:o;3881:456::-;3958:6;3966;3974;4027:2;4015:9;4006:7;4002:23;3998:32;3995:52;;;4043:1;4040;4033:12;3995:52;4082:9;4069:23;4101:31;4126:5;4101:31;:::i;:::-;4151:5;-1:-1:-1;4208:2:34;4193:18;;4180:32;4221:33;4180:32;4221:33;:::i;:::-;3881:456;;4273:7;;-1:-1:-1;;;4327:2:34;4312:18;;;;4299:32;;3881:456::o;4709:315::-;4777:6;4785;4838:2;4826:9;4817:7;4813:23;4809:32;4806:52;;;4854:1;4851;4844:12;4806:52;4890:9;4877:23;4867:33;;4950:2;4939:9;4935:18;4922:32;4963:31;4988:5;4963:31;:::i;:::-;5013:5;5003:15;;;4709:315;;;;;:::o;5865:413::-;5972:6;5980;5988;6041:2;6029:9;6020:7;6016:23;6012:32;6009:52;;;6057:1;6054;6047:12;6009:52;6096:9;6083:23;6115:31;6140:5;6115:31;:::i;:::-;6165:5;6217:2;6202:18;;6189:32;;-1:-1:-1;6268:2:34;6253:18;;;6240:32;;5865:413;-1:-1:-1;;;5865:413:34:o;6283:184::-;6335:77;6332:1;6325:88;6432:4;6429:1;6422:15;6456:4;6453:1;6446:15;6472:691;6537:5;6567:18;6608:2;6600:6;6597:14;6594:40;;;6614:18;;:::i;:::-;6748:2;6742:9;6814:2;6802:15;;6653:66;6798:24;;;6824:2;6794:33;6790:42;6778:55;;;6848:18;;;6868:22;;;6845:46;6842:72;;;6894:18;;:::i;:::-;6934:10;6930:2;6923:22;6963:6;6954:15;;6993:6;6985;6978:22;7033:3;7024:6;7019:3;7015:16;7012:25;7009:45;;;7050:1;7047;7040:12;7009:45;7100:6;7095:3;7088:4;7080:6;7076:17;7063:44;7155:1;7148:4;7139:6;7131;7127:19;7123:30;7116:41;;;;6472:691;;;;;:::o;7168:222::-;7211:5;7264:3;7257:4;7249:6;7245:17;7241:27;7231:55;;7282:1;7279;7272:12;7231:55;7304:80;7380:3;7371:6;7358:20;7351:4;7343:6;7339:17;7304:80;:::i;7395:543::-;7483:6;7491;7544:2;7532:9;7523:7;7519:23;7515:32;7512:52;;;7560:1;7557;7550:12;7512:52;7600:9;7587:23;7629:18;7670:2;7662:6;7659:14;7656:34;;;7686:1;7683;7676:12;7656:34;7709:50;7751:7;7742:6;7731:9;7727:22;7709:50;:::i;:::-;7699:60;;7812:2;7801:9;7797:18;7784:32;7768:48;;7841:2;7831:8;7828:16;7825:36;;;7857:1;7854;7847:12;7825:36;;7880:52;7924:7;7913:8;7902:9;7898:24;7880:52;:::i;:::-;7870:62;;;7395:543;;;;;:::o;7943:585::-;8020:6;8028;8081:2;8069:9;8060:7;8056:23;8052:32;8049:52;;;8097:1;8094;8087:12;8049:52;8136:9;8123:23;8155:31;8180:5;8155:31;:::i;:::-;8205:5;-1:-1:-1;8261:2:34;8246:18;;8233:32;8288:18;8277:30;;8274:50;;;8320:1;8317;8310:12;8274:50;8343:22;;8396:4;8388:13;;8384:27;-1:-1:-1;8374:55:34;;8425:1;8422;8415:12;8374:55;8448:74;8514:7;8509:2;8496:16;8491:2;8487;8483:11;8448:74;:::i;9869:342::-;9972:6;9980;9988;10041:2;10029:9;10020:7;10016:23;10012:32;10009:52;;;10057:1;10054;10047:12;10009:52;-1:-1:-1;;10080:23:34;;;10150:2;10135:18;;10122:32;;-1:-1:-1;10201:2:34;10186:18;;;10173:32;;9869:342;-1:-1:-1;9869:342:34:o;10216:184::-;10268:77;10265:1;10258:88;10365:4;10362:1;10355:15;10389:4;10386:1;10379:15;10405:291;10483:1;10476:5;10473:12;10463:200;;10519:77;10516:1;10509:88;10620:4;10617:1;10610:15;10648:4;10645:1;10638:15;10463:200;10672:18;;10405:291::o;10701:589::-;11008:3;10993:19;;11021:41;10997:9;11044:6;11021:41;:::i;:::-;11110:42;11102:6;11098:55;11093:2;11082:9;11078:18;11071:83;11190:6;11185:2;11174:9;11170:18;11163:34;11233:6;11228:2;11217:9;11213:18;11206:34;11277:6;11271:3;11260:9;11256:19;11249:35;10701:589;;;;;;;;:::o;11997:388::-;12065:6;12073;12126:2;12114:9;12105:7;12101:23;12097:32;12094:52;;;12142:1;12139;12132:12;12094:52;12181:9;12168:23;12200:31;12225:5;12200:31;:::i;:::-;12250:5;-1:-1:-1;12307:2:34;12292:18;;12279:32;12320:33;12279:32;12320:33;:::i;12390:437::-;12469:1;12465:12;;;;12512;;;12533:61;;12587:4;12579:6;12575:17;12565:27;;12533:61;12640:2;12632:6;12629:14;12609:18;12606:38;12603:218;;12677:77;12674:1;12667:88;12778:4;12775:1;12768:15;12806:4;12803:1;12796:15;12603:218;;12390:437;;;:::o;12832:184::-;12902:6;12955:2;12943:9;12934:7;12930:23;12926:32;12923:52;;;12971:1;12968;12961:12;12923:52;-1:-1:-1;12994:16:34;;12832:184;-1:-1:-1;12832:184:34:o;13782:266::-;13814:1;13840;13830:189;;13875:77;13872:1;13865:88;13976:4;13973:1;13966:15;14004:4;14001:1;13994:15;13830:189;-1:-1:-1;14033:9:34;;13782:266::o;15798:184::-;15850:77;15847:1;15840:88;15947:4;15944:1;15937:15;15971:4;15968:1;15961:15;15987:125;16052:9;;;16073:10;;;16070:36;;;16086:18;;:::i;16532:151::-;16622:4;16615:12;;;16601;;;16597:31;;16640:14;;16637:40;;;16657:18;;:::i;16688:482::-;16777:1;16820:5;16777:1;16834:330;16855:7;16845:8;16842:21;16834:330;;;16974:4;16906:66;16902:77;16896:4;16893:87;16890:113;;;16983:18;;:::i;:::-;17033:7;17023:8;17019:22;17016:55;;;17053:16;;;;17016:55;17132:22;;;;17092:15;;;;16834:330;;;16838:3;16688:482;;;;;:::o;17175:866::-;17224:5;17254:8;17244:80;;-1:-1:-1;17295:1:34;17309:5;;17244:80;17343:4;17333:76;;-1:-1:-1;17380:1:34;17394:5;;17333:76;17425:4;17443:1;17438:59;;;;17511:1;17506:130;;;;17418:218;;17438:59;17468:1;17459:10;;17482:5;;;17506:130;17543:3;17533:8;17530:17;17527:43;;;17550:18;;:::i;:::-;-1:-1:-1;;17606:1:34;17592:16;;17621:5;;17418:218;;17720:2;17710:8;17707:16;17701:3;17695:4;17692:13;17688:36;17682:2;17672:8;17669:16;17664:2;17658:4;17655:12;17651:35;17648:77;17645:159;;;-1:-1:-1;17757:19:34;;;17789:5;;17645:159;17836:34;17861:8;17855:4;17836:34;:::i;:::-;17966:6;17898:66;17894:79;17885:7;17882:92;17879:118;;;17977:18;;:::i;:::-;18015:20;;17175:866;-1:-1:-1;;;17175:866:34:o;18046:140::-;18104:5;18133:47;18174:4;18164:8;18160:19;18154:4;18133:47;:::i;18191:184::-;18243:77;18240:1;18233:88;18340:4;18337:1;18330:15;18364:4;18361:1;18354:15;22464:184;22516:77;22513:1;22506:88;22613:4;22610:1;22603:15;22637:4;22634:1;22627:15;22653:128;22720:9;;;22741:11;;;22738:37;;;22755:18;;:::i;22786:184::-;22838:77;22835:1;22828:88;22935:4;22932:1;22925:15;22959:4;22956:1;22949:15;24550:298;24730:2;24715:18;;24742:41;24719:9;24765:6;24742:41;:::i;:::-;24792:50;24838:2;24827:9;24823:18;24815:6;24792:50;:::i;26279:273::-;26347:6;26400:2;26388:9;26379:7;26375:23;26371:32;26368:52;;;26416:1;26413;26406:12;26368:52;26448:9;26442:16;26498:4;26491:5;26487:16;26480:5;26477:27;26467:55;;26518:1;26515;26508:12;26824:179;26902:13;;26955:22;26944:34;;26934:45;;26924:73;;26993:1;26990;26983:12;26924:73;26824:179;;;:::o;27008:473::-;27111:6;27119;27127;27135;27143;27196:3;27184:9;27175:7;27171:23;27167:33;27164:53;;;27213:1;27210;27203:12;27164:53;27236:39;27265:9;27236:39;:::i;:::-;27226:49;;27315:2;27304:9;27300:18;27294:25;27284:35;;27359:2;27348:9;27344:18;27338:25;27328:35;;27403:2;27392:9;27388:18;27382:25;27372:35;;27426:49;27470:3;27459:9;27455:19;27426:49;:::i;:::-;27416:59;;27008:473;;;;;;;;:::o;29389:812::-;29800:25;29795:3;29788:38;29770:3;29855:6;29849:13;29871:75;29939:6;29934:2;29929:3;29925:12;29918:4;29910:6;29906:17;29871:75;:::i;:::-;30010:19;30005:2;29965:16;;;29997:11;;;29990:40;30055:13;;30077:76;30055:13;30139:2;30131:11;;30124:4;30112:17;;30077:76;:::i;:::-;30173:17;30192:2;30169:26;;29389:812;-1:-1:-1;;;;29389:812:34:o;30206:277::-;30273:6;30326:2;30314:9;30305:7;30301:23;30297:32;30294:52;;;30342:1;30339;30332:12;30294:52;30374:9;30368:16;30427:5;30420:13;30413:21;30406:5;30403:32;30393:60;;30449:1;30446;30439:12;30899:195;30938:3;30969:66;30962:5;30959:77;30956:103;;31039:18;;:::i;:::-;-1:-1:-1;31086:1:34;31075:13;;30899:195::o;31988:545::-;32090:2;32085:3;32082:11;32079:448;;;32126:1;32151:5;32147:2;32140:17;32196:4;32192:2;32182:19;32266:2;32254:10;32250:19;32247:1;32243:27;32237:4;32233:38;32302:4;32290:10;32287:20;32284:47;;;-1:-1:-1;32325:4:34;32284:47;32380:2;32375:3;32371:12;32368:1;32364:20;32358:4;32354:31;32344:41;;32435:82;32453:2;32446:5;32443:13;32435:82;;;32498:17;;;32479:1;32468:13;32435:82;;32769:1471;32895:3;32889:10;32922:18;32914:6;32911:30;32908:56;;;32944:18;;:::i;:::-;32973:97;33063:6;33023:38;33055:4;33049:11;33023:38;:::i;:::-;33017:4;32973:97;:::i;:::-;33125:4;;33189:2;33178:14;;33206:1;33201:782;;;;34027:1;34044:6;34041:89;;;-1:-1:-1;34096:19:34;;;34090:26;34041:89;32675:66;32666:1;32662:11;;;32658:84;32654:89;32644:100;32750:1;32746:11;;;32641:117;34143:81;;33171:1063;;33201:782;31935:1;31928:14;;;31972:4;31959:18;;33249:66;33237:79;;;33414:236;33428:7;33425:1;33422:14;33414:236;;;33517:19;;;33511:26;33496:42;;33609:27;;;;33577:1;33565:14;;;;33444:19;;33414:236;;;33418:3;33678:6;33669:7;33666:19;33663:261;;;33739:19;;;33733:26;33840:66;33822:1;33818:14;;;33834:3;33814:24;33810:97;33806:102;33791:118;33776:134;;33663:261;-1:-1:-1;;;;;33970:1:34;33954:14;;;33950:22;33937:36;;-1:-1:-1;32769:1471:34:o;34590:196::-;34629:3;34657:5;34647:39;;34666:18;;:::i;:::-;-1:-1:-1;34713:66:34;34702:78;;34590:196::o;34791:168::-;34864:9;;;34895;;34912:15;;;34906:22;;34892:37;34882:71;;34933:18;;:::i;35732:287::-;35861:3;35899:6;35893:13;35915:66;35974:6;35969:3;35962:4;35954:6;35950:17;35915:66;:::i;:::-;35997:16;;;;;35732:287;-1:-1:-1;;35732:287:34:o
Swarm Source
ipfs://3877674babd5c024ccfa7d86146e70d83be05618fdc2777994acd17b685af26f
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.