Contract Overview
Balance:
0 xDAI
xDAI Value:
$0.00
My Name Tag:
Not Available, login to update
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0x82729fdf393bee68c5be64f8bf73e9b81452d0971f36ebaf1355287f6eaa54e5 | 0x60806040 | 26026379 | 436 days 1 hr ago | 0xedb35e0e5adb5afc460dc4066b6b82d1bb46a6ee | IN | Create: LP | 0 xDAI | 0.0325902809 |
[ Download CSV Export ]
View more zero value Internal Transactions in Advanced View mode
Contract Name:
LP
Compiler Version
v0.8.16+commit.07a7930e
Optimization Enabled:
Yes with 2 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0-rc.1) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * 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 Internal function that returns the initialized version. Returns `_initialized` */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Internal function that returns the initialized version. Returns `_initializing` */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0-rc.1) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; import "./IERC721Upgradeable.sol"; import "./IERC721ReceiverUpgradeable.sol"; import "./extensions/IERC721MetadataUpgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/ContextUpgradeable.sol"; import "../../utils/StringsUpgradeable.sol"; import "../../utils/introspection/ERC165Upgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable { using AddressUpgradeable for address; using StringsUpgradeable for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing { __ERC721_init_unchained(name_, symbol_); } function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) { return interfaceId == type(IERC721Upgradeable).interfaceId || interfaceId == type(IERC721MetadataUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721Upgradeable.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _ownerOf(tokenId) != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721Upgradeable.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721Upgradeable.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721Upgradeable.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721Upgradeable.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721Upgradeable.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { return retval == IERC721ReceiverUpgradeable.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any (single) token transfer. This includes minting and burning. * See {_beforeConsecutiveTokenTransfer}. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` 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 tokenId ) internal virtual {} /** * @dev Hook that is called after any (single) transfer of tokens. This includes minting and burning. * See {_afterConsecutiveTokenTransfer}. * * Calling conditions: * * - when `from` and `to` are both non-zero. * - `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 tokenId ) internal virtual {} /** * @dev Hook that is called before consecutive token transfers. * Calling conditions are similar to {_beforeTokenTransfer}. * * The default implementation include balances updates that extensions such as {ERC721Consecutive} cannot perform * directly. */ function _beforeConsecutiveTokenTransfer( address from, address to, uint256, /*first*/ uint96 size ) internal virtual { if (from != address(0)) { _balances[from] -= size; } if (to != address(0)) { _balances[to] += size; } } /** * @dev Hook that is called after consecutive token transfers. * Calling conditions are similar to {_afterTokenTransfer}. */ function _afterConsecutiveTokenTransfer( address, /*from*/ address, /*to*/ uint256, /*first*/ uint96 /*size*/ ) 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[44] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0-rc.1) (token/ERC721/extensions/ERC721Enumerable.sol) pragma solidity ^0.8.0; import "../ERC721Upgradeable.sol"; import "./IERC721EnumerableUpgradeable.sol"; import "../../../proxy/utils/Initializable.sol"; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721EnumerableUpgradeable is Initializable, ERC721Upgradeable, IERC721EnumerableUpgradeable { function __ERC721Enumerable_init() internal onlyInitializing { } function __ERC721Enumerable_init_unchained() internal onlyInitializing { } // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC721Upgradeable) returns (bool) { return interfaceId == type(IERC721EnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require(index < ERC721Upgradeable.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < ERC721EnumerableUpgradeable.totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` and 'to' cannot be the zero address at the same time. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual override { super._beforeTokenTransfer(from, to, tokenId); if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Hook that is called before any batch token transfer. For now this is limited * to batch minting by the {ERC721Consecutive} extension. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` cannot be the zero address. * - `to` cannot be the zero address. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeConsecutiveTokenTransfer( address, address, uint256, uint96 size ) internal virtual override { // We revert because enumerability is not supported with consecutive batch minting. // This conditional is only needed to silence spurious warnings about unreachable code. if (size > 0) { revert("ERC721Enumerable: consecutive transfers not supported"); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721Upgradeable.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721Upgradeable.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } /** * @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[46] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; import "../IERC721Upgradeable.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721EnumerableUpgradeable is IERC721Upgradeable { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "../IERC721Upgradeable.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721MetadataUpgradeable is IERC721Upgradeable { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721ReceiverUpgradeable { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0-rc.1) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0-rc.1) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return 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 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 v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../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; } /** * @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 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165Upgradeable.sol"; import "../../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 (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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0-rc.1) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. 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 10, 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 * 8) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0-rc.1) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/MathUpgradeable.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 `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); } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity >=0.6.0; // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false library TransferHelper { function safeApprove( address token, address to, uint256 value ) internal { // bytes4(keccak256(bytes('approve(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); require( success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper::safeApprove: approve failed' ); } function safeTransfer( address token, address to, uint256 value ) internal { // bytes4(keccak256(bytes('transfer(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); require( success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper::safeTransfer: transfer failed' ); } function safeTransferFrom( address token, address from, address to, uint256 value ) internal { // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); require( success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper::transferFrom: transferFrom failed' ); } function safeTransferETH(address to, uint256 value) internal { (bool success, ) = to.call{value: value}(new bytes(0)); require(success, 'TransferHelper::safeTransferETH: ETH transfer failed'); } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.9; import "./IOwnable.sol"; interface IAccess is IOwnable { struct RoleData { address target; // target contract address bytes4 selector; // target function selector uint8 roleId; // ID of the role associated with contract-function combination } event RoleAdded(bytes32 indexed role, uint256 indexed roleId); event RoleRenamed(bytes32 indexed role, uint8 indexed roleId); event RoleBound(bytes32 indexed funcId, uint8 indexed roleId); event RoleUnbound(bytes32 indexed funcId, uint8 indexed roleId); event RoleGranted(address indexed user, uint8 indexed roleId); event RoleRevoked(address indexed user, uint8 indexed roleId); error NotTokenOwner(); error MaxRolesReached(); error AccessNotGranted(); error RoleAlreadyGranted(); function initialize() external; function checkAccess( address sender, address _contract, bytes4 selector ) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.9; interface IAffiliate { function resolveAffiliateReward(address affiliate, bytes calldata data) external returns (uint256 contribution); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.9; interface IBet { struct BetData { address affiliate; // address indicated as an affiliate when placing bet bytes data; // core-specific customized bet data } error BetNotExists(); /** * @notice Register new bet. * @param bettor wallet for emitting bet token * @param amount amount of tokens to bet * @param betData customized bet data */ function putBet( address bettor, uint128 amount, BetData calldata betData ) external returns (uint256 tokenId); function resolvePayout(uint256 tokenId) external returns (address account, uint128 payout); function viewPayout(uint256 tokenId) external view returns (uint128 payout); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.9; interface ICondition { enum ConditionState { CREATED, RESOLVED, CANCELED, PAUSED } struct Condition { uint256 gameId; uint128[2] funds; uint128[2] virtualFunds; uint128 reinforcement; uint128 affiliatesReward; uint64[2] outcomes; uint64 outcomeWin; uint64 margin; address oracle; uint64 endsAt; ConditionState state; uint48 leaf; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.9; import "./ICoreBase.sol"; interface ICore is ICoreBase { event NewBet( address indexed bettor, address indexed affiliate, uint256 indexed conditionId, uint256 tokenId, uint64 outcomeId, uint128 amount, uint64 odds, uint128[2] funds ); function resolveCondition(uint256 conditionId, uint64 outcomeWin) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.9; import "./IOwnable.sol"; import "./ICondition.sol"; import "./IBet.sol"; import "./IAffiliate.sol"; interface ICoreBase is ICondition, IOwnable, IBet, IAffiliate { struct AffiliateParams { uint256 start; uint256 count; } struct Bet { uint256 conditionId; uint128 amount; uint128 payout; uint64 outcome; bool isPaid; } struct CoreBetData { uint256 conditionId; // The match or game ID uint64 outcomeId; // ID of predicted outcome uint64 minOdds; // Minimum allowed betting odds } event ConditionCreated(uint256 indexed gameId, uint256 indexed conditionId); event ConditionResolved( uint256 indexed conditionId, uint8 state, uint64 outcomeWin, int128 lpProfit ); event ConditionStopped(uint256 indexed conditionId, bool flag); event OddsChanged(uint256 indexed conditionId, uint64[2] newOdds); error OnlyLp(); error AlreadyPaid(); error IncorrectConditionId(); error IncorrectMargin(); error IncorrectTimestamp(); error NoPendingReward(); error OnlyOracle(address); error SameOutcomes(); error SmallOdds(); error StartOutOfRange(uint256 pendingRewardsCount); error ZeroOdds(); error ActionNotAllowed(); error CantChangeFlag(); error ConditionAlreadyCreated(); error ConditionAlreadyResolved(); error ConditionNotExists(); error ConditionNotFinished(); error GameAlreadyStarted(); error ResolveTooEarly(uint64 waitTime); function initialize(address azuroBet, address lp) external; function calcOdds( uint256 conditionId, uint128 amount, uint64 outcome ) external view returns (uint64 odds); function changeOdds(uint256 conditionId, uint64[2] calldata newOdds) external; function getCondition(uint256 conditionId) external view returns (Condition memory); /** * @notice Register new condition. * @param gameId the game ID the condition belongs * @param conditionId the match or condition ID according to oracle's internal numbering * @param odds start odds for [team 1, team 2] * @param outcomes unique outcomes for the condition [outcome 1, outcome 2] * @param reinforcement maximum amount of liquidity intended to condition reinforcement * @param margin bookmaker commission */ function createCondition( uint256 gameId, uint256 conditionId, uint64[2] calldata odds, uint64[2] calldata outcomes, uint128 reinforcement, uint64 margin ) external; function isConditionCanceled(uint256 conditionId) external view returns (bool); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.9; import "./ICore.sol"; import "./IOwnable.sol"; interface ILP is IOwnable { enum FeeType { DAO, DATA_PROVIDER, AFFILIATE } enum CoreState { UNKNOWN, ACTIVE, INACTIVE } struct Condition { address core; uint256 conditionId; } struct CoreData { CoreState state; uint64 reinforcementAbility; uint128 minBet; uint128 lockedLiquidity; } struct Game { bytes32 ipfsHash; uint128 lockedLiquidity; uint64 startsAt; bool canceled; } struct Reward { int128 amount; uint64 claimedAt; } event CoreSettingsUpdated( address indexed core, CoreState state, uint64 reinforcementAbility, uint128 minBet ); event AffiliateRewarded(address indexed affiliate, uint256 amount); event BettorWin( address indexed core, address indexed bettor, uint256 tokenId, uint256 amount ); event ClaimTimeoutChanged(uint64 newClaimTimeout); event DataProviderChanged(address newDataProvider); event FeeChanged(FeeType feeType, uint64 fee); event GameCanceled(uint256 indexed gameId); event GameShifted(uint256 indexed gameId, uint64 newStart); event LiquidityAdded( address indexed account, uint48 indexed leaf, uint256 amount ); event LiquidityRemoved( address indexed account, uint48 indexed leaf, uint256 amount ); event MinBetChanged(address core, uint128 newMinBet); event MinDepoChanged(uint128 newMinDepo); event NewGame(uint256 indexed gameId, bytes32 ipfsHash, uint64 startsAt); event ReinforcementAbilityChanged(uint128 newReinforcementAbility); event WithdrawTimeoutChanged(uint64 newWithdrawTimeout); error OnlyFactory(); error SmallDepo(); error BetExpired(); error CoreNotActive(); error ClaimTimeout(uint64 waitTime); error GameAlreadyCanceled(); error GameAlreadyCreated(); error GameCanceled_(); error GameNotExists(); error IncorrectCoreState(); error IncorrectFee(); error IncorrectGameId(); error IncorrectMinBet(); error IncorrectMinDepo(); error IncorrectReinforcementAbility(); error IncorrectTimestamp(); error LiquidityNotOwned(); error LiquidityIsLocked(); error NoLiquidity(); error NotEnoughLiquidity(); error SmallBet(); error UnknownCore(); error WithdrawalTimeout(uint64 waitTime); function initialize( address access, address dataProvider, address token, uint128 minDepo, uint64 daoFee, uint64 dataProviderFee, uint64 affiliateFee ) external; function addCore(address core) external; function addLiquidity(uint128 amount) external; function addLiquidityNative() external payable; function withdrawLiquidity( uint48 depNum, uint40 percent, bool isNative ) external; function viewPayout(address core, uint256 tokenId) external view returns (uint128 payout); function betFor( address bettor, address core, uint128 amount, uint64 expiresAt, IBet.BetData calldata betData ) external returns (uint256 tokenId); function betNative( address core, uint64 expiresAt, IBet.BetData calldata betData ) external payable returns (uint256 tokenId); /** * @notice Make new bet. * @notice Emits bet token to `msg.sender`. * @param core address of the Core the bet is intended * @param amount amount of tokens to bet * @param expiresAt the time before which bet should be made * @param betData customized bet data */ function bet( address core, uint128 amount, uint64 expiresAt, IBet.BetData calldata betData ) external returns (uint256 tokenId); function changeDataProvider(address newDataProvider) external; function claimAffiliateReward(address core, bytes calldata data) external returns (uint256); function claimReward() external returns (uint256); function getReserve() external view returns (uint128); function addReserve( uint256 gameId, uint128 lockedReserve, uint128 profitReserve, uint48 leaf ) external returns (uint128 affiliatesReward); function addCondition(uint256 gameId) external returns (uint64); function withdrawPayout( address core, uint256 tokenId, bool isNative ) external; function changeLockedLiquidity(uint256 gameId, int128 deltaReserve) external; function getGameInfo(uint256 gameId) external view returns (uint64 startsAt, bool canceled); function getLockedLiquidityLimit(address core) external view returns (uint128); function isGameCanceled(uint256 gameId) external view returns (bool canceled); function checkAccess( address account, address target, bytes4 selector ) external; function checkCore(address core) external view; function getLeaf() external view returns (uint48 leaf); function coreAffRewards(address) external view returns (uint128); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.9; interface IOwnable { event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); function owner() external view returns (address); function checkOwner(address account) external view; function transferOwnership(address newOwner) external; }
// SPDX-License-Identifier: GPL-3.0 /** * @dev interface for canonical wrapped native contract based on WETH9.sol */ pragma solidity ^0.8.9; interface IWNative { function deposit() external payable; function transfer(address to, uint256 value) external returns (bool); function withdraw(uint256) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.9; /// @title Fixed-point math tools library FixedMath { uint256 constant ONE = 1e12; function mul(uint256 self, uint256 other) internal pure returns (uint256) { return (self * other) / ONE; } function div(uint256 self, uint256 other) internal pure returns (uint256) { return (self * ONE) / other; } function sqr(uint256 self) internal pure returns (uint256) { return (self * self) / ONE; } function sqrt(uint256 self) internal pure returns (uint256) { self *= ONE; uint256 previous = self; uint256 next = (self + 1) / 2; while (next < previous) { previous = next; next = (self / next + next) / 2; } return previous; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.9; library SafeCast { enum Type { BYTES32, INT128, UINT64, UINT128 } error SafeCastError(Type to); function toBytes32(string calldata value) internal pure returns (bytes32) { bytes memory value_ = bytes(value); if (value_.length > 32) revert SafeCastError(Type.BYTES32); return bytes32(value_); } function toInt128(uint128 value) internal pure returns (int128) { if (value > uint128(type(int128).max)) revert SafeCastError(Type.INT128); return int128(value); } function toUint64(uint256 value) internal pure returns (uint64) { if (value > type(uint64).max) revert SafeCastError(Type.UINT64); return uint64(value); } function toUint128(uint256 value) internal pure returns (uint128) { if (value > type(uint128).max) revert SafeCastError(Type.UINT128); return uint128(value); } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.9; import "./interface/IAccess.sol"; import "./interface/ICoreBase.sol"; import "./interface/ILP.sol"; import "./interface/IOwnable.sol"; import "./interface/IWNative.sol"; import "./interface/IBet.sol"; import "./interface/IAffiliate.sol"; import "./libraries/FixedMath.sol"; import "./libraries/SafeCast.sol"; import "./utils/LiquidityTree.sol"; import "./utils/OwnableUpgradeable.sol"; import "@uniswap/lib/contracts/libraries/TransferHelper.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; /// @title Azuro Liquidity Pool managing contract LP is LiquidityTree, OwnableUpgradeable, ERC721EnumerableUpgradeable, ILP { using FixedMath for uint64; using SafeCast for uint256; using SafeCast for uint128; IOwnable public factory; IAccess public access; address public token; address public dataProvider; uint128 public minDepo; // Minimum amount of liquidity deposit uint128 public lockedLiquidity; // Liquidity reserved by conditions uint64 public claimTimeout; // Withdraw reward timeout uint64 public withdrawTimeout; // Deposit-withdraw liquidity timeout mapping(address => CoreData) public cores; mapping(uint256 => Game) public games; uint64[3] public fees; mapping(address => Reward) public rewards; // withdrawAfter[depNum] = timestamp when liquidity withdraw will be available mapping(uint48 => uint64) public withdrawAfter; mapping(address => uint128) public override coreAffRewards; // Affiliate rewards by Core's conditions /** * @notice Check if Core `core` belongs to this Liquidity Pool and is active. */ modifier isActive(address core) { _checkCoreActive(core); _; } /** * @notice Check if Core `core` belongs to this Liquidity Pool. */ modifier isCore(address core) { checkCore(core); _; } /** * @notice Throw if caller is not the Pool Factory. */ modifier onlyFactory() { if (msg.sender != address(factory)) revert OnlyFactory(); _; } /** * @notice Throw if caller have no access to function with selector `selector`. */ modifier restricted(bytes4 selector) { checkAccess(msg.sender, address(this), selector); _; } receive() external payable { require(msg.sender == token); } function initialize( address access_, address dataProvider_, address token_, uint128 minDepo_, uint64 daoFee, uint64 dataProviderFee, uint64 affiliateFee ) external virtual override initializer { if (minDepo_ == 0) revert IncorrectMinDepo(); __Ownable_init(); __ERC721_init("Azuro LP NFT token", "LP-AZR"); __liquidityTree_init(); factory = IOwnable(msg.sender); access = IAccess(access_); dataProvider = dataProvider_; token = token_; fees[0] = daoFee; fees[1] = dataProviderFee; fees[2] = affiliateFee; _checkFee(); minDepo = minDepo_; } /** * @notice Owner: Set `newClaimTimeout` as claim timeout. */ function changeClaimTimeout(uint64 newClaimTimeout) external onlyOwner { claimTimeout = newClaimTimeout; emit ClaimTimeoutChanged(newClaimTimeout); } /** * @notice Owner: Set `newDataProvider` as Data Provider. */ function changeDataProvider(address newDataProvider) external onlyOwner { dataProvider = newDataProvider; emit DataProviderChanged(newDataProvider); } /** * @notice Owner: Set `newFee` as type `feeType` fee. * @param newFee fee share where `FixedMath.ONE` is 100% of the Liquidity Pool profit */ function changeFee(FeeType feeType, uint64 newFee) external onlyOwner { fees[uint256(feeType)] = newFee; _checkFee(); emit FeeChanged(feeType, newFee); } /** * @notice Owner: Set `newMinDepo` as minimum liquidity deposit. */ function changeMinDepo(uint128 newMinDepo) external onlyOwner { if (newMinDepo == 0) revert IncorrectMinDepo(); minDepo = newMinDepo; emit MinDepoChanged(newMinDepo); } /** * @notice Owner: Set `withdrawTimeout` as liquidity deposit withdrawal timeout. */ function changeWithdrawTimeout(uint64 newWithdrawTimeout) external onlyOwner { withdrawTimeout = newWithdrawTimeout; emit WithdrawTimeoutChanged(newWithdrawTimeout); } /** * @notice Owner: Update Core `core` settings. */ function updateCoreSettings( address core, CoreState state, uint64 reinforcementAbility, uint128 minBet ) external onlyOwner isCore(core) { if (minBet == 0) revert IncorrectMinBet(); if (reinforcementAbility > FixedMath.ONE) revert IncorrectReinforcementAbility(); if (state == CoreState.UNKNOWN) revert IncorrectCoreState(); CoreData storage coreData = cores[core]; coreData.minBet = minBet; coreData.reinforcementAbility = reinforcementAbility; coreData.state = state; emit CoreSettingsUpdated(core, state, reinforcementAbility, minBet); } /** * @notice Indicate the game `gameId` as canceled. * @param gameId the game ID */ function cancelGame(uint256 gameId) external restricted(this.cancelGame.selector) { Game storage game = _getGame(gameId); if (game.canceled) revert GameAlreadyCanceled(); lockedLiquidity -= game.lockedLiquidity; game.canceled = true; emit GameCanceled(gameId); } /** * @notice Create new game. * @param gameId the match or condition ID according to oracle's internal numbering * @param ipfsHash hash of detailed info about the game stored in the IPFS * @param startsAt timestamp when the game starts */ function createGame( uint256 gameId, bytes32 ipfsHash, uint64 startsAt ) external restricted(this.createGame.selector) { Game storage game = games[gameId]; if (game.startsAt > 0) revert GameAlreadyCreated(); if (gameId == 0) revert IncorrectGameId(); if (startsAt < block.timestamp) revert IncorrectTimestamp(); game.ipfsHash = ipfsHash; game.startsAt = startsAt; emit NewGame(gameId, ipfsHash, startsAt); } /** * @notice Set `startsAt` as new game `gameId` start time. * @param gameId the game ID * @param startsAt new timestamp when the game starts */ function shiftGame(uint256 gameId, uint64 startsAt) external restricted(this.shiftGame.selector) { Game storage game = _getGame(gameId); game.startsAt = startsAt; emit GameShifted(gameId, startsAt); } /** * @notice Deposit liquidity in the Liquidity Pool. * @notice Emits deposit token to `msg.sender`. * @param amount token's amount to deposit */ function addLiquidity(uint128 amount) external { TransferHelper.safeTransferFrom( token, msg.sender, address(this), amount ); _addLiquidity(amount); } /** * @notice Deposit liquidity in the Liquidity Pool via sending native tokens with msg.value. * @notice Emits deposit token to `msg.sender`. */ function addLiquidityNative() external payable { IWNative(token).deposit{value: msg.value}(); _addLiquidity(msg.value.toUint128()); } /** * @notice Withdraw payout for liquidity deposit. * @param depNum deposit token ID * @param percent payout share to withdraw where `FixedMath.ONE` is 100% of deposit payout */ function withdrawLiquidity( uint48 depNum, uint40 percent, bool isNative ) external { uint128 withdrawAmount = _withdrawLiquidity(depNum, percent); if (isNative) { IWNative(token).withdraw(withdrawAmount); TransferHelper.safeTransferETH(msg.sender, withdrawAmount); } else { TransferHelper.safeTransfer(token, msg.sender, withdrawAmount); } } /** * @notice Withdraw affiliate profit share based on the contribution to betting traffic. * @notice The gas cost of the function is directly proportional to the number of elements of the array of all conditions contributed by the affiliate that are not rewarded yet. * @param core address of the Core traffic to which should be rewarded * @param data core specific params * @return claimedAmount claimed reward amount */ function claimAffiliateReward(address core, bytes calldata data) external isCore(core) returns (uint256 claimedAmount) { claimedAmount = IAffiliate(core).resolveAffiliateReward( msg.sender, data ); if (claimedAmount > 0) { TransferHelper.safeTransfer(token, msg.sender, claimedAmount); emit AffiliateRewarded(msg.sender, claimedAmount); } } /** * @notice Reward the Factory owner (DAO) or Data Provider with total amount of charged fees. * @return claimedAmount claimed reward amount */ function claimReward() external returns (uint256 claimedAmount) { Reward storage reward = rewards[msg.sender]; if ((block.timestamp - reward.claimedAt) < claimTimeout) revert ClaimTimeout(reward.claimedAt + claimTimeout); int128 rewardAmount = reward.amount; if (rewardAmount <= 0) return 0; reward.amount = 0; reward.claimedAt = uint64(block.timestamp); claimedAmount = uint128(rewardAmount); TransferHelper.safeTransfer(token, msg.sender, claimedAmount); } /** * @notice Make new bet. * @notice Emits bet token to `msg.sender`. * @notice See {ILP-bet}. */ function bet( address core, uint128 amount, uint64 expiresAt, IBet.BetData calldata betData ) external override returns (uint256) { TransferHelper.safeTransferFrom( token, msg.sender, address(this), amount ); return _bet(msg.sender, core, amount, expiresAt, betData); } /** * @notice Make new bet for `bettor`. * @notice Emits bet token to `bettor`. * @param bettor wallet for emitting bet token * @param core address of the Core the bet is intended * @param amount amount of tokens to bet * @param expiresAt the time before which bet should be made * @param betData customized bet data */ function betFor( address bettor, address core, uint128 amount, uint64 expiresAt, IBet.BetData calldata betData ) external override returns (uint256) { TransferHelper.safeTransferFrom( token, msg.sender, address(this), amount ); return _bet(bettor, core, amount, expiresAt, betData); } /** * @notice Make new bet via sending native tokens with msg.value. * @notice Emits bet token to `msg.sender`. * @param core address of the Core the bet is intended * @param expiresAt the time before which bet should be made * @param betData customized bet data */ function betNative( address core, uint64 expiresAt, IBet.BetData calldata betData ) external payable override returns (uint256) { IWNative(token).deposit{value: msg.value}(); return _bet(msg.sender, core, msg.value.toUint128(), expiresAt, betData); } function withdrawPayout( address core, uint256 tokenId, bool isNative ) external override isCore(core) { (address account, uint128 amount) = IBet(core).resolvePayout(tokenId); if (amount > 0) { emit BettorWin(core, account, tokenId, amount); if (isNative) { IWNative(token).withdraw(amount); TransferHelper.safeTransferETH(account, amount); } else { TransferHelper.safeTransfer(token, account, amount); } } } /** * @notice Active Core: Check if Core `msg.sender` can create condition for game `gameId`. */ function addCondition(uint256 gameId) external override isActive(msg.sender) returns (uint64) { Game storage game = _getGame(gameId); if (game.canceled) revert GameCanceled_(); return game.startsAt; } /** * @notice Active Core: Change amount of liquidity reserved by the game `gameId`. * @param gameId the game ID * @param deltaReserve value of the change in the amount of liquidity used by the game as a reinforcement */ function changeLockedLiquidity(uint256 gameId, int128 deltaReserve) external override isActive(msg.sender) { if (deltaReserve > 0) { uint128 _deltaReserve = uint128(deltaReserve); if (gameId > 0) { games[gameId].lockedLiquidity += _deltaReserve; } CoreData storage coreData = cores[msg.sender]; coreData.lockedLiquidity += _deltaReserve; lockedLiquidity += _deltaReserve; uint128 reserve = getReserve(); if ( lockedLiquidity > reserve || coreData.lockedLiquidity > coreData.reinforcementAbility.mul(reserve) ) revert NotEnoughLiquidity(); } else _reduceLockedLiquidity(msg.sender, gameId, uint128(-deltaReserve)); } /** * @notice Factory: Indicate `core` as new active Core. */ function addCore(address core) external override onlyFactory { CoreData storage coreData = cores[core]; coreData.minBet = 1; coreData.reinforcementAbility = uint64(FixedMath.ONE); coreData.state = CoreState.ACTIVE; emit CoreSettingsUpdated( core, CoreState.ACTIVE, uint64(FixedMath.ONE), 1 ); } /** * @notice Core: Finalize changes in the balance of Liquidity Pool * after the game `gameId` condition's resolve. * @param gameId the game ID * @param lockedReserve amount of liquidity reserved by condition * @param finalReserve amount of liquidity that was not demand according to the condition result */ function addReserve( uint256 gameId, uint128 lockedReserve, uint128 finalReserve, uint48 leaf ) external override isCore(msg.sender) returns (uint128 affiliatesReward) { Reward storage dataProviderRewards = rewards[dataProvider]; Reward storage daoRewards = rewards[factory.owner()]; if (finalReserve > lockedReserve) { uint128 profit = finalReserve - lockedReserve; uint128 netProfit = profit; // increase oracle rewards uint128 dataProviderReward = _getFee(FeeType.DATA_PROVIDER) .mul(profit) .toUint128(); netProfit -= _addDelta( dataProviderRewards.amount, dataProviderReward ); dataProviderRewards.amount += dataProviderReward.toInt128(); // increase DAO rewards uint128 daoReward = _getFee(FeeType.DAO).mul(profit).toUint128(); netProfit -= _addDelta(daoRewards.amount, daoReward); daoRewards.amount += daoReward.toInt128(); // calc affiliate rewards affiliatesReward = _getFee(FeeType.AFFILIATE) .mul(profit) .toUint128(); // add profit to core aff accumulator, save raw rewards coreAffRewards[msg.sender] += affiliatesReward; // add profit to liquidity (reduced by oracle/dao's rewards) _addLimit(netProfit - affiliatesReward, leaf); } else { // remove loss from liquidityTree excluding canceled conditions (when finalReserve = lockedReserve) if (lockedReserve - finalReserve > 0) { uint128 loss = lockedReserve - finalReserve; uint128 netLoss = loss; // reduce oracle loss uint128 oracleLoss = _getFee(FeeType.DATA_PROVIDER) .mul(loss) .toUint128(); netLoss -= _reduceDelta(dataProviderRewards.amount, oracleLoss); dataProviderRewards.amount -= oracleLoss.toInt128(); // reduce DAO rewards uint128 daoLoss = _getFee(FeeType.DAO).mul(loss).toUint128(); netLoss -= _reduceDelta(daoRewards.amount, daoLoss); daoRewards.amount -= daoLoss.toInt128(); // remove all loss (reduced by oracle/dao's losses) from liquidity _remove(netLoss); } } if (lockedReserve > 0) _reduceLockedLiquidity(msg.sender, gameId, lockedReserve); } /** * @notice Get the start time of the game `gameId` and whether it was canceled. */ function getGameInfo(uint256 gameId) external view override returns (uint64, bool) { Game storage game = games[gameId]; return (game.startsAt, game.canceled); } /** * @notice Get the max amount of liquidity that can be locked by Core `core` conditions. */ function getLockedLiquidityLimit(address core) external view returns (uint128) { return uint128(cores[core].reinforcementAbility.mul(getReserve())); } /** * @notice Get the total amount of liquidity in the Pool. */ function getReserve() public view override returns (uint128 reserve) { return treeNode[1].amount; } /** * @notice Get ID of the last added leaf to the liquidity tree. */ function getLeaf() external view override returns (uint48 leaf) { return (nextNode - 1); } /** * @notice Check if game `gameId` is canceled. */ function isGameCanceled(uint256 gameId) external view override returns (bool) { return games[gameId].canceled; } /** * @notice Get bet token `tokenId` payout. * @param core address of the Core where bet was placed * @param tokenId bet token ID * @return payout winnings of the token owner */ function viewPayout(address core, uint256 tokenId) external view isCore(core) returns (uint128) { return IBet(core).viewPayout(tokenId); } /** * @notice Throw if `account` have no access to function with selector `selector` of `target`. */ function checkAccess( address account, address target, bytes4 selector ) public { access.checkAccess(account, target, selector); } /** * @notice Throw if `core` not belongs to the Liquidity Pool's Cores. */ function checkCore(address core) public view { if (_getCoreState(core) == CoreState.UNKNOWN) revert UnknownCore(); } /** * @notice Deposit liquidity in the Liquidity Pool. * @notice Emits deposit token to `msg.sender`. * @param amount token's amount to deposit */ function _addLiquidity(uint128 amount) internal { if (amount < minDepo) revert SmallDepo(); uint48 leaf = _nodeAddLiquidity(amount); withdrawAfter[leaf] = uint64(block.timestamp) + withdrawTimeout; _mint(msg.sender, leaf); emit LiquidityAdded(msg.sender, leaf, amount); } /** * @notice Make new bet. * @param bettor wallet for emitting bet token * @param core address of the Core the bet is intended * @param amount amount of tokens to bet * @param expiresAt the time before which bet should be made * @param betData customized bet data */ function _bet( address bettor, address core, uint128 amount, uint64 expiresAt, IBet.BetData memory betData ) internal isActive(core) returns (uint256) { if (block.timestamp >= expiresAt) revert BetExpired(); if (amount < cores[core].minBet) revert SmallBet(); // owner is default affiliate if (betData.affiliate == address(0)) betData.affiliate = owner(); return IBet(core).putBet(bettor, amount, betData); } function _reduceLockedLiquidity( address core, uint256 gameId, uint128 deltaReserve ) internal { if (gameId > 0) { games[gameId].lockedLiquidity -= deltaReserve; } cores[core].lockedLiquidity -= deltaReserve; lockedLiquidity -= deltaReserve; } /** * @notice Resolve payout for liquidity deposit. * @param depNum deposit token ID * @param percent payout share to resolve where `FixedMath.ONE` is 100% of deposit payout */ function _withdrawLiquidity(uint48 depNum, uint40 percent) internal returns (uint128 withdrawAmount) { uint64 time = uint64(block.timestamp); uint64 _withdrawAfter = withdrawAfter[depNum]; if (time < _withdrawAfter) revert WithdrawalTimeout(_withdrawAfter - time); if (msg.sender != ownerOf(depNum)) revert LiquidityNotOwned(); withdrawAfter[depNum] = time + withdrawTimeout; uint128 topNodeAmount = getReserve(); withdrawAmount = _nodeWithdrawPercent(depNum, percent); if (withdrawAmount == 0) revert NoLiquidity(); // check withdrawAmount allowed in ("node #1" - "active condition reinforcements") if (withdrawAmount > (topNodeAmount - lockedLiquidity)) revert LiquidityIsLocked(); emit LiquidityRemoved(msg.sender, depNum, withdrawAmount); } /** * @notice Throw if `core` not belongs to the Liquidity Pool's active Cores. */ function _checkCoreActive(address core) internal view { if (_getCoreState(core) != CoreState.ACTIVE) revert CoreNotActive(); } /** * @notice Get `CoreState` by core address. */ function _getCoreState(address core) internal view returns (CoreState) { return cores[core].state; } /** * @notice Throw if set fees are incorrect. */ function _checkFee() internal view { if ( _getFee(FeeType.DAO) + _getFee(FeeType.DATA_PROVIDER) + _getFee(FeeType.AFFILIATE) > FixedMath.ONE ) revert IncorrectFee(); } /** * @notice Get current fee type `feeType` profit share. */ function _getFee(FeeType feeType) internal view returns (uint64) { return fees[uint256(feeType)]; } /** * @notice Get game by it's ID. */ function _getGame(uint256 gameId) internal view returns (Game storage) { Game storage game = games[gameId]; if (game.startsAt == 0) revert GameNotExists(); return game; } /** * @notice Calculate the positive delta between `a` and `a + b`. */ function _addDelta(int128 a, uint128 b) internal pure returns (uint128) { if (a < 0) { int128 c = a + b.toInt128(); return (c > 0) ? uint128(c) : 0; } else return b; } /** * @notice Calculate the positive delta between `a - b` and `a`. */ function _reduceDelta(int128 a, uint128 b) internal pure returns (uint128) { return (a < 0 ? 0 : (a > b.toInt128() ? b : uint128(a))); } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.9; import "../libraries/FixedMath.sol"; contract LiquidityTree { using FixedMath for uint40; struct Node { uint64 updateId; // last update number uint128 amount; // node amount } uint48 constant LIQUIDITYNODES = 1_099_511_627_776; // begining of data nodes (top at node #1) uint48 constant LIQUIDITYLASTNODE = LIQUIDITYNODES * 2 - 1; uint48 public nextNode; // next unused node number for adding liquidity uint64 public updateId; // update number, used instead of timestamp for splitting changes time on the same nodes // liquidity (segment) tree mapping(uint48 => Node) public treeNode; error LeafNotExist(); error IncorrectPercent(); /** * @dev initializing LIQUIDITYNODES and nextNode. * @dev LIQUIDITYNODES is count of liquidity (segment) tree leaves contains single liquidity addings * @dev liquidity (segment) tree build as array of 2*LIQUIDITYNODES count, top node has id #1 (id #0 not used) * @dev liquidity (segment) tree leaves is array [LIQUIDITYNODES, 2*LIQUIDITYNODES-1] * @dev liquidity (segment) tree node index N has left child index 2*N and right child index 2N+1 * @dev +--------------------------------------------+ | 1 (top node) | +------------------------+-------------------+ | 2 | 3 | +-------------+----------+---------+---------+ | 4 (nextNode)| 5 | 6 | 7 | +-------------+----------+---------+---------+ */ function __liquidityTree_init() internal { nextNode = LIQUIDITYNODES; updateId++; // start from non zero } /** * @dev leaf withdraw preview, emulates push value from updated node to leaf * @param leaf - withdrawing leaf */ function nodeWithdrawView(uint48 leaf) public view returns (uint128 withdrawAmount) { if (leaf < LIQUIDITYNODES || leaf > LIQUIDITYLASTNODE) return 0; if (treeNode[leaf].updateId == 0) return 0; // get last-updated top node (uint48 updatedNode, uint48 start, uint48 end) = _getUpdatedNode( 1, treeNode[1].updateId, LIQUIDITYNODES, LIQUIDITYLASTNODE, 1, LIQUIDITYNODES, LIQUIDITYLASTNODE, leaf ); return _getPushView( updatedNode, start, end, leaf, treeNode[updatedNode].amount ); } /** * @dev add amount only for limited leaves in tree [first_leaf, leaf] * @param amount value to add */ function _addLimit(uint128 amount, uint48 leaf) internal { // get last-updated top node (uint48 updatedNode, uint48 start, uint48 end) = _getUpdatedNode( 1, treeNode[1].updateId, LIQUIDITYNODES, LIQUIDITYLASTNODE, 1, LIQUIDITYNODES, LIQUIDITYLASTNODE, leaf ); uint64 updateId_ = updateId; // push changes from last-updated node down to the leaf, if leaf is not up to date _push(updatedNode, start, end, leaf, ++updateId_); _pushLazy( 1, LIQUIDITYNODES, LIQUIDITYLASTNODE, LIQUIDITYNODES, leaf, amount, false, ++updateId_ ); updateId = updateId_; } /** * @dev change amount by adding value or reducing value * @param node - node for changing * @param amount - amount value for changing * @param isSub - true - reduce by amount, true - add by amount * @param updateId_ - update number */ function _changeAmount( uint48 node, uint128 amount, bool isSub, uint64 updateId_ ) internal { treeNode[node].updateId = updateId_; if (isSub) { treeNode[node].amount -= amount; } else { treeNode[node].amount += amount; } } /** * @dev add liquidity amount from the leaf up to top node * @param amount - adding amount */ function _nodeAddLiquidity(uint128 amount) internal returns (uint48 resNode) { resNode = nextNode++; _updateUp(resNode, amount, false, ++updateId); } /** * @dev withdraw part of liquidity from the leaf, due possible many changes in leaf's parent nodes * @dev it is needed firstly to update its amount and then withdraw * @dev used steps: * @dev 1 - get last updated parent most near to the leaf * @dev 2 - push all changes from found parent to the leaf - that updates leaf's amount * @dev 3 - execute withdraw of leaf amount and update amount changing up to top parents * @param leaf - * @param percent - percent of leaf amount 1*10^12 is 100%, 5*10^11 is 50% */ function _nodeWithdrawPercent(uint48 leaf, uint40 percent) internal returns (uint128 withdrawAmount) { if (treeNode[leaf].updateId == 0) revert LeafNotExist(); if (percent > FixedMath.ONE) revert IncorrectPercent(); // get last-updated top node (uint48 updatedNode, uint48 start, uint48 end) = _getUpdatedNode( 1, treeNode[1].updateId, LIQUIDITYNODES, LIQUIDITYLASTNODE, 1, LIQUIDITYNODES, LIQUIDITYLASTNODE, leaf ); uint64 updateId_ = updateId; // push changes from last-updated node down to the leaf, if leaf is not up to date _push(updatedNode, start, end, leaf, ++updateId_); // remove amount (percent of amount) from leaf to it's parents withdrawAmount = uint128(percent.mul(treeNode[leaf].amount)); _updateUp(leaf, withdrawAmount, true, ++updateId_); updateId = updateId_; } /** * @dev push changes from last "lazy update" down to leaf * @param node - last node from lazy update * @param start - leaf search start * @param end - leaf search end * @param leaf - last node to update * @param updateId_ update number */ function _push( uint48 node, uint48 start, uint48 end, uint48 leaf, uint64 updateId_ ) internal { // if node is leaf, stop if (node == leaf) { return; } uint48 lChild = node * 2; uint48 rChild = node * 2 + 1; uint128 amount = treeNode[node].amount; uint256 lAmount = treeNode[lChild].amount; uint256 rAmount = treeNode[rChild].amount; uint256 sumAmounts = lAmount + rAmount; if (sumAmounts == 0) return; uint128 setLAmount = uint128((amount * lAmount) / sumAmounts); // update left and right child _setAmount(lChild, setLAmount, updateId_); _setAmount(rChild, amount - setLAmount, updateId_); uint48 mid = (start + end) / 2; if (start <= leaf && leaf <= mid) { _push(lChild, start, mid, leaf, updateId_); } else { _push(rChild, mid + 1, end, leaf, updateId_); } } /** * @dev push lazy (lazy propagation) amount value from top node to child nodes contained leafs from 0 to r * @param node - start from node * @param start - node left element * @param end - node right element * @param l - left leaf child * @param r - right leaf child * @param amount - amount to add/reduce stored amounts * @param isSub - true means negative to reduce * @param updateId_ update number */ function _pushLazy( uint48 node, uint48 start, uint48 end, uint48 l, uint48 r, uint128 amount, bool isSub, uint64 updateId_ ) internal { if ((start == l && end == r) || (start == end)) { // if node leafs equal to leaf interval then stop _changeAmount(node, amount, isSub, updateId_); return; } uint48 mid = (start + end) / 2; if (start <= r && r <= mid) { // [l,r] in [start,mid] - all leafs in left child _pushLazy(node * 2, start, mid, l, r, amount, isSub, updateId_); } else { uint256 lAmount = treeNode[node * 2].amount; // get right amount excluding unused leaves when adding amounts uint256 rAmount = treeNode[node * 2 + 1].amount - ( !isSub ? _getLeavesAmount( node * 2 + 1, mid + 1, end, r + 1, end ) : 0 ); uint256 sumAmounts = lAmount + rAmount; if (sumAmounts == 0) return; uint128 forLeftAmount = uint128((amount * lAmount) / sumAmounts); // l in [start,mid] - part in left child _pushLazy( node * 2, start, mid, l, mid, forLeftAmount, isSub, updateId_ ); // r in [mid+1,end] - part in right child _pushLazy( node * 2 + 1, mid + 1, end, mid + 1, r, amount - forLeftAmount, isSub, updateId_ ); } _changeAmount(node, amount, isSub, updateId_); } /** * @dev remove amount from whole tree, starting from top node #1 * @param amount value to remove */ function _remove(uint128 amount) internal { if (treeNode[1].amount >= amount) { _pushLazy( 1, LIQUIDITYNODES, LIQUIDITYLASTNODE, LIQUIDITYNODES, nextNode - 1, amount, true, ++updateId ); } } /** * @dev reset node amount, used in push * @param node for set * @param amount value * @param updateId_ update number */ function _setAmount( uint48 node, uint128 amount, uint64 updateId_ ) internal { if (treeNode[node].amount != amount) { treeNode[node].updateId = updateId_; treeNode[node].amount = amount; } } /** * @dev update up amounts from leaf up to top node #1, used in adding/removing values on leaves * @param child node for update * @param amount value for update * @param isSub true - reduce, false - add * @param updateId_ update number */ function _updateUp( uint48 child, uint128 amount, bool isSub, uint64 updateId_ ) internal { _changeAmount(child, amount, isSub, updateId_); // if not top parent if (child != 1) { _updateUp(child > 1 ? child / 2 : 1, amount, isSub, updateId_); } } /** * @dev for current node get sum amount of exact leaves list * @param node node to get sum amount * @param start - node left element * @param end - node right element * @param l - left leaf of the list * @param r - right leaf of the list * @return amount sum of leaves list */ function _getLeavesAmount( uint48 node, uint48 start, uint48 end, uint48 l, uint48 r ) internal view returns (uint128 amount) { if ((start == l && end == r) || (start == end)) { // if node leafs equal to leaf interval then stop and return amount value return (treeNode[node].amount); } uint48 mid = (start + end) / 2; if (start <= l && l <= mid) { amount += _getLeavesAmount(node * 2, start, mid, l, mid); amount += _getLeavesAmount(node * 2 + 1, mid + 1, end, mid + 1, r); } else { amount += _getLeavesAmount(node * 2 + 1, mid + 1, end, l, r); } return amount; } /** * @dev emulating push changes from last "lazy update" down to leaf * @param node - last node from lazy update * @param start - leaf search start * @param end - leaf search end * @param leaf - last node to update * @param amount - pushed (calced) amount for the node */ function _getPushView( uint48 node, uint48 start, uint48 end, uint48 leaf, uint128 amount ) internal view returns (uint128 withdrawAmount) { // if node is leaf, stop if (node == leaf) { return amount; } uint48 lChild = node * 2; uint48 rChild = node * 2 + 1; uint256 lAmount = treeNode[lChild].amount; uint256 sumAmounts = lAmount + treeNode[rChild].amount; if (sumAmounts == 0) return 0; uint128 setLAmount = uint128((amount * lAmount) / sumAmounts); uint48 mid = (start + end) / 2; if (start <= leaf && leaf <= mid) { return _getPushView(lChild, start, mid, leaf, setLAmount); } else { return _getPushView(rChild, mid + 1, end, leaf, amount - setLAmount); } } /** * @dev top node is ever most updated, trying to find lower node not older then top node * @dev get nearest to leaf (lowest) last-updated node from the parents, runing down from top to leaf * @param parent top node * @param parentUpdate top node update * @param parentBegin top node most left leaf * @param parentEnd top node most right leaf * @param node node parent for the leaf * @param start node most left leaf * @param end node most right leaf * @param leaf target leaf * @return resParent found most updated leaf parent * @return resBegin found parent most left leaf * @return resEnd found parent most right leaf */ function _getUpdatedNode( uint48 parent, uint64 parentUpdate, uint48 parentBegin, uint48 parentEnd, uint48 node, uint48 start, uint48 end, uint48 leaf ) internal view returns ( uint48 resParent, uint48 resBegin, uint48 resEnd ) { // if node is older than it's parent, stop and return parent if (treeNode[node].updateId < parentUpdate) { return (parent, parentBegin, parentEnd); } if (node == leaf) { return (leaf, start, end); } uint48 mid = (start + end) / 2; if (start <= leaf && leaf <= mid) { // work on left child (resParent, resBegin, resEnd) = _getUpdatedNode( node, parentUpdate, start, end, node * 2, start, mid, leaf ); } else { // work on right child (resParent, resBegin, resEnd) = _getUpdatedNode( node, parentUpdate, start, end, node * 2 + 1, mid + 1, end, leaf ); } } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.9; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; import "../interface/IOwnable.sol"; /** * @dev Forked from OpenZeppelin contract: * https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/ae03ee04ae226526abad6731cf4024134f46ae28/contracts/access/OwnableUpgradeable.sol * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is IOwnable, Initializable, ContextUpgradeable { address private _owner; /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Context_init_unchained(); __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { checkOwner(_msgSender()); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual override returns (address) { return _owner; } /** * @dev Throws if the account is not the owner. */ function checkOwner(address account) public view virtual override { require(owner() == account, "Ownable: account is not the owner"); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual override onlyOwner { require( newOwner != address(0), "Ownable: new owner is the zero address" ); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @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; }
{ "optimizer": { "enabled": true, "runs": 2 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
[{"inputs":[],"name":"BetExpired","type":"error"},{"inputs":[{"internalType":"uint64","name":"waitTime","type":"uint64"}],"name":"ClaimTimeout","type":"error"},{"inputs":[],"name":"CoreNotActive","type":"error"},{"inputs":[],"name":"GameAlreadyCanceled","type":"error"},{"inputs":[],"name":"GameAlreadyCreated","type":"error"},{"inputs":[],"name":"GameCanceled_","type":"error"},{"inputs":[],"name":"GameNotExists","type":"error"},{"inputs":[],"name":"IncorrectCoreState","type":"error"},{"inputs":[],"name":"IncorrectFee","type":"error"},{"inputs":[],"name":"IncorrectGameId","type":"error"},{"inputs":[],"name":"IncorrectMinBet","type":"error"},{"inputs":[],"name":"IncorrectMinDepo","type":"error"},{"inputs":[],"name":"IncorrectPercent","type":"error"},{"inputs":[],"name":"IncorrectReinforcementAbility","type":"error"},{"inputs":[],"name":"IncorrectTimestamp","type":"error"},{"inputs":[],"name":"LeafNotExist","type":"error"},{"inputs":[],"name":"LiquidityIsLocked","type":"error"},{"inputs":[],"name":"LiquidityNotOwned","type":"error"},{"inputs":[],"name":"NoLiquidity","type":"error"},{"inputs":[],"name":"NotEnoughLiquidity","type":"error"},{"inputs":[],"name":"OnlyFactory","type":"error"},{"inputs":[{"internalType":"enum SafeCast.Type","name":"to","type":"uint8"}],"name":"SafeCastError","type":"error"},{"inputs":[],"name":"SmallBet","type":"error"},{"inputs":[],"name":"SmallDepo","type":"error"},{"inputs":[],"name":"UnknownCore","type":"error"},{"inputs":[{"internalType":"uint64","name":"waitTime","type":"uint64"}],"name":"WithdrawalTimeout","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"affiliate","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AffiliateRewarded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"core","type":"address"},{"indexed":true,"internalType":"address","name":"bettor","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BettorWin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"newClaimTimeout","type":"uint64"}],"name":"ClaimTimeoutChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"core","type":"address"},{"indexed":false,"internalType":"enum ILP.CoreState","name":"state","type":"uint8"},{"indexed":false,"internalType":"uint64","name":"reinforcementAbility","type":"uint64"},{"indexed":false,"internalType":"uint128","name":"minBet","type":"uint128"}],"name":"CoreSettingsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newDataProvider","type":"address"}],"name":"DataProviderChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum ILP.FeeType","name":"feeType","type":"uint8"},{"indexed":false,"internalType":"uint64","name":"fee","type":"uint64"}],"name":"FeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"gameId","type":"uint256"}],"name":"GameCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"gameId","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"newStart","type":"uint64"}],"name":"GameShifted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint48","name":"leaf","type":"uint48"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LiquidityAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint48","name":"leaf","type":"uint48"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LiquidityRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"core","type":"address"},{"indexed":false,"internalType":"uint128","name":"newMinBet","type":"uint128"}],"name":"MinBetChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint128","name":"newMinDepo","type":"uint128"}],"name":"MinDepoChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"gameId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"ipfsHash","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"startsAt","type":"uint64"}],"name":"NewGame","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint128","name":"newReinforcementAbility","type":"uint128"}],"name":"ReinforcementAbilityChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"newWithdrawTimeout","type":"uint64"}],"name":"WithdrawTimeoutChanged","type":"event"},{"inputs":[],"name":"access","outputs":[{"internalType":"contract IAccess","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"gameId","type":"uint256"}],"name":"addCondition","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"core","type":"address"}],"name":"addCore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"amount","type":"uint128"}],"name":"addLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"addLiquidityNative","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"gameId","type":"uint256"},{"internalType":"uint128","name":"lockedReserve","type":"uint128"},{"internalType":"uint128","name":"finalReserve","type":"uint128"},{"internalType":"uint48","name":"leaf","type":"uint48"}],"name":"addReserve","outputs":[{"internalType":"uint128","name":"affiliatesReward","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"core","type":"address"},{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint64","name":"expiresAt","type":"uint64"},{"components":[{"internalType":"address","name":"affiliate","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IBet.BetData","name":"betData","type":"tuple"}],"name":"bet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"bettor","type":"address"},{"internalType":"address","name":"core","type":"address"},{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint64","name":"expiresAt","type":"uint64"},{"components":[{"internalType":"address","name":"affiliate","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IBet.BetData","name":"betData","type":"tuple"}],"name":"betFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"core","type":"address"},{"internalType":"uint64","name":"expiresAt","type":"uint64"},{"components":[{"internalType":"address","name":"affiliate","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IBet.BetData","name":"betData","type":"tuple"}],"name":"betNative","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"gameId","type":"uint256"}],"name":"cancelGame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"newClaimTimeout","type":"uint64"}],"name":"changeClaimTimeout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newDataProvider","type":"address"}],"name":"changeDataProvider","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum ILP.FeeType","name":"feeType","type":"uint8"},{"internalType":"uint64","name":"newFee","type":"uint64"}],"name":"changeFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"gameId","type":"uint256"},{"internalType":"int128","name":"deltaReserve","type":"int128"}],"name":"changeLockedLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"newMinDepo","type":"uint128"}],"name":"changeMinDepo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"newWithdrawTimeout","type":"uint64"}],"name":"changeWithdrawTimeout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"checkAccess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"core","type":"address"}],"name":"checkCore","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"checkOwner","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"core","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"claimAffiliateReward","outputs":[{"internalType":"uint256","name":"claimedAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimReward","outputs":[{"internalType":"uint256","name":"claimedAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimTimeout","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"coreAffRewards","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"cores","outputs":[{"internalType":"enum ILP.CoreState","name":"state","type":"uint8"},{"internalType":"uint64","name":"reinforcementAbility","type":"uint64"},{"internalType":"uint128","name":"minBet","type":"uint128"},{"internalType":"uint128","name":"lockedLiquidity","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"gameId","type":"uint256"},{"internalType":"bytes32","name":"ipfsHash","type":"bytes32"},{"internalType":"uint64","name":"startsAt","type":"uint64"}],"name":"createGame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dataProvider","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"contract IOwnable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"fees","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"games","outputs":[{"internalType":"bytes32","name":"ipfsHash","type":"bytes32"},{"internalType":"uint128","name":"lockedLiquidity","type":"uint128"},{"internalType":"uint64","name":"startsAt","type":"uint64"},{"internalType":"bool","name":"canceled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"gameId","type":"uint256"}],"name":"getGameInfo","outputs":[{"internalType":"uint64","name":"","type":"uint64"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLeaf","outputs":[{"internalType":"uint48","name":"leaf","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"core","type":"address"}],"name":"getLockedLiquidityLimit","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReserve","outputs":[{"internalType":"uint128","name":"reserve","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"access_","type":"address"},{"internalType":"address","name":"dataProvider_","type":"address"},{"internalType":"address","name":"token_","type":"address"},{"internalType":"uint128","name":"minDepo_","type":"uint128"},{"internalType":"uint64","name":"daoFee","type":"uint64"},{"internalType":"uint64","name":"dataProviderFee","type":"uint64"},{"internalType":"uint64","name":"affiliateFee","type":"uint64"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"gameId","type":"uint256"}],"name":"isGameCanceled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockedLiquidity","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minDepo","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextNode","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint48","name":"leaf","type":"uint48"}],"name":"nodeWithdrawView","outputs":[{"internalType":"uint128","name":"withdrawAmount","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"int128","name":"amount","type":"int128"},{"internalType":"uint64","name":"claimedAt","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"gameId","type":"uint256"},{"internalType":"uint64","name":"startsAt","type":"uint64"}],"name":"shiftGame","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":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","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":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint48","name":"","type":"uint48"}],"name":"treeNode","outputs":[{"internalType":"uint64","name":"updateId","type":"uint64"},{"internalType":"uint128","name":"amount","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"core","type":"address"},{"internalType":"enum ILP.CoreState","name":"state","type":"uint8"},{"internalType":"uint64","name":"reinforcementAbility","type":"uint64"},{"internalType":"uint128","name":"minBet","type":"uint128"}],"name":"updateCoreSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateId","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"core","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"viewPayout","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint48","name":"","type":"uint48"}],"name":"withdrawAfter","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint48","name":"depNum","type":"uint48"},{"internalType":"uint40","name":"percent","type":"uint40"},{"internalType":"bool","name":"isNative","type":"bool"}],"name":"withdrawLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"core","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bool","name":"isNative","type":"bool"}],"name":"withdrawPayout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawTimeout","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234801561001057600080fd5b50615faa80620000216000396000f3fe6080604052600436106103035760003560e01c806301ffc9a71461032657806306fdde031461035b5780630700037d1461037d578063081812fc146103e3578063095ea7b3146104105780630c6b6b7a146104305780630e1da6c314610450578063117a5b901461047e57806318160ddd14610511578063184c2be61461053057806323b872dd1461055057806323ebb4a41461057057806325aa820b146105905780632f745c59146105bd57806342842e0e146105dd5780634724201a146105fd57806347e1d5501461061057806349f565cd1461067c5780634acc79ed1461069c5780634f6ccce7146106bc578063535cacb5146106dc57806359bf5d39146106fc5780635a8d9d1514610711578063627edd70146107315780636352211e146107685780636396eb8d1461078857806365715c56146107a857806369958ab9146107de578063709e9952146107fe57806370a082311461081e578063710e71c01461083e57806371907f171461085e57806375fcb1b31461087e5780637e9488f6146108865780637f4270c1146108a65780638154f2d3146108c65780638164b4d6146108e657806385ad32c4146109065780638da5cb5b146109735780638e8dc736146109885780639207c4af146109a857806395d89b41146109c957806396577a33146109de5780639aebfea7146109fe5780639c15d1a214610a1e578063a22cb46514610a46578063a67111d714610a66578063a882206114610a86578063b334ed8614610aa6578063b439824414610ac7578063b88a802f14610aef578063b88d4fde14610b04578063bdb36f8914610b24578063be559f7a14610b44578063bfcf04cf14610b59578063c26e1b4414610b80578063c45a015514610bb7578063c87b56dd14610bd7578063cd6072e614610bf7578063d2a382b214610c66578063db1c822714610c86578063de7ad2d114610ca6578063e0e3671c14610cc6578063e2ca81f014610ce6578063e408d78814610d21578063e985e9c514610d41578063f2fde38b14610d61578063fc0c546a14610d8157600080fd5b366103215760ff546001600160a01b0316331461031f57600080fd5b005b600080fd5b34801561033257600080fd5b50610346610341366004614e77565b610da1565b60405190151581526020015b60405180910390f35b34801561036757600080fd5b50610370610dcc565b6040516103529190614ee4565b34801561038957600080fd5b506103c1610398366004614f0c565b61010660205260009081526040902054600f81900b90600160801b90046001600160401b031682565b60408051600f9390930b83526001600160401b03909116602083015201610352565b3480156103ef57600080fd5b506104036103fe366004614f29565b610e5e565b6040516103529190614f42565b34801561041c57600080fd5b5061031f61042b366004614f56565b610e85565b34801561043c57600080fd5b5061031f61044b366004614f99565b610f9f565b34801561045c57600080fd5b5061010254610471906001600160401b031681565b6040516103529190614fce565b34801561048a57600080fd5b506104d9610499366004614f29565b61010460205260009081526040902080546001909101546001600160801b03811690600160801b81046001600160401b031690600160c01b900460ff1684565b604080519485526001600160801b0390931660208501526001600160401b039091169183019190915215156060820152608001610352565b34801561051d57600080fd5b5060cd545b604051908152602001610352565b34801561053c57600080fd5b5061052261054b366004615009565b6110b1565b34801561055c57600080fd5b5061031f61056b36600461508e565b6110f6565b34801561057c57600080fd5b5061031f61058b3660046150dc565b611127565b34801561059c57600080fd5b506105b06105ab366004614f56565b6111ca565b6040516103529190615111565b3480156105c957600080fd5b506105226105d8366004614f56565b611249565b3480156105e957600080fd5b5061031f6105f836600461508e565b6112df565b61052261060b366004615125565b6112fa565b34801561061c57600080fd5b5061065d61062b366004614f29565b60009081526101046020526040902060010154600160801b81046001600160401b031691600160c01b90910460ff1690565b604080516001600160401b039093168352901515602083015201610352565b34801561068857600080fd5b5061031f610697366004615192565b611385565b3480156106a857600080fd5b506104716106b7366004614f29565b61150b565b3480156106c857600080fd5b506105226106d7366004614f29565b61153f565b3480156106e857600080fd5b5061031f6106f73660046151d4565b6115d2565b34801561070857600080fd5b506105b0611829565b34801561071d57600080fd5b5061031f61072c366004615262565b611856565b34801561073d57600080fd5b506105b061074c366004614f0c565b610108602052600090815260409020546001600160801b031681565b34801561077457600080fd5b50610403610783366004614f29565b6119a4565b34801561079457600080fd5b5061031f6107a33660046152bc565b6119d8565b3480156107b457600080fd5b506000546107c79065ffffffffffff1681565b60405165ffffffffffff9091168152602001610352565b3480156107ea57600080fd5b5061031f6107f9366004614f29565b611a54565b34801561080a57600080fd5b5061031f6108193660046152fc565b611b36565b34801561082a57600080fd5b50610522610839366004614f0c565b611b63565b34801561084a57600080fd5b506105b0610859366004614f0c565b611be9565b34801561086a57600080fd5b5060fe54610403906001600160a01b031681565b61031f611c2d565b34801561089257600080fd5b506105226108a1366004615319565b611ca9565b3480156108b257600080fd5b506105b06108c13660046153a1565b611cdd565b3480156108d257600080fd5b506105b06108e13660046153bc565b611e0c565b3480156108f257600080fd5b5061031f6109013660046152fc565b612201565b34801561091257600080fd5b50610963610921366004614f0c565b610103602052600090815260409020805460019091015460ff8216916001600160401b03610100820416916001600160801b03600160481b9092048216911684565b6040516103529493929190615433565b34801561097f57600080fd5b5061040361228b565b34801561099457600080fd5b5061031f6109a336600461546e565b61229a565b3480156109b457600080fd5b50610101546105b0906001600160801b031681565b3480156109d557600080fd5b506103706122f8565b3480156109ea57600080fd5b5061031f6109f9366004615489565b612307565b348015610a0a57600080fd5b5061031f610a19366004614f0c565b61249f565b348015610a2a57600080fd5b506101025461047190600160401b90046001600160401b031681565b348015610a5257600080fd5b5061031f610a613660046154bf565b612535565b348015610a7257600080fd5b50610522610a813660046154ed565b612544565b348015610a9257600080fd5b5061031f610aa1366004615571565b612620565b348015610ab257600080fd5b5061010054610403906001600160a01b031681565b348015610ad357600080fd5b50610101546105b090600160801b90046001600160801b031681565b348015610afb57600080fd5b506105226126a7565b348015610b1057600080fd5b5061031f610b1f366004615636565b61277b565b348015610b3057600080fd5b50610471610b3f366004614f29565b6127b3565b348015610b5057600080fd5b506107c7612817565b348015610b6557600080fd5b5060005461047190600160301b90046001600160401b031681565b348015610b8c57600080fd5b50610471610b9b3660046153a1565b610107602052600090815260409020546001600160401b031681565b348015610bc357600080fd5b5060fd54610403906001600160a01b031681565b348015610be357600080fd5b50610370610bf2366004614f29565b612834565b348015610c0357600080fd5b50610c3f610c123660046153a1565b6001602052600090815260409020546001600160401b03811690600160401b90046001600160801b031682565b604080516001600160401b0390931683526001600160801b03909116602083015201610352565b348015610c7257600080fd5b5061031f610c8136600461546e565b6128a8565b348015610c9257600080fd5b5061031f610ca1366004614f0c565b6128fd565b348015610cb257600080fd5b5061031f610cc1366004614f0c565b612952565b348015610cd257600080fd5b5061031f610ce1366004614f0c565b61298c565b348015610cf257600080fd5b50610346610d01366004614f29565b60009081526101046020526040902060010154600160c01b900460ff1690565b348015610d2d57600080fd5b5061031f610d3c366004615695565b6129fe565b348015610d4d57600080fd5b50610346610d5c3660046156dd565b612aac565b348015610d6d57600080fd5b5061031f610d7c366004614f0c565b612ada565b348015610d8d57600080fd5b5060ff54610403906001600160a01b031681565b60006001600160e01b0319821663780e9d6360e01b1480610dc65750610dc682612b51565b92915050565b606060998054610ddb9061570b565b80601f0160208091040260200160405190810160405280929190818152602001828054610e079061570b565b8015610e545780601f10610e2957610100808354040283529160200191610e54565b820191906000526020600020905b815481529060010190602001808311610e3757829003601f168201915b5050505050905090565b6000610e6982612ba1565b506000908152609d60205260409020546001600160a01b031690565b6000610e90826119a4565b9050806001600160a01b0316836001600160a01b031603610f025760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b0382161480610f1e5750610f1e8133612aac565b610f905760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610ef9565b610f9a8383612bc6565b505050565b630635b5bd60e11b610fb23330836119d8565b6000848152610104602052604090206001810154600160801b90046001600160401b031615610ff4576040516346a9b15d60e01b815260040160405180910390fd5b84600003611015576040516371da551f60e11b815260040160405180910390fd5b42836001600160401b0316101561103f5760405163686c69fd60e01b815260040160405180910390fd5b838155600181018054600160801b600160c01b031916600160801b6001600160401b0386169081029190911790915560408051868152602081019290925286917f13e7611f15031843c0158f76bc4d04d132ae6a98d7250430645b367c3ec4ba08910160405180910390a25050505050565b60ff546000906110d5906001600160a01b031633306001600160801b038816612c34565b6110ea868686866110e58761573f565b612d6a565b90505b95945050505050565b6111003382612e90565b61111c5760405162461bcd60e51b8152600401610ef9906157b4565b610f9a838383612eee565b6111303361298c565b806101058360028111156111465761114661540d565b6003811061115657611156615801565b600491828204019190066008026101000a8154816001600160401b0302191690836001600160401b0316021790555061118d61304b565b7fe1fa3eb1a7d6742cc114a9e0bb7fea501c069f767320079521d8a45ef2b40bfb82826040516111be929190615817565b60405180910390a15050565b6000826111d681612952565b604051632589867d60e01b8152600481018490526001600160a01b03851690632589867d90602401602060405180830381865afa15801561121b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123f919061583c565b91505b5092915050565b600061125483611b63565b82106112b65760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610ef9565b506001600160a01b0391909116600090815260cb60209081526040808320938352929052205490565b610f9a8383836040518060200160405280600081525061277b565b600060ff60009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561134c57600080fd5b505af1158015611360573d6000803e3d6000fd5b505050505061137d3385611373346130ab565b866110e58761573f565b949350505050565b8261138f81612952565b604051637e40cb6b60e11b81526004810184905260009081906001600160a01b0387169063fc8196d69060240160408051808303816000875af11580156113da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113fe9190615859565b90925090506001600160801b0381161561150357604080518681526001600160801b03831660208201526001600160a01b0380851692908916917f53df85a6d27721f38c9c99d095a4c565f68a5e74f22f17c711578461253cbef2910160405180910390a383156114e35760ff54604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d90611499908490600401615111565b600060405180830381600087803b1580156114b357600080fd5b505af11580156114c7573d6000803e3d6000fd5b505050506114de82826001600160801b03166130dc565b611503565b60ff54611503906001600160a01b0316836001600160801b0384166131b6565b505050505050565b610105816003811061151c57600080fd5b60049182820401919006600802915054906101000a90046001600160401b031681565b600061154a60cd5490565b82106115ad5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610ef9565b60cd82815481106115c0576115c0615801565b90600052602060002001549050919050565b600254610100900460ff16158080156115f25750600254600160ff909116105b806116135750611601306132e7565b158015611613575060025460ff166001145b6116765760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610ef9565b6002805460ff191660011790558015611699576002805461ff0019166101001790555b846001600160801b03166000036116c35760405163fa6bfc6d60e01b815260040160405180910390fd5b6116cb6132f6565b61171d6040518060400160405280601281526020017120bd3ab9379026281027232a103a37b5b2b760711b81525060405180604001604052806006815260200165262816a0ad2960d11b81525061332d565b61172561335e565b60fd80546001600160a01b0319908116331790915560fe80546001600160a01b038b81169184169190911790915561010080548a831690841617905560ff80549189169190921617905561010580546001600160401b03858116600160401b026001600160801b03199092168782161791909117600160801b600160c01b031916600160801b918516919091021790556117bd61304b565b61010180546001600160801b0319166001600160801b038716179055801561181f576002805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b60016000819052602052600080516020615f1583398151915254600160401b90046001600160801b031690565b61185f3361298c565b8361186981612952565b816001600160801b03166000036118935760405163cad66eef60e01b815260040160405180910390fd5b64e8d4a51000836001600160401b031611156118c25760405163c6e3629b60e01b815260040160405180910390fd5b60008460028111156118d6576118d661540d565b036118f457604051635b10d6dd60e01b815260040160405180910390fd5b6001600160a01b0385166000908152610103602052604090208054610100600160c81b031916600160481b6001600160801b03851602610100600160481b031916176101006001600160401b03861602178082558590829060ff191660018360028111156119645761196461540d565b0217905550856001600160a01b0316600080516020615f5583398151915286868660405161199493929190615888565b60405180910390a2505050505050565b6000806119b0836133b8565b90506001600160a01b038116610dc65760405162461bcd60e51b8152600401610ef9906158bb565b60fe54604051636396eb8d60e01b81526001600160a01b03858116600483015284811660248301526001600160e01b03198416604483015290911690636396eb8d90606401600060405180830381600087803b158015611a3757600080fd5b505af1158015611a4b573d6000803e3d6000fd5b50505050505050565b6369958ab960e01b611a673330836119d8565b6000611a72836133d3565b6001810154909150600160c01b900460ff1615611aa25760405163c076a8db60e01b815260040160405180910390fd5b600181015461010180546001600160801b0392831692601091611ace918591600160801b900416615903565b82546001600160801b039182166101009390930a92830291909202199091161790555060018101805460ff60c01b1916600160c01b17905560405183907f8f1ffb72cf9e5acc4eddafab2be9e2951d12377b9e1e4bdc7bd686b19c91fd8990600090a2505050565b60ff54611b57906001600160a01b031633306001600160801b038516612c34565b611b6081613416565b50565b60006001600160a01b038216611bcd5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610ef9565b506001600160a01b03166000908152609c602052604090205490565b6000610dc6611bf6611829565b6001600160a01b0384166000908152610103602052604090205461010090046001600160401b0316906001600160801b0316613503565b60ff60009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611c7d57600080fd5b505af1158015611c91573d6000803e3d6000fd5b5050505050611ca7611ca2346130ab565b613416565b565b60ff54600090611ccd906001600160a01b031633306001600160801b038816612c34565b6110ed338686866110e58761573f565b6000600160281b65ffffffffffff83161080611d2257506001611d05600160281b6002615923565b611d0f9190615951565b65ffffffffffff168265ffffffffffff16115b15611d2f57506000919050565b65ffffffffffff82166000908152600160205260408120546001600160401b03169003611d5e57506000919050565b600160008181526020829052600080516020615f1583398151915254909182918291611dcb916001600160401b0316600160281b82611d9e826002615923565b611da89190615951565b6001600160281b81611dbb826002615923565b611dc59190615951565b8c61351f565b65ffffffffffff831660009081526001602052604090205492955090935091506110ed908490849084908990600160401b90046001600160801b031661363b565b600033611e1881612952565b610100546001600160a01b0390811660009081526101066020818152604080842060fd548251638da5cb5b60e01b8152925191968694911692638da5cb5b92600480830193928290030181865afa158015611e77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e9b9190615970565b6001600160a01b03166001600160a01b031681526020019081526020016000209050866001600160801b0316866001600160801b03161115612094576000611ee38888615903565b9050806000611f16611f116001600160801b038416611f02600161378b565b6001600160401b031690613503565b6130ab565b8554909150611f2890600f0b826137d8565b611f329083615903565b9150611f46816001600160801b0316613828565b85548690600090611f5b908490600f0b61598d565b92506101000a8154816001600160801b030219169083600f0b6001600160801b031602179055506000611f9e611f11856001600160801b0316611f02600061378b565b8554909150611fb090600f0b826137d8565b611fba9084615903565b9250611fce816001600160801b0316613828565b85548690600090611fe3908490600f0b61598d565b92506101000a8154816001600160801b030219169083600f0b6001600160801b03160217905550612024611f11856001600160801b0316611f02600261378b565b336000908152610108602052604081208054929a508a929091906120529084906001600160801b03166159ba565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555061208b88846120859190615903565b8a61385e565b505050506121dc565b60006120a08789615903565b6001600160801b031611156121dc5760006120bb8789615903565b90508060006120da611f116001600160801b038416611f02600161378b565b85549091506120ec90600f0b82613969565b6120f69083615903565b915061210a816001600160801b0316613828565b8554869060009061211f908490600f0b6159da565b92506101000a8154816001600160801b030219169083600f0b6001600160801b031602179055506000612162611f11856001600160801b0316611f02600061378b565b855490915061217490600f0b82613969565b61217e9084615903565b9250612192816001600160801b0316613828565b855486906000906121a7908490600f0b6159da565b92506101000a8154816001600160801b030219169083600f0b6001600160801b031602179055506121d7836139a8565b505050505b6001600160801b038716156121f6576121f6338989613a64565b505050949350505050565b61220a3361298c565b806001600160801b03166000036122345760405163fa6bfc6d60e01b815260040160405180910390fd5b61010180546001600160801b0319166001600160801b0383161790556040517f483032c7f41f1ba71455a09f574b92ba07ae933719975978f96f457d4c1c98d390612280908390615111565b60405180910390a150565b6035546001600160a01b031690565b6122a33361298c565b6101028054600160401b600160801b031916600160401b6001600160401b038416021790556040517f527dd140711eb0a9177d62725055c7fe5eb62351eabf406fd3f80886ba57ea3090612280908390614fce565b6060609a8054610ddb9061570b565b3361231181613b61565b600082600f0b131561248c5781831561237457600084815261010460205260408120600101805483929061234f9084906001600160801b03166159ba565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505b33600090815261010360205260408120600181018054919284926123a29084906001600160801b03166159ba565b92506101000a8154816001600160801b0302191690836001600160801b031602179055508161010160108282829054906101000a90046001600160801b03166123eb91906159ba565b92506101000a8154816001600160801b0302191690836001600160801b031602179055506000612419611829565b610101549091506001600160801b03808316600160801b90920416118061246e5750815461245e9061010090046001600160401b03166001600160801b038316613503565b60018301546001600160801b0316115b1561150357604051634323a55560e01b815260040160405180910390fd5b610f9a338461249a85615a07565b613a64565b60fd546001600160a01b031633146124ca57604051630636a15760e11b815260040160405180910390fd5b6001600160a01b038116600081815261010360205260409081902080546001600160c81b0319166901000000e8d4a51000011781559051909190600080516020615f55833981519152906125299060019064e8d4a51000908290615888565b60405180910390a25050565b612540338383613b9b565b5050565b60008361255081612952565b6040516306c1977760e51b81526001600160a01b0386169063d832eee09061258090339088908890600401615a2a565b6020604051808303816000875af115801561259f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125c39190615a6a565b915081156126185760ff546125e2906001600160a01b031633846131b6565b60405182815233907f9b0d35bce028284da7866dad519c879899d1bb723a419c6626d10ef3daef10f39060200160405180910390a25b509392505050565b63a882206160e01b6126333330836119d8565b600061263e846133d3565b600181018054600160801b600160c01b031916600160801b6001600160401b0387160217905560405190915084907fd9d775beef68977fe4ecd3d35a3441b417b2876ea656d0a6bfb568f8ff56fa9b90612699908690614fce565b60405180910390a250505050565b336000908152610106602052604081206101025481546001600160401b03918216916126db91600160801b90041642615a83565b101561271e57610102548154612704916001600160401b0390811691600160801b900416615a96565b6040516318789e3d60e21b8152600401610ef99190614fce565b8054600f0b600081136127345760009250505090565b81546001600160c01b031916600160801b426001600160401b03160217825560ff546001600160801b0382169350612776906001600160a01b031633856131b6565b505090565b6127853383612e90565b6127a15760405162461bcd60e51b8152600401610ef9906157b4565b6127ad84848484613c65565b50505050565b6000336127bf81613b61565b60006127ca846133d3565b6001810154909150600160c01b900460ff16156127fa57604051639b83033760e01b815260040160405180910390fd5b60010154600160801b90046001600160401b031691505b50919050565b6000805461282f9060019065ffffffffffff16615951565b905090565b606061283f82612ba1565b600061285660408051602081019091526000815290565b9050600081511161287657604051806020016040528060008152506128a1565b8061288084613c98565b604051602001612891929190615ab6565b6040516020818303038152906040525b9392505050565b6128b13361298c565b61010280546001600160401b0319166001600160401b0383161790556040517f27cd37fc700f6b98651e78d699d1bcc11b859e18a8ab4948c58dbfa51572e0c990612280908390614fce565b6129063361298c565b61010080546001600160a01b0319166001600160a01b0383161790556040517f0a399af491b2850718a568553f7c18dbda624e511789ab3473b72a6a4d6d748b90612280908390614f42565b600061295d82613d2a565b600281111561296e5761296e61540d565b03611b6057604051632b3907cb60e21b815260040160405180910390fd5b806001600160a01b031661299e61228b565b6001600160a01b031614611b605760405162461bcd60e51b815260206004820152602160248201527f4f776e61626c653a206163636f756e74206973206e6f7420746865206f776e656044820152603960f91b6064820152608401610ef9565b6000612a0a8484613d49565b90508115612a8c5760ff54604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d90612a42908490600401615111565b600060405180830381600087803b158015612a5c57600080fd5b505af1158015612a70573d6000803e3d6000fd5b50505050612a8733826001600160801b03166130dc565b6127ad565b60ff546127ad906001600160a01b0316336001600160801b0384166131b6565b6001600160a01b039182166000908152609e6020908152604080832093909416825291909152205460ff1690565b612ae33361298c565b6001600160a01b038116612b485760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610ef9565b611b6081613f17565b60006001600160e01b031982166380ac58cd60e01b1480612b8257506001600160e01b03198216635b5e139f60e01b145b80610dc657506301ffc9a760e01b6001600160e01b0319831614610dc6565b612baa81613f69565b611b605760405162461bcd60e51b8152600401610ef9906158bb565b6000818152609d6020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612bfb826119a4565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691612c989190615ae5565b6000604051808303816000865af19150503d8060008114612cd5576040519150601f19603f3d011682016040523d82523d6000602084013e612cda565b606091505b5091509150818015612d04575080511580612d04575080806020019051810190612d049190615b01565b6115035760405162461bcd60e51b815260206004820152603160248201527f5472616e7366657248656c7065723a3a7472616e7366657246726f6d3a207472604482015270185b9cd9995c919c9bdb4819985a5b1959607a1b6064820152608401610ef9565b600084612d7681613b61565b836001600160401b03164210612d9f57604051637a0ef04360e11b815260040160405180910390fd5b6001600160a01b038616600090815261010360205260409020546001600160801b03600160481b90910481169086161015612ded57604051632fb3e82760e01b815260040160405180910390fd5b82516001600160a01b0316612e1057612e0461228b565b6001600160a01b031683525b604051634ab029db60e11b81526001600160a01b0387169063956053b690612e40908a9089908890600401615b1e565b6020604051808303816000875af1158015612e5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e839190615a6a565b91505b5095945050505050565b600080612e9c836119a4565b9050806001600160a01b0316846001600160a01b03161480612ec35750612ec38185612aac565b8061123f5750836001600160a01b0316612edc84610e5e565b6001600160a01b031614949350505050565b826001600160a01b0316612f01826119a4565b6001600160a01b031614612f275760405162461bcd60e51b8152600401610ef990615b6e565b6001600160a01b038216612f895760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610ef9565b612f94838383613f86565b826001600160a01b0316612fa7826119a4565b6001600160a01b031614612fcd5760405162461bcd60e51b8152600401610ef990615b6e565b6000818152609d6020908152604080832080546001600160a01b03199081169091556001600160a01b03878116808652609c8552838620805460001901905590871680865283862080546001019055868652609b9094528285208054909216841790915590518493600080516020615f3583398151915291a4505050565b64e8d4a5100061305b600261378b565b613065600161378b565b61306f600061378b565b6130799190615a96565b6130839190615a96565b6001600160401b03161115611ca75760405163cd3cb2bb60e01b815260040160405180910390fd5b60006001600160801b038211156130d8576003604051639b3137df60e01b8152600401610ef99190615bb3565b5090565b604080516000808252602082019092526001600160a01b0384169083906040516131069190615ae5565b60006040518083038185875af1925050503d8060008114613143576040519150601f19603f3d011682016040523d82523d6000602084013e613148565b606091505b5050905080610f9a5760405162461bcd60e51b815260206004820152603460248201527f5472616e7366657248656c7065723a3a736166655472616e736665724554483a60448201527308115512081d1c985b9cd9995c8819985a5b195960621b6064820152608401610ef9565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291516000928392908716916132129190615ae5565b6000604051808303816000865af19150503d806000811461324f576040519150601f19603f3d011682016040523d82523d6000602084013e613254565b606091505b509150915081801561327e57508051158061327e57508080602001905181019061327e9190615b01565b6132e05760405162461bcd60e51b815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201526c185b9cd9995c8819985a5b1959609a1b6064820152608401610ef9565b5050505050565b6001600160a01b03163b151590565b600254610100900460ff1661331d5760405162461bcd60e51b8152600401610ef990615bcd565b61332561403e565b611ca7614065565b600254610100900460ff166133545760405162461bcd60e51b8152600401610ef990615bcd565b6125408282614095565b6000805465ffffffffffff1916600160281b178082556001600160401b03600160301b9091041690600661339183615c18565b91906101000a8154816001600160401b0302191690836001600160401b0316021790555050565b6000908152609b60205260409020546001600160a01b031690565b6000818152610104602052604081206001810154600160801b90046001600160401b03168203610dc6576040516387aeb83d60e01b815260040160405180910390fd5b610101546001600160801b039081169082161015613447576040516320d3137f60e01b815260040160405180910390fd5b6000613452826140d5565b6101025490915061347390600160401b90046001600160401b031642615a96565b65ffffffffffff821660008181526101076020526040902080546001600160401b0319166001600160401b0393909316929092179091556134b5903390614164565b8065ffffffffffff16336001600160a01b03167f04aea1979a2b879b0578efc9fb3e03cd6ae3bdc964f047e81f526ea2350967e5846040516134f79190615111565b60405180910390a35050565b600064e8d4a510006135158385615c46565b6128a19190615c7b565b65ffffffffffff8416600090815260016020526040812054819081906001600160401b03808c169116101561355b57508991508790508661362d565b8365ffffffffffff168765ffffffffffff160361357f57508291508490508361362d565b6000600261358d8789615c8f565b6135979190615cae565b90508465ffffffffffff168765ffffffffffff16111580156135c957508065ffffffffffff168565ffffffffffff1611155b156135f4576135e8888c89896135e0846002615923565b8c878c61351f565b9195509350915061362b565b613623888c8989613606846002615923565b613611906001615c8f565b61361c876001615c8f565b8c8c61351f565b919550935091505b505b985098509895505050505050565b60008265ffffffffffff168665ffffffffffff160361365b5750806110ed565b6000613668876002615923565b90506000613677886002615923565b613682906001615c8f565b65ffffffffffff8084166000908152600160205260408082205492841682528120549293506001600160801b03600160401b9283900481169391926136c992041683615cd3565b9050806000036136e05760009450505050506110ed565b6000816136f6846001600160801b038a16615c46565b6137009190615c7b565b9050600060026137108b8d615c8f565b61371a9190615cae565b90508865ffffffffffff168b65ffffffffffff161115801561374c57508065ffffffffffff168965ffffffffffff1611155b1561376b5761375e868c838c8661363b565b96505050505050506110ed565b61375e8561377a836001615c8f565b8c8c613786878e615903565b61363b565b60006101058260028111156137a2576137a261540d565b600381106137b2576137b2615801565b600491828204019190066008029054906101000a90046001600160401b03169050919050565b60008083600f0b12156138215760006137f9836001600160801b0316613828565b613803908561598d565b9050600081600f0b13613817576000613819565b805b915050610dc6565b5080610dc6565b600060016001607f1b036001600160801b03831611156130d8576001604051639b3137df60e01b8152600401610ef99190615bb3565b600160008181526020829052600080516020615f15833981519152549091829182916138cb916001600160401b0316600160281b8261389e826002615923565b6138a89190615951565b6001600160281b816138bb826002615923565b6138c59190615951565b8b61351f565b6000549295509093509150600160301b90046001600160401b03166138fe848484886138f686615c18565b95508561426b565b6139386001600160281b81613914826002615923565b61391e9190615951565b600160281b898b600061393089615c18565b9850886143e1565b600080546001600160401b03909216600160301b02600160301b600160701b03199092169190911790555050505050565b60008083600f0b1261399f57613987826001600160801b0316613828565b600f0b83600f0b1361399957826128a1565b816128a1565b50600092915050565b60016000819052602052600080516020615f15833981519152546001600160801b03808316600160401b9092041610611b6057611b606001600160281b816139f1826002615923565b6139fb9190615951565b600054600160281b90613a189060019065ffffffffffff16615951565b8660016000600681819054906101000a90046001600160401b0316613a3c90615c18565b91906101000a8154816001600160401b0302191690836001600160401b0316021790556143e1565b8115613aba576000828152610104602052604081206001018054839290613a959084906001600160801b0316615903565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505b6001600160a01b0383166000908152610103602052604081206001018054839290613aef9084906001600160801b0316615903565b92506101000a8154816001600160801b0302191690836001600160801b031602179055508061010160108282829054906101000a90046001600160801b0316613b389190615903565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550505050565b6001613b6c82613d2a565b6002811115613b7d57613b7d61540d565b14611b6057604051630324ec9560e41b815260040160405180910390fd5b816001600160a01b0316836001600160a01b031603613bf85760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b6044820152606401610ef9565b6001600160a01b038381166000818152609e6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b613c70848484612eee565b613c7c8484848461463e565b6127ad5760405162461bcd60e51b8152600401610ef990615ce6565b60606000613ca583614743565b60010190506000816001600160401b03811115613cc457613cc4615594565b6040519080825280601f01601f191660200182016040528015613cee576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084613cf857509392505050565b6001600160a01b03166000908152610103602052604090205460ff1690565b65ffffffffffff82166000908152610107602052604081205442906001600160401b03908116908216811115613d9d57613d838282615d38565b604051633ca8f33960e11b8152600401610ef99190614fce565b613dae8565ffffffffffff166119a4565b6001600160a01b0316336001600160a01b031614613ddf57604051633ce20b5960e11b815260040160405180910390fd5b61010254613dfd90600160401b90046001600160401b031683615a96565b65ffffffffffff861660009081526101076020526040812080546001600160401b0319166001600160401b039390931692909217909155613e3c611829565b9050613e488686614819565b9350836001600160801b0316600003613e7457604051636180f03f60e11b815260040160405180910390fd5b61010154613e9290600160801b90046001600160801b031682615903565b6001600160801b0316846001600160801b03161115613ec457604051636bac637f60e01b815260040160405180910390fd5b8565ffffffffffff16336001600160a01b03167f6cf9643c04552344f0a92825c122b0a19d0b217bbeec89f3444755e3899f854f86604051613f069190615111565b60405180910390a350505092915050565b603580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600080613f75836133b8565b6001600160a01b0316141592915050565b6001600160a01b038316613fe157613fdc8160cd8054600083815260ce60205260408120829055600182018355919091527f83978b4c69c48dd978ab43fe30f077615294f938fb7f936d9eb340e51ea7db2e0155565b614004565b816001600160a01b0316836001600160a01b0316146140045761400483826149a6565b6001600160a01b03821661401b57610f9a81614a43565b826001600160a01b0316826001600160a01b031614610f9a57610f9a8282614af2565b600254610100900460ff16611ca75760405162461bcd60e51b8152600401610ef990615bcd565b600254610100900460ff1661408c5760405162461bcd60e51b8152600401610ef990615bcd565b611ca733613f17565b600254610100900460ff166140bc5760405162461bcd60e51b8152600401610ef990615bcd565b60996140c88382615d9e565b50609a610f9a8282615d9e565b6000805465ffffffffffff1681806140ec83615e5d565b91906101000a81548165ffffffffffff021916908365ffffffffffff160217905550905061415f8183600080600681819054906101000a90046001600160401b031661413790615c18565b91906101000a8154816001600160401b0302191690836001600160401b031602179055614b36565b919050565b6001600160a01b0382166141ba5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610ef9565b6141c381613f69565b156141e05760405162461bcd60e51b8152600401610ef990615e78565b6141ec60008383613f86565b6141f581613f69565b156142125760405162461bcd60e51b8152600401610ef990615e78565b6001600160a01b0382166000818152609c6020908152604080832080546001019055848352609b90915280822080546001600160a01b031916841790555183929190600080516020615f35833981519152908290a45050565b8165ffffffffffff168565ffffffffffff1603156132e0576000614290866002615923565b9050600061429f876002615923565b6142aa906001615c8f565b65ffffffffffff808916600090815260016020526040808220548684168352818320549385168352908220549394506001600160801b03600160401b91829004811694938290048116939190910416906143048284615cd3565b905080600003614319575050505050506132e0565b60008161432f856001600160801b038816615c46565b6143399190615c7b565b905061434687828a614b7f565b61435a866143548388615903565b8a614b7f565b600060026143688c8e615c8f565b6143729190615cae565b90508965ffffffffffff168c65ffffffffffff16111580156143a457508065ffffffffffff168a65ffffffffffff1611155b156143bb576143b6888d838d8d61426b565b6143d2565b6143d2876143ca836001615c8f565b8d8d8d61426b565b50505050505050505050505050565b8465ffffffffffff168765ffffffffffff1614801561440f57508365ffffffffffff168665ffffffffffff16145b8061442957508565ffffffffffff168765ffffffffffff16145b1561443f5761443a88848484614bf8565b61181f565b6000600261444d888a615c8f565b6144579190615cae565b90508465ffffffffffff168865ffffffffffff161115801561448957508065ffffffffffff168565ffffffffffff1611155b156144ad576144a861449c8a6002615923565b898389898989896143e1565b614627565b60006001816144bd8c6002615923565b65ffffffffffff1681526020810191909152604001600090812054600160401b90046001600160801b0316915084156144f757600061452d565b61452d6145058c6002615923565b614510906001615c8f565b61451b856001615c8f565b8b6145278b6001615c8f565b8d614cf5565b6001600061453c8e6002615923565b614547906001615c8f565b65ffffffffffff16815260208101919091526040016000205461457a9190600160401b90046001600160801b0316615903565b6001600160801b0316905060006145918284615cd3565b9050806000036145a4575050505061181f565b6000816145ba856001600160801b038b16615c46565b6145c49190615c7b565b90506145e06145d48e6002615923565b8d878d89868d8d6143e1565b6146226145ee8e6002615923565b6145f9906001615c8f565b614604876001615c8f565b8d614610896001615c8f565b8d61461b878f615903565b8d8d6143e1565b505050505b61463389858585614bf8565b505050505050505050565b6000614652846001600160a01b03166132e7565b1561473b57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614689903390899088908890600401615eae565b6020604051808303816000875af19250505080156146c4575060408051601f3d908101601f191682019092526146c191810190615ee1565b60015b614721573d8080156146f2576040519150601f19603f3d011682016040523d82523d6000602084013e6146f7565b606091505b5080516000036147195760405162461bcd60e51b8152600401610ef990615ce6565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061137d565b50600161137d565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106147825772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6904ee2d6d415b85acef8160201b83106147ac576904ee2d6d415b85acef8160201b830492506020015b662386f26fc1000083106147ca57662386f26fc10000830492506010015b6305f5e10083106147e2576305f5e100830492506008015b61271083106147f657612710830492506004015b60648310614808576064830492506002015b600a8310610dc65760010192915050565b65ffffffffffff82166000908152600160205260408120546001600160401b0316810361485957604051631b2862ff60e21b815260040160405180910390fd5b64e8d4a510008264ffffffffff16111561488657604051635a60b01360e01b815260040160405180910390fd5b600160008181526020829052600080516020615f15833981519152549091829182916148f3916001600160401b0316600160281b826148c6826002615923565b6148d09190615951565b6001600160281b816148e3826002615923565b6148ed9190615951565b8d61351f565b6000549295509093509150600160301b90046001600160401b031661491e8484848a6138f686615c18565b65ffffffffffff87166000908152600160205260409020546149589064ffffffffff881690600160401b90046001600160801b0316613503565b94506149728786600161496a85615c18565b945084614b36565b600080546001600160401b03909216600160301b02600160301b600160701b03199092169190911790555091949350505050565b600060016149b384611b63565b6149bd9190615a83565b600083815260cc6020526040902054909150808214614a10576001600160a01b038416600090815260cb60209081526040808320858452825280832054848452818420819055835260cc90915290208190555b50600091825260cc602090815260408084208490556001600160a01b03909416835260cb81528383209183525290812055565b60cd54600090614a5590600190615a83565b600083815260ce602052604081205460cd8054939450909284908110614a7d57614a7d615801565b906000526020600020015490508060cd8381548110614a9e57614a9e615801565b600091825260208083209091019290925582815260ce909152604080822084905585825281205560cd805480614ad657614ad6615efe565b6001900381819060005260206000200160009055905550505050565b6000614afd83611b63565b6001600160a01b03909316600090815260cb60209081526040808320868452825280832085905593825260cc9052919091209190915550565b614b4284848484614bf8565b8365ffffffffffff166001146127ad576127ad60018565ffffffffffff1611614b6c576001614b77565b614b77600286615cae565b848484614b36565b65ffffffffffff83166000908152600160205260409020546001600160801b03838116600160401b9092041614610f9a5765ffffffffffff8316600090815260016020526040902080546001600160801b038416600160401b026001600160c01b03199091166001600160401b03841617179055505050565b65ffffffffffff8416600090815260016020526040902080546001600160401b0319166001600160401b0383161790558115614c915765ffffffffffff841660009081526001602052604090208054849190600890614c68908490600160401b90046001600160801b0316615903565b92506101000a8154816001600160801b0302191690836001600160801b031602179055506127ad565b65ffffffffffff841660009081526001602052604090208054849190600890614ccb908490600160401b90046001600160801b03166159ba565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555050505050565b60008265ffffffffffff168565ffffffffffff16148015614d2557508165ffffffffffff168465ffffffffffff16145b80614d3f57508365ffffffffffff168565ffffffffffff16145b15614d72575065ffffffffffff8516600090815260016020526040902054600160401b90046001600160801b03166110ed565b60006002614d808688615c8f565b614d8a9190615cae565b90508365ffffffffffff168665ffffffffffff1611158015614dbc57508065ffffffffffff168465ffffffffffff1611155b15614e2b57614dd8614dcf886002615923565b87838785614cf5565b614de290836159ba565b9150614e1a614df2886002615923565b614dfd906001615c8f565b614e08836001615c8f565b87614e14856001615c8f565b87614cf5565b614e2490836159ba565b9150612e86565b614e57614e39886002615923565b614e44906001615c8f565b614e4f836001615c8f565b878787614cf5565b612e8390836159ba565b6001600160e01b031981168114611b6057600080fd5b600060208284031215614e8957600080fd5b81356128a181614e61565b60005b83811015614eaf578181015183820152602001614e97565b50506000910152565b60008151808452614ed0816020860160208601614e94565b601f01601f19169290920160200192915050565b6020815260006128a16020830184614eb8565b6001600160a01b0381168114611b6057600080fd5b600060208284031215614f1e57600080fd5b81356128a181614ef7565b600060208284031215614f3b57600080fd5b5035919050565b6001600160a01b0391909116815260200190565b60008060408385031215614f6957600080fd5b8235614f7481614ef7565b946020939093013593505050565b80356001600160401b038116811461415f57600080fd5b600080600060608486031215614fae57600080fd5b8335925060208401359150614fc560408501614f82565b90509250925092565b6001600160401b0391909116815260200190565b6001600160801b0381168114611b6057600080fd5b60006040828403121561281157600080fd5b600080600080600060a0868803121561502157600080fd5b853561502c81614ef7565b9450602086013561503c81614ef7565b9350604086013561504c81614fe2565b925061505a60608701614f82565b915060808601356001600160401b0381111561507557600080fd5b61508188828901614ff7565b9150509295509295909350565b6000806000606084860312156150a357600080fd5b83356150ae81614ef7565b925060208401356150be81614ef7565b929592945050506040919091013590565b60038110611b6057600080fd5b600080604083850312156150ef57600080fd5b82356150fa816150cf565b915061510860208401614f82565b90509250929050565b6001600160801b0391909116815260200190565b60008060006060848603121561513a57600080fd5b833561514581614ef7565b925061515360208501614f82565b915060408401356001600160401b0381111561516e57600080fd5b61517a86828701614ff7565b9150509250925092565b8015158114611b6057600080fd5b6000806000606084860312156151a757600080fd5b83356151b281614ef7565b92506020840135915060408401356151c981615184565b809150509250925092565b600080600080600080600060e0888a0312156151ef57600080fd5b87356151fa81614ef7565b9650602088013561520a81614ef7565b9550604088013561521a81614ef7565b9450606088013561522a81614fe2565b935061523860808901614f82565b925061524660a08901614f82565b915061525460c08901614f82565b905092959891949750929550565b6000806000806080858703121561527857600080fd5b843561528381614ef7565b93506020850135615293816150cf565b92506152a160408601614f82565b915060608501356152b181614fe2565b939692955090935050565b6000806000606084860312156152d157600080fd5b83356152dc81614ef7565b925060208401356152ec81614ef7565b915060408401356151c981614e61565b60006020828403121561530e57600080fd5b81356128a181614fe2565b6000806000806080858703121561532f57600080fd5b843561533a81614ef7565b9350602085013561534a81614fe2565b925061535860408601614f82565b915060608501356001600160401b0381111561537357600080fd5b61537f87828801614ff7565b91505092959194509250565b803565ffffffffffff8116811461415f57600080fd5b6000602082840312156153b357600080fd5b6128a18261538b565b600080600080608085870312156153d257600080fd5b8435935060208501356153e481614fe2565b925060408501356153f481614fe2565b91506154026060860161538b565b905092959194509250565b634e487b7160e01b600052602160045260246000fd5b60038110611b6057611b6061540d565b6080810161544086615423565b9481526001600160401b039390931660208401526001600160801b0391821660408401521660609091015290565b60006020828403121561548057600080fd5b6128a182614f82565b6000806040838503121561549c57600080fd5b82359150602083013580600f0b81146154b457600080fd5b809150509250929050565b600080604083850312156154d257600080fd5b82356154dd81614ef7565b915060208301356154b481615184565b60008060006040848603121561550257600080fd5b833561550d81614ef7565b925060208401356001600160401b038082111561552957600080fd5b818601915086601f83011261553d57600080fd5b81358181111561554c57600080fd5b87602082850101111561555e57600080fd5b6020830194508093505050509250925092565b6000806040838503121561558457600080fd5b8235915061510860208401614f82565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126155bb57600080fd5b81356001600160401b03808211156155d5576155d5615594565b604051601f8301601f19908116603f011681019082821181831017156155fd576155fd615594565b8160405283815286602085880101111561561657600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806080858703121561564c57600080fd5b843561565781614ef7565b9350602085013561566781614ef7565b92506040850135915060608501356001600160401b0381111561568957600080fd5b61537f878288016155aa565b6000806000606084860312156156aa57600080fd5b6156b38461538b565b9250602084013564ffffffffff811681146156cd57600080fd5b915060408401356151c981615184565b600080604083850312156156f057600080fd5b82356156fb81614ef7565b915060208301356154b481614ef7565b600181811c9082168061571f57607f821691505b60208210810361281157634e487b7160e01b600052602260045260246000fd5b60006040823603121561575157600080fd5b604080519081016001600160401b03808211838310171561577457615774615594565b816040528435915061578582614ef7565b9082526020840135908082111561579b57600080fd5b506157a8368286016155aa565b60208301525092915050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b6040810161582484615423565b9281526001600160401b039190911660209091015290565b60006020828403121561584e57600080fd5b81516128a181614fe2565b6000806040838503121561586c57600080fd5b825161587781614ef7565b60208401519092506154b481614fe2565b6060810161589585615423565b9381526001600160401b039290921660208301526001600160801b031660409091015290565b602080825260189082015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6001600160801b03828116828216039080821115611242576112426158ed565b600065ffffffffffff80831681851681830481118215151615615948576159486158ed565b02949350505050565b65ffffffffffff828116828216039080821115611242576112426158ed565b60006020828403121561598257600080fd5b81516128a181614ef7565b600f81810b9083900b0160016001607f1b03811360016001607f1b031982121715610dc657610dc66158ed565b6001600160801b03818116838216019080821115611242576112426158ed565b600f82810b9082900b0360016001607f1b0319811260016001607f1b0382131715610dc657610dc66158ed565b6000600f82900b6001607f1b8101615a2157615a216158ed565b60000392915050565b6001600160a01b03841681526040602082018190528101829052818360608301376000818301606090810191909152601f909201601f1916010192915050565b600060208284031215615a7c57600080fd5b5051919050565b81810381811115610dc657610dc66158ed565b6001600160401b03818116838216019080821115611242576112426158ed565b60008351615ac8818460208801614e94565b835190830190615adc818360208801614e94565b01949350505050565b60008251615af7818460208701614e94565b9190910192915050565b600060208284031215615b1357600080fd5b81516128a181615184565b600060018060a01b03808616835260018060801b03851660208401526060604084015280845116606084015250602083015160406080840152615b6460a0840182614eb8565b9695505050505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b6020810160048310615bc757615bc761540d565b91905290565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60006001600160401b038281166002600160401b03198101615c3c57615c3c6158ed565b6001019392505050565b6000816000190483118215151615615c6057615c606158ed565b500290565b634e487b7160e01b600052601260045260246000fd5b600082615c8a57615c8a615c65565b500490565b65ffffffffffff818116838216019080821115611242576112426158ed565b600065ffffffffffff80841680615cc757615cc7615c65565b92169190910492915050565b80820180821115610dc657610dc66158ed565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160401b03828116828216039080821115611242576112426158ed565b601f821115610f9a57600081815260208120601f850160051c81016020861015615d7f5750805b601f850160051c820191505b8181101561150357828155600101615d8b565b81516001600160401b03811115615db757615db7615594565b615dcb81615dc5845461570b565b84615d58565b602080601f831160018114615e005760008415615de85750858301515b600019600386901b1c1916600185901b178555611503565b600085815260208120601f198616915b82811015615e2f57888601518255948401946001909101908401615e10565b5085821015615e4d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600065ffffffffffff808316818103615c3c57615c3c6158ed565b6020808252601c908201527b115490cdcc8c4e881d1bdad95b88185b1c9958591e481b5a5b9d195960221b604082015260600190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906110ea90830184614eb8565b600060208284031215615ef357600080fd5b81516128a181614e61565b634e487b7160e01b600052603160045260246000fdfecc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efd108a4f6fc411b0a4df994fcad4ff1051f5d37f74abaf52fb1e1e2c54b32880fa2646970667358221220d782d9cfbb1748277b51a599a6d5e89b6f01306b0d1953707f8b4da0bcff38f564736f6c63430008100033
Deployed Bytecode
0x6080604052600436106103035760003560e01c806301ffc9a71461032657806306fdde031461035b5780630700037d1461037d578063081812fc146103e3578063095ea7b3146104105780630c6b6b7a146104305780630e1da6c314610450578063117a5b901461047e57806318160ddd14610511578063184c2be61461053057806323b872dd1461055057806323ebb4a41461057057806325aa820b146105905780632f745c59146105bd57806342842e0e146105dd5780634724201a146105fd57806347e1d5501461061057806349f565cd1461067c5780634acc79ed1461069c5780634f6ccce7146106bc578063535cacb5146106dc57806359bf5d39146106fc5780635a8d9d1514610711578063627edd70146107315780636352211e146107685780636396eb8d1461078857806365715c56146107a857806369958ab9146107de578063709e9952146107fe57806370a082311461081e578063710e71c01461083e57806371907f171461085e57806375fcb1b31461087e5780637e9488f6146108865780637f4270c1146108a65780638154f2d3146108c65780638164b4d6146108e657806385ad32c4146109065780638da5cb5b146109735780638e8dc736146109885780639207c4af146109a857806395d89b41146109c957806396577a33146109de5780639aebfea7146109fe5780639c15d1a214610a1e578063a22cb46514610a46578063a67111d714610a66578063a882206114610a86578063b334ed8614610aa6578063b439824414610ac7578063b88a802f14610aef578063b88d4fde14610b04578063bdb36f8914610b24578063be559f7a14610b44578063bfcf04cf14610b59578063c26e1b4414610b80578063c45a015514610bb7578063c87b56dd14610bd7578063cd6072e614610bf7578063d2a382b214610c66578063db1c822714610c86578063de7ad2d114610ca6578063e0e3671c14610cc6578063e2ca81f014610ce6578063e408d78814610d21578063e985e9c514610d41578063f2fde38b14610d61578063fc0c546a14610d8157600080fd5b366103215760ff546001600160a01b0316331461031f57600080fd5b005b600080fd5b34801561033257600080fd5b50610346610341366004614e77565b610da1565b60405190151581526020015b60405180910390f35b34801561036757600080fd5b50610370610dcc565b6040516103529190614ee4565b34801561038957600080fd5b506103c1610398366004614f0c565b61010660205260009081526040902054600f81900b90600160801b90046001600160401b031682565b60408051600f9390930b83526001600160401b03909116602083015201610352565b3480156103ef57600080fd5b506104036103fe366004614f29565b610e5e565b6040516103529190614f42565b34801561041c57600080fd5b5061031f61042b366004614f56565b610e85565b34801561043c57600080fd5b5061031f61044b366004614f99565b610f9f565b34801561045c57600080fd5b5061010254610471906001600160401b031681565b6040516103529190614fce565b34801561048a57600080fd5b506104d9610499366004614f29565b61010460205260009081526040902080546001909101546001600160801b03811690600160801b81046001600160401b031690600160c01b900460ff1684565b604080519485526001600160801b0390931660208501526001600160401b039091169183019190915215156060820152608001610352565b34801561051d57600080fd5b5060cd545b604051908152602001610352565b34801561053c57600080fd5b5061052261054b366004615009565b6110b1565b34801561055c57600080fd5b5061031f61056b36600461508e565b6110f6565b34801561057c57600080fd5b5061031f61058b3660046150dc565b611127565b34801561059c57600080fd5b506105b06105ab366004614f56565b6111ca565b6040516103529190615111565b3480156105c957600080fd5b506105226105d8366004614f56565b611249565b3480156105e957600080fd5b5061031f6105f836600461508e565b6112df565b61052261060b366004615125565b6112fa565b34801561061c57600080fd5b5061065d61062b366004614f29565b60009081526101046020526040902060010154600160801b81046001600160401b031691600160c01b90910460ff1690565b604080516001600160401b039093168352901515602083015201610352565b34801561068857600080fd5b5061031f610697366004615192565b611385565b3480156106a857600080fd5b506104716106b7366004614f29565b61150b565b3480156106c857600080fd5b506105226106d7366004614f29565b61153f565b3480156106e857600080fd5b5061031f6106f73660046151d4565b6115d2565b34801561070857600080fd5b506105b0611829565b34801561071d57600080fd5b5061031f61072c366004615262565b611856565b34801561073d57600080fd5b506105b061074c366004614f0c565b610108602052600090815260409020546001600160801b031681565b34801561077457600080fd5b50610403610783366004614f29565b6119a4565b34801561079457600080fd5b5061031f6107a33660046152bc565b6119d8565b3480156107b457600080fd5b506000546107c79065ffffffffffff1681565b60405165ffffffffffff9091168152602001610352565b3480156107ea57600080fd5b5061031f6107f9366004614f29565b611a54565b34801561080a57600080fd5b5061031f6108193660046152fc565b611b36565b34801561082a57600080fd5b50610522610839366004614f0c565b611b63565b34801561084a57600080fd5b506105b0610859366004614f0c565b611be9565b34801561086a57600080fd5b5060fe54610403906001600160a01b031681565b61031f611c2d565b34801561089257600080fd5b506105226108a1366004615319565b611ca9565b3480156108b257600080fd5b506105b06108c13660046153a1565b611cdd565b3480156108d257600080fd5b506105b06108e13660046153bc565b611e0c565b3480156108f257600080fd5b5061031f6109013660046152fc565b612201565b34801561091257600080fd5b50610963610921366004614f0c565b610103602052600090815260409020805460019091015460ff8216916001600160401b03610100820416916001600160801b03600160481b9092048216911684565b6040516103529493929190615433565b34801561097f57600080fd5b5061040361228b565b34801561099457600080fd5b5061031f6109a336600461546e565b61229a565b3480156109b457600080fd5b50610101546105b0906001600160801b031681565b3480156109d557600080fd5b506103706122f8565b3480156109ea57600080fd5b5061031f6109f9366004615489565b612307565b348015610a0a57600080fd5b5061031f610a19366004614f0c565b61249f565b348015610a2a57600080fd5b506101025461047190600160401b90046001600160401b031681565b348015610a5257600080fd5b5061031f610a613660046154bf565b612535565b348015610a7257600080fd5b50610522610a813660046154ed565b612544565b348015610a9257600080fd5b5061031f610aa1366004615571565b612620565b348015610ab257600080fd5b5061010054610403906001600160a01b031681565b348015610ad357600080fd5b50610101546105b090600160801b90046001600160801b031681565b348015610afb57600080fd5b506105226126a7565b348015610b1057600080fd5b5061031f610b1f366004615636565b61277b565b348015610b3057600080fd5b50610471610b3f366004614f29565b6127b3565b348015610b5057600080fd5b506107c7612817565b348015610b6557600080fd5b5060005461047190600160301b90046001600160401b031681565b348015610b8c57600080fd5b50610471610b9b3660046153a1565b610107602052600090815260409020546001600160401b031681565b348015610bc357600080fd5b5060fd54610403906001600160a01b031681565b348015610be357600080fd5b50610370610bf2366004614f29565b612834565b348015610c0357600080fd5b50610c3f610c123660046153a1565b6001602052600090815260409020546001600160401b03811690600160401b90046001600160801b031682565b604080516001600160401b0390931683526001600160801b03909116602083015201610352565b348015610c7257600080fd5b5061031f610c8136600461546e565b6128a8565b348015610c9257600080fd5b5061031f610ca1366004614f0c565b6128fd565b348015610cb257600080fd5b5061031f610cc1366004614f0c565b612952565b348015610cd257600080fd5b5061031f610ce1366004614f0c565b61298c565b348015610cf257600080fd5b50610346610d01366004614f29565b60009081526101046020526040902060010154600160c01b900460ff1690565b348015610d2d57600080fd5b5061031f610d3c366004615695565b6129fe565b348015610d4d57600080fd5b50610346610d5c3660046156dd565b612aac565b348015610d6d57600080fd5b5061031f610d7c366004614f0c565b612ada565b348015610d8d57600080fd5b5060ff54610403906001600160a01b031681565b60006001600160e01b0319821663780e9d6360e01b1480610dc65750610dc682612b51565b92915050565b606060998054610ddb9061570b565b80601f0160208091040260200160405190810160405280929190818152602001828054610e079061570b565b8015610e545780601f10610e2957610100808354040283529160200191610e54565b820191906000526020600020905b815481529060010190602001808311610e3757829003601f168201915b5050505050905090565b6000610e6982612ba1565b506000908152609d60205260409020546001600160a01b031690565b6000610e90826119a4565b9050806001600160a01b0316836001600160a01b031603610f025760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b0382161480610f1e5750610f1e8133612aac565b610f905760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610ef9565b610f9a8383612bc6565b505050565b630635b5bd60e11b610fb23330836119d8565b6000848152610104602052604090206001810154600160801b90046001600160401b031615610ff4576040516346a9b15d60e01b815260040160405180910390fd5b84600003611015576040516371da551f60e11b815260040160405180910390fd5b42836001600160401b0316101561103f5760405163686c69fd60e01b815260040160405180910390fd5b838155600181018054600160801b600160c01b031916600160801b6001600160401b0386169081029190911790915560408051868152602081019290925286917f13e7611f15031843c0158f76bc4d04d132ae6a98d7250430645b367c3ec4ba08910160405180910390a25050505050565b60ff546000906110d5906001600160a01b031633306001600160801b038816612c34565b6110ea868686866110e58761573f565b612d6a565b90505b95945050505050565b6111003382612e90565b61111c5760405162461bcd60e51b8152600401610ef9906157b4565b610f9a838383612eee565b6111303361298c565b806101058360028111156111465761114661540d565b6003811061115657611156615801565b600491828204019190066008026101000a8154816001600160401b0302191690836001600160401b0316021790555061118d61304b565b7fe1fa3eb1a7d6742cc114a9e0bb7fea501c069f767320079521d8a45ef2b40bfb82826040516111be929190615817565b60405180910390a15050565b6000826111d681612952565b604051632589867d60e01b8152600481018490526001600160a01b03851690632589867d90602401602060405180830381865afa15801561121b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123f919061583c565b91505b5092915050565b600061125483611b63565b82106112b65760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610ef9565b506001600160a01b0391909116600090815260cb60209081526040808320938352929052205490565b610f9a8383836040518060200160405280600081525061277b565b600060ff60009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561134c57600080fd5b505af1158015611360573d6000803e3d6000fd5b505050505061137d3385611373346130ab565b866110e58761573f565b949350505050565b8261138f81612952565b604051637e40cb6b60e11b81526004810184905260009081906001600160a01b0387169063fc8196d69060240160408051808303816000875af11580156113da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113fe9190615859565b90925090506001600160801b0381161561150357604080518681526001600160801b03831660208201526001600160a01b0380851692908916917f53df85a6d27721f38c9c99d095a4c565f68a5e74f22f17c711578461253cbef2910160405180910390a383156114e35760ff54604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d90611499908490600401615111565b600060405180830381600087803b1580156114b357600080fd5b505af11580156114c7573d6000803e3d6000fd5b505050506114de82826001600160801b03166130dc565b611503565b60ff54611503906001600160a01b0316836001600160801b0384166131b6565b505050505050565b610105816003811061151c57600080fd5b60049182820401919006600802915054906101000a90046001600160401b031681565b600061154a60cd5490565b82106115ad5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610ef9565b60cd82815481106115c0576115c0615801565b90600052602060002001549050919050565b600254610100900460ff16158080156115f25750600254600160ff909116105b806116135750611601306132e7565b158015611613575060025460ff166001145b6116765760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610ef9565b6002805460ff191660011790558015611699576002805461ff0019166101001790555b846001600160801b03166000036116c35760405163fa6bfc6d60e01b815260040160405180910390fd5b6116cb6132f6565b61171d6040518060400160405280601281526020017120bd3ab9379026281027232a103a37b5b2b760711b81525060405180604001604052806006815260200165262816a0ad2960d11b81525061332d565b61172561335e565b60fd80546001600160a01b0319908116331790915560fe80546001600160a01b038b81169184169190911790915561010080548a831690841617905560ff80549189169190921617905561010580546001600160401b03858116600160401b026001600160801b03199092168782161791909117600160801b600160c01b031916600160801b918516919091021790556117bd61304b565b61010180546001600160801b0319166001600160801b038716179055801561181f576002805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b60016000819052602052600080516020615f1583398151915254600160401b90046001600160801b031690565b61185f3361298c565b8361186981612952565b816001600160801b03166000036118935760405163cad66eef60e01b815260040160405180910390fd5b64e8d4a51000836001600160401b031611156118c25760405163c6e3629b60e01b815260040160405180910390fd5b60008460028111156118d6576118d661540d565b036118f457604051635b10d6dd60e01b815260040160405180910390fd5b6001600160a01b0385166000908152610103602052604090208054610100600160c81b031916600160481b6001600160801b03851602610100600160481b031916176101006001600160401b03861602178082558590829060ff191660018360028111156119645761196461540d565b0217905550856001600160a01b0316600080516020615f5583398151915286868660405161199493929190615888565b60405180910390a2505050505050565b6000806119b0836133b8565b90506001600160a01b038116610dc65760405162461bcd60e51b8152600401610ef9906158bb565b60fe54604051636396eb8d60e01b81526001600160a01b03858116600483015284811660248301526001600160e01b03198416604483015290911690636396eb8d90606401600060405180830381600087803b158015611a3757600080fd5b505af1158015611a4b573d6000803e3d6000fd5b50505050505050565b6369958ab960e01b611a673330836119d8565b6000611a72836133d3565b6001810154909150600160c01b900460ff1615611aa25760405163c076a8db60e01b815260040160405180910390fd5b600181015461010180546001600160801b0392831692601091611ace918591600160801b900416615903565b82546001600160801b039182166101009390930a92830291909202199091161790555060018101805460ff60c01b1916600160c01b17905560405183907f8f1ffb72cf9e5acc4eddafab2be9e2951d12377b9e1e4bdc7bd686b19c91fd8990600090a2505050565b60ff54611b57906001600160a01b031633306001600160801b038516612c34565b611b6081613416565b50565b60006001600160a01b038216611bcd5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610ef9565b506001600160a01b03166000908152609c602052604090205490565b6000610dc6611bf6611829565b6001600160a01b0384166000908152610103602052604090205461010090046001600160401b0316906001600160801b0316613503565b60ff60009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611c7d57600080fd5b505af1158015611c91573d6000803e3d6000fd5b5050505050611ca7611ca2346130ab565b613416565b565b60ff54600090611ccd906001600160a01b031633306001600160801b038816612c34565b6110ed338686866110e58761573f565b6000600160281b65ffffffffffff83161080611d2257506001611d05600160281b6002615923565b611d0f9190615951565b65ffffffffffff168265ffffffffffff16115b15611d2f57506000919050565b65ffffffffffff82166000908152600160205260408120546001600160401b03169003611d5e57506000919050565b600160008181526020829052600080516020615f1583398151915254909182918291611dcb916001600160401b0316600160281b82611d9e826002615923565b611da89190615951565b6001600160281b81611dbb826002615923565b611dc59190615951565b8c61351f565b65ffffffffffff831660009081526001602052604090205492955090935091506110ed908490849084908990600160401b90046001600160801b031661363b565b600033611e1881612952565b610100546001600160a01b0390811660009081526101066020818152604080842060fd548251638da5cb5b60e01b8152925191968694911692638da5cb5b92600480830193928290030181865afa158015611e77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e9b9190615970565b6001600160a01b03166001600160a01b031681526020019081526020016000209050866001600160801b0316866001600160801b03161115612094576000611ee38888615903565b9050806000611f16611f116001600160801b038416611f02600161378b565b6001600160401b031690613503565b6130ab565b8554909150611f2890600f0b826137d8565b611f329083615903565b9150611f46816001600160801b0316613828565b85548690600090611f5b908490600f0b61598d565b92506101000a8154816001600160801b030219169083600f0b6001600160801b031602179055506000611f9e611f11856001600160801b0316611f02600061378b565b8554909150611fb090600f0b826137d8565b611fba9084615903565b9250611fce816001600160801b0316613828565b85548690600090611fe3908490600f0b61598d565b92506101000a8154816001600160801b030219169083600f0b6001600160801b03160217905550612024611f11856001600160801b0316611f02600261378b565b336000908152610108602052604081208054929a508a929091906120529084906001600160801b03166159ba565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555061208b88846120859190615903565b8a61385e565b505050506121dc565b60006120a08789615903565b6001600160801b031611156121dc5760006120bb8789615903565b90508060006120da611f116001600160801b038416611f02600161378b565b85549091506120ec90600f0b82613969565b6120f69083615903565b915061210a816001600160801b0316613828565b8554869060009061211f908490600f0b6159da565b92506101000a8154816001600160801b030219169083600f0b6001600160801b031602179055506000612162611f11856001600160801b0316611f02600061378b565b855490915061217490600f0b82613969565b61217e9084615903565b9250612192816001600160801b0316613828565b855486906000906121a7908490600f0b6159da565b92506101000a8154816001600160801b030219169083600f0b6001600160801b031602179055506121d7836139a8565b505050505b6001600160801b038716156121f6576121f6338989613a64565b505050949350505050565b61220a3361298c565b806001600160801b03166000036122345760405163fa6bfc6d60e01b815260040160405180910390fd5b61010180546001600160801b0319166001600160801b0383161790556040517f483032c7f41f1ba71455a09f574b92ba07ae933719975978f96f457d4c1c98d390612280908390615111565b60405180910390a150565b6035546001600160a01b031690565b6122a33361298c565b6101028054600160401b600160801b031916600160401b6001600160401b038416021790556040517f527dd140711eb0a9177d62725055c7fe5eb62351eabf406fd3f80886ba57ea3090612280908390614fce565b6060609a8054610ddb9061570b565b3361231181613b61565b600082600f0b131561248c5781831561237457600084815261010460205260408120600101805483929061234f9084906001600160801b03166159ba565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505b33600090815261010360205260408120600181018054919284926123a29084906001600160801b03166159ba565b92506101000a8154816001600160801b0302191690836001600160801b031602179055508161010160108282829054906101000a90046001600160801b03166123eb91906159ba565b92506101000a8154816001600160801b0302191690836001600160801b031602179055506000612419611829565b610101549091506001600160801b03808316600160801b90920416118061246e5750815461245e9061010090046001600160401b03166001600160801b038316613503565b60018301546001600160801b0316115b1561150357604051634323a55560e01b815260040160405180910390fd5b610f9a338461249a85615a07565b613a64565b60fd546001600160a01b031633146124ca57604051630636a15760e11b815260040160405180910390fd5b6001600160a01b038116600081815261010360205260409081902080546001600160c81b0319166901000000e8d4a51000011781559051909190600080516020615f55833981519152906125299060019064e8d4a51000908290615888565b60405180910390a25050565b612540338383613b9b565b5050565b60008361255081612952565b6040516306c1977760e51b81526001600160a01b0386169063d832eee09061258090339088908890600401615a2a565b6020604051808303816000875af115801561259f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125c39190615a6a565b915081156126185760ff546125e2906001600160a01b031633846131b6565b60405182815233907f9b0d35bce028284da7866dad519c879899d1bb723a419c6626d10ef3daef10f39060200160405180910390a25b509392505050565b63a882206160e01b6126333330836119d8565b600061263e846133d3565b600181018054600160801b600160c01b031916600160801b6001600160401b0387160217905560405190915084907fd9d775beef68977fe4ecd3d35a3441b417b2876ea656d0a6bfb568f8ff56fa9b90612699908690614fce565b60405180910390a250505050565b336000908152610106602052604081206101025481546001600160401b03918216916126db91600160801b90041642615a83565b101561271e57610102548154612704916001600160401b0390811691600160801b900416615a96565b6040516318789e3d60e21b8152600401610ef99190614fce565b8054600f0b600081136127345760009250505090565b81546001600160c01b031916600160801b426001600160401b03160217825560ff546001600160801b0382169350612776906001600160a01b031633856131b6565b505090565b6127853383612e90565b6127a15760405162461bcd60e51b8152600401610ef9906157b4565b6127ad84848484613c65565b50505050565b6000336127bf81613b61565b60006127ca846133d3565b6001810154909150600160c01b900460ff16156127fa57604051639b83033760e01b815260040160405180910390fd5b60010154600160801b90046001600160401b031691505b50919050565b6000805461282f9060019065ffffffffffff16615951565b905090565b606061283f82612ba1565b600061285660408051602081019091526000815290565b9050600081511161287657604051806020016040528060008152506128a1565b8061288084613c98565b604051602001612891929190615ab6565b6040516020818303038152906040525b9392505050565b6128b13361298c565b61010280546001600160401b0319166001600160401b0383161790556040517f27cd37fc700f6b98651e78d699d1bcc11b859e18a8ab4948c58dbfa51572e0c990612280908390614fce565b6129063361298c565b61010080546001600160a01b0319166001600160a01b0383161790556040517f0a399af491b2850718a568553f7c18dbda624e511789ab3473b72a6a4d6d748b90612280908390614f42565b600061295d82613d2a565b600281111561296e5761296e61540d565b03611b6057604051632b3907cb60e21b815260040160405180910390fd5b806001600160a01b031661299e61228b565b6001600160a01b031614611b605760405162461bcd60e51b815260206004820152602160248201527f4f776e61626c653a206163636f756e74206973206e6f7420746865206f776e656044820152603960f91b6064820152608401610ef9565b6000612a0a8484613d49565b90508115612a8c5760ff54604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d90612a42908490600401615111565b600060405180830381600087803b158015612a5c57600080fd5b505af1158015612a70573d6000803e3d6000fd5b50505050612a8733826001600160801b03166130dc565b6127ad565b60ff546127ad906001600160a01b0316336001600160801b0384166131b6565b6001600160a01b039182166000908152609e6020908152604080832093909416825291909152205460ff1690565b612ae33361298c565b6001600160a01b038116612b485760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610ef9565b611b6081613f17565b60006001600160e01b031982166380ac58cd60e01b1480612b8257506001600160e01b03198216635b5e139f60e01b145b80610dc657506301ffc9a760e01b6001600160e01b0319831614610dc6565b612baa81613f69565b611b605760405162461bcd60e51b8152600401610ef9906158bb565b6000818152609d6020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612bfb826119a4565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691612c989190615ae5565b6000604051808303816000865af19150503d8060008114612cd5576040519150601f19603f3d011682016040523d82523d6000602084013e612cda565b606091505b5091509150818015612d04575080511580612d04575080806020019051810190612d049190615b01565b6115035760405162461bcd60e51b815260206004820152603160248201527f5472616e7366657248656c7065723a3a7472616e7366657246726f6d3a207472604482015270185b9cd9995c919c9bdb4819985a5b1959607a1b6064820152608401610ef9565b600084612d7681613b61565b836001600160401b03164210612d9f57604051637a0ef04360e11b815260040160405180910390fd5b6001600160a01b038616600090815261010360205260409020546001600160801b03600160481b90910481169086161015612ded57604051632fb3e82760e01b815260040160405180910390fd5b82516001600160a01b0316612e1057612e0461228b565b6001600160a01b031683525b604051634ab029db60e11b81526001600160a01b0387169063956053b690612e40908a9089908890600401615b1e565b6020604051808303816000875af1158015612e5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e839190615a6a565b91505b5095945050505050565b600080612e9c836119a4565b9050806001600160a01b0316846001600160a01b03161480612ec35750612ec38185612aac565b8061123f5750836001600160a01b0316612edc84610e5e565b6001600160a01b031614949350505050565b826001600160a01b0316612f01826119a4565b6001600160a01b031614612f275760405162461bcd60e51b8152600401610ef990615b6e565b6001600160a01b038216612f895760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610ef9565b612f94838383613f86565b826001600160a01b0316612fa7826119a4565b6001600160a01b031614612fcd5760405162461bcd60e51b8152600401610ef990615b6e565b6000818152609d6020908152604080832080546001600160a01b03199081169091556001600160a01b03878116808652609c8552838620805460001901905590871680865283862080546001019055868652609b9094528285208054909216841790915590518493600080516020615f3583398151915291a4505050565b64e8d4a5100061305b600261378b565b613065600161378b565b61306f600061378b565b6130799190615a96565b6130839190615a96565b6001600160401b03161115611ca75760405163cd3cb2bb60e01b815260040160405180910390fd5b60006001600160801b038211156130d8576003604051639b3137df60e01b8152600401610ef99190615bb3565b5090565b604080516000808252602082019092526001600160a01b0384169083906040516131069190615ae5565b60006040518083038185875af1925050503d8060008114613143576040519150601f19603f3d011682016040523d82523d6000602084013e613148565b606091505b5050905080610f9a5760405162461bcd60e51b815260206004820152603460248201527f5472616e7366657248656c7065723a3a736166655472616e736665724554483a60448201527308115512081d1c985b9cd9995c8819985a5b195960621b6064820152608401610ef9565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291516000928392908716916132129190615ae5565b6000604051808303816000865af19150503d806000811461324f576040519150601f19603f3d011682016040523d82523d6000602084013e613254565b606091505b509150915081801561327e57508051158061327e57508080602001905181019061327e9190615b01565b6132e05760405162461bcd60e51b815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201526c185b9cd9995c8819985a5b1959609a1b6064820152608401610ef9565b5050505050565b6001600160a01b03163b151590565b600254610100900460ff1661331d5760405162461bcd60e51b8152600401610ef990615bcd565b61332561403e565b611ca7614065565b600254610100900460ff166133545760405162461bcd60e51b8152600401610ef990615bcd565b6125408282614095565b6000805465ffffffffffff1916600160281b178082556001600160401b03600160301b9091041690600661339183615c18565b91906101000a8154816001600160401b0302191690836001600160401b0316021790555050565b6000908152609b60205260409020546001600160a01b031690565b6000818152610104602052604081206001810154600160801b90046001600160401b03168203610dc6576040516387aeb83d60e01b815260040160405180910390fd5b610101546001600160801b039081169082161015613447576040516320d3137f60e01b815260040160405180910390fd5b6000613452826140d5565b6101025490915061347390600160401b90046001600160401b031642615a96565b65ffffffffffff821660008181526101076020526040902080546001600160401b0319166001600160401b0393909316929092179091556134b5903390614164565b8065ffffffffffff16336001600160a01b03167f04aea1979a2b879b0578efc9fb3e03cd6ae3bdc964f047e81f526ea2350967e5846040516134f79190615111565b60405180910390a35050565b600064e8d4a510006135158385615c46565b6128a19190615c7b565b65ffffffffffff8416600090815260016020526040812054819081906001600160401b03808c169116101561355b57508991508790508661362d565b8365ffffffffffff168765ffffffffffff160361357f57508291508490508361362d565b6000600261358d8789615c8f565b6135979190615cae565b90508465ffffffffffff168765ffffffffffff16111580156135c957508065ffffffffffff168565ffffffffffff1611155b156135f4576135e8888c89896135e0846002615923565b8c878c61351f565b9195509350915061362b565b613623888c8989613606846002615923565b613611906001615c8f565b61361c876001615c8f565b8c8c61351f565b919550935091505b505b985098509895505050505050565b60008265ffffffffffff168665ffffffffffff160361365b5750806110ed565b6000613668876002615923565b90506000613677886002615923565b613682906001615c8f565b65ffffffffffff8084166000908152600160205260408082205492841682528120549293506001600160801b03600160401b9283900481169391926136c992041683615cd3565b9050806000036136e05760009450505050506110ed565b6000816136f6846001600160801b038a16615c46565b6137009190615c7b565b9050600060026137108b8d615c8f565b61371a9190615cae565b90508865ffffffffffff168b65ffffffffffff161115801561374c57508065ffffffffffff168965ffffffffffff1611155b1561376b5761375e868c838c8661363b565b96505050505050506110ed565b61375e8561377a836001615c8f565b8c8c613786878e615903565b61363b565b60006101058260028111156137a2576137a261540d565b600381106137b2576137b2615801565b600491828204019190066008029054906101000a90046001600160401b03169050919050565b60008083600f0b12156138215760006137f9836001600160801b0316613828565b613803908561598d565b9050600081600f0b13613817576000613819565b805b915050610dc6565b5080610dc6565b600060016001607f1b036001600160801b03831611156130d8576001604051639b3137df60e01b8152600401610ef99190615bb3565b600160008181526020829052600080516020615f15833981519152549091829182916138cb916001600160401b0316600160281b8261389e826002615923565b6138a89190615951565b6001600160281b816138bb826002615923565b6138c59190615951565b8b61351f565b6000549295509093509150600160301b90046001600160401b03166138fe848484886138f686615c18565b95508561426b565b6139386001600160281b81613914826002615923565b61391e9190615951565b600160281b898b600061393089615c18565b9850886143e1565b600080546001600160401b03909216600160301b02600160301b600160701b03199092169190911790555050505050565b60008083600f0b1261399f57613987826001600160801b0316613828565b600f0b83600f0b1361399957826128a1565b816128a1565b50600092915050565b60016000819052602052600080516020615f15833981519152546001600160801b03808316600160401b9092041610611b6057611b606001600160281b816139f1826002615923565b6139fb9190615951565b600054600160281b90613a189060019065ffffffffffff16615951565b8660016000600681819054906101000a90046001600160401b0316613a3c90615c18565b91906101000a8154816001600160401b0302191690836001600160401b0316021790556143e1565b8115613aba576000828152610104602052604081206001018054839290613a959084906001600160801b0316615903565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505b6001600160a01b0383166000908152610103602052604081206001018054839290613aef9084906001600160801b0316615903565b92506101000a8154816001600160801b0302191690836001600160801b031602179055508061010160108282829054906101000a90046001600160801b0316613b389190615903565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550505050565b6001613b6c82613d2a565b6002811115613b7d57613b7d61540d565b14611b6057604051630324ec9560e41b815260040160405180910390fd5b816001600160a01b0316836001600160a01b031603613bf85760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b6044820152606401610ef9565b6001600160a01b038381166000818152609e6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b613c70848484612eee565b613c7c8484848461463e565b6127ad5760405162461bcd60e51b8152600401610ef990615ce6565b60606000613ca583614743565b60010190506000816001600160401b03811115613cc457613cc4615594565b6040519080825280601f01601f191660200182016040528015613cee576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084613cf857509392505050565b6001600160a01b03166000908152610103602052604090205460ff1690565b65ffffffffffff82166000908152610107602052604081205442906001600160401b03908116908216811115613d9d57613d838282615d38565b604051633ca8f33960e11b8152600401610ef99190614fce565b613dae8565ffffffffffff166119a4565b6001600160a01b0316336001600160a01b031614613ddf57604051633ce20b5960e11b815260040160405180910390fd5b61010254613dfd90600160401b90046001600160401b031683615a96565b65ffffffffffff861660009081526101076020526040812080546001600160401b0319166001600160401b039390931692909217909155613e3c611829565b9050613e488686614819565b9350836001600160801b0316600003613e7457604051636180f03f60e11b815260040160405180910390fd5b61010154613e9290600160801b90046001600160801b031682615903565b6001600160801b0316846001600160801b03161115613ec457604051636bac637f60e01b815260040160405180910390fd5b8565ffffffffffff16336001600160a01b03167f6cf9643c04552344f0a92825c122b0a19d0b217bbeec89f3444755e3899f854f86604051613f069190615111565b60405180910390a350505092915050565b603580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600080613f75836133b8565b6001600160a01b0316141592915050565b6001600160a01b038316613fe157613fdc8160cd8054600083815260ce60205260408120829055600182018355919091527f83978b4c69c48dd978ab43fe30f077615294f938fb7f936d9eb340e51ea7db2e0155565b614004565b816001600160a01b0316836001600160a01b0316146140045761400483826149a6565b6001600160a01b03821661401b57610f9a81614a43565b826001600160a01b0316826001600160a01b031614610f9a57610f9a8282614af2565b600254610100900460ff16611ca75760405162461bcd60e51b8152600401610ef990615bcd565b600254610100900460ff1661408c5760405162461bcd60e51b8152600401610ef990615bcd565b611ca733613f17565b600254610100900460ff166140bc5760405162461bcd60e51b8152600401610ef990615bcd565b60996140c88382615d9e565b50609a610f9a8282615d9e565b6000805465ffffffffffff1681806140ec83615e5d565b91906101000a81548165ffffffffffff021916908365ffffffffffff160217905550905061415f8183600080600681819054906101000a90046001600160401b031661413790615c18565b91906101000a8154816001600160401b0302191690836001600160401b031602179055614b36565b919050565b6001600160a01b0382166141ba5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610ef9565b6141c381613f69565b156141e05760405162461bcd60e51b8152600401610ef990615e78565b6141ec60008383613f86565b6141f581613f69565b156142125760405162461bcd60e51b8152600401610ef990615e78565b6001600160a01b0382166000818152609c6020908152604080832080546001019055848352609b90915280822080546001600160a01b031916841790555183929190600080516020615f35833981519152908290a45050565b8165ffffffffffff168565ffffffffffff1603156132e0576000614290866002615923565b9050600061429f876002615923565b6142aa906001615c8f565b65ffffffffffff808916600090815260016020526040808220548684168352818320549385168352908220549394506001600160801b03600160401b91829004811694938290048116939190910416906143048284615cd3565b905080600003614319575050505050506132e0565b60008161432f856001600160801b038816615c46565b6143399190615c7b565b905061434687828a614b7f565b61435a866143548388615903565b8a614b7f565b600060026143688c8e615c8f565b6143729190615cae565b90508965ffffffffffff168c65ffffffffffff16111580156143a457508065ffffffffffff168a65ffffffffffff1611155b156143bb576143b6888d838d8d61426b565b6143d2565b6143d2876143ca836001615c8f565b8d8d8d61426b565b50505050505050505050505050565b8465ffffffffffff168765ffffffffffff1614801561440f57508365ffffffffffff168665ffffffffffff16145b8061442957508565ffffffffffff168765ffffffffffff16145b1561443f5761443a88848484614bf8565b61181f565b6000600261444d888a615c8f565b6144579190615cae565b90508465ffffffffffff168865ffffffffffff161115801561448957508065ffffffffffff168565ffffffffffff1611155b156144ad576144a861449c8a6002615923565b898389898989896143e1565b614627565b60006001816144bd8c6002615923565b65ffffffffffff1681526020810191909152604001600090812054600160401b90046001600160801b0316915084156144f757600061452d565b61452d6145058c6002615923565b614510906001615c8f565b61451b856001615c8f565b8b6145278b6001615c8f565b8d614cf5565b6001600061453c8e6002615923565b614547906001615c8f565b65ffffffffffff16815260208101919091526040016000205461457a9190600160401b90046001600160801b0316615903565b6001600160801b0316905060006145918284615cd3565b9050806000036145a4575050505061181f565b6000816145ba856001600160801b038b16615c46565b6145c49190615c7b565b90506145e06145d48e6002615923565b8d878d89868d8d6143e1565b6146226145ee8e6002615923565b6145f9906001615c8f565b614604876001615c8f565b8d614610896001615c8f565b8d61461b878f615903565b8d8d6143e1565b505050505b61463389858585614bf8565b505050505050505050565b6000614652846001600160a01b03166132e7565b1561473b57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614689903390899088908890600401615eae565b6020604051808303816000875af19250505080156146c4575060408051601f3d908101601f191682019092526146c191810190615ee1565b60015b614721573d8080156146f2576040519150601f19603f3d011682016040523d82523d6000602084013e6146f7565b606091505b5080516000036147195760405162461bcd60e51b8152600401610ef990615ce6565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061137d565b50600161137d565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106147825772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6904ee2d6d415b85acef8160201b83106147ac576904ee2d6d415b85acef8160201b830492506020015b662386f26fc1000083106147ca57662386f26fc10000830492506010015b6305f5e10083106147e2576305f5e100830492506008015b61271083106147f657612710830492506004015b60648310614808576064830492506002015b600a8310610dc65760010192915050565b65ffffffffffff82166000908152600160205260408120546001600160401b0316810361485957604051631b2862ff60e21b815260040160405180910390fd5b64e8d4a510008264ffffffffff16111561488657604051635a60b01360e01b815260040160405180910390fd5b600160008181526020829052600080516020615f15833981519152549091829182916148f3916001600160401b0316600160281b826148c6826002615923565b6148d09190615951565b6001600160281b816148e3826002615923565b6148ed9190615951565b8d61351f565b6000549295509093509150600160301b90046001600160401b031661491e8484848a6138f686615c18565b65ffffffffffff87166000908152600160205260409020546149589064ffffffffff881690600160401b90046001600160801b0316613503565b94506149728786600161496a85615c18565b945084614b36565b600080546001600160401b03909216600160301b02600160301b600160701b03199092169190911790555091949350505050565b600060016149b384611b63565b6149bd9190615a83565b600083815260cc6020526040902054909150808214614a10576001600160a01b038416600090815260cb60209081526040808320858452825280832054848452818420819055835260cc90915290208190555b50600091825260cc602090815260408084208490556001600160a01b03909416835260cb81528383209183525290812055565b60cd54600090614a5590600190615a83565b600083815260ce602052604081205460cd8054939450909284908110614a7d57614a7d615801565b906000526020600020015490508060cd8381548110614a9e57614a9e615801565b600091825260208083209091019290925582815260ce909152604080822084905585825281205560cd805480614ad657614ad6615efe565b6001900381819060005260206000200160009055905550505050565b6000614afd83611b63565b6001600160a01b03909316600090815260cb60209081526040808320868452825280832085905593825260cc9052919091209190915550565b614b4284848484614bf8565b8365ffffffffffff166001146127ad576127ad60018565ffffffffffff1611614b6c576001614b77565b614b77600286615cae565b848484614b36565b65ffffffffffff83166000908152600160205260409020546001600160801b03838116600160401b9092041614610f9a5765ffffffffffff8316600090815260016020526040902080546001600160801b038416600160401b026001600160c01b03199091166001600160401b03841617179055505050565b65ffffffffffff8416600090815260016020526040902080546001600160401b0319166001600160401b0383161790558115614c915765ffffffffffff841660009081526001602052604090208054849190600890614c68908490600160401b90046001600160801b0316615903565b92506101000a8154816001600160801b0302191690836001600160801b031602179055506127ad565b65ffffffffffff841660009081526001602052604090208054849190600890614ccb908490600160401b90046001600160801b03166159ba565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555050505050565b60008265ffffffffffff168565ffffffffffff16148015614d2557508165ffffffffffff168465ffffffffffff16145b80614d3f57508365ffffffffffff168565ffffffffffff16145b15614d72575065ffffffffffff8516600090815260016020526040902054600160401b90046001600160801b03166110ed565b60006002614d808688615c8f565b614d8a9190615cae565b90508365ffffffffffff168665ffffffffffff1611158015614dbc57508065ffffffffffff168465ffffffffffff1611155b15614e2b57614dd8614dcf886002615923565b87838785614cf5565b614de290836159ba565b9150614e1a614df2886002615923565b614dfd906001615c8f565b614e08836001615c8f565b87614e14856001615c8f565b87614cf5565b614e2490836159ba565b9150612e86565b614e57614e39886002615923565b614e44906001615c8f565b614e4f836001615c8f565b878787614cf5565b612e8390836159ba565b6001600160e01b031981168114611b6057600080fd5b600060208284031215614e8957600080fd5b81356128a181614e61565b60005b83811015614eaf578181015183820152602001614e97565b50506000910152565b60008151808452614ed0816020860160208601614e94565b601f01601f19169290920160200192915050565b6020815260006128a16020830184614eb8565b6001600160a01b0381168114611b6057600080fd5b600060208284031215614f1e57600080fd5b81356128a181614ef7565b600060208284031215614f3b57600080fd5b5035919050565b6001600160a01b0391909116815260200190565b60008060408385031215614f6957600080fd5b8235614f7481614ef7565b946020939093013593505050565b80356001600160401b038116811461415f57600080fd5b600080600060608486031215614fae57600080fd5b8335925060208401359150614fc560408501614f82565b90509250925092565b6001600160401b0391909116815260200190565b6001600160801b0381168114611b6057600080fd5b60006040828403121561281157600080fd5b600080600080600060a0868803121561502157600080fd5b853561502c81614ef7565b9450602086013561503c81614ef7565b9350604086013561504c81614fe2565b925061505a60608701614f82565b915060808601356001600160401b0381111561507557600080fd5b61508188828901614ff7565b9150509295509295909350565b6000806000606084860312156150a357600080fd5b83356150ae81614ef7565b925060208401356150be81614ef7565b929592945050506040919091013590565b60038110611b6057600080fd5b600080604083850312156150ef57600080fd5b82356150fa816150cf565b915061510860208401614f82565b90509250929050565b6001600160801b0391909116815260200190565b60008060006060848603121561513a57600080fd5b833561514581614ef7565b925061515360208501614f82565b915060408401356001600160401b0381111561516e57600080fd5b61517a86828701614ff7565b9150509250925092565b8015158114611b6057600080fd5b6000806000606084860312156151a757600080fd5b83356151b281614ef7565b92506020840135915060408401356151c981615184565b809150509250925092565b600080600080600080600060e0888a0312156151ef57600080fd5b87356151fa81614ef7565b9650602088013561520a81614ef7565b9550604088013561521a81614ef7565b9450606088013561522a81614fe2565b935061523860808901614f82565b925061524660a08901614f82565b915061525460c08901614f82565b905092959891949750929550565b6000806000806080858703121561527857600080fd5b843561528381614ef7565b93506020850135615293816150cf565b92506152a160408601614f82565b915060608501356152b181614fe2565b939692955090935050565b6000806000606084860312156152d157600080fd5b83356152dc81614ef7565b925060208401356152ec81614ef7565b915060408401356151c981614e61565b60006020828403121561530e57600080fd5b81356128a181614fe2565b6000806000806080858703121561532f57600080fd5b843561533a81614ef7565b9350602085013561534a81614fe2565b925061535860408601614f82565b915060608501356001600160401b0381111561537357600080fd5b61537f87828801614ff7565b91505092959194509250565b803565ffffffffffff8116811461415f57600080fd5b6000602082840312156153b357600080fd5b6128a18261538b565b600080600080608085870312156153d257600080fd5b8435935060208501356153e481614fe2565b925060408501356153f481614fe2565b91506154026060860161538b565b905092959194509250565b634e487b7160e01b600052602160045260246000fd5b60038110611b6057611b6061540d565b6080810161544086615423565b9481526001600160401b039390931660208401526001600160801b0391821660408401521660609091015290565b60006020828403121561548057600080fd5b6128a182614f82565b6000806040838503121561549c57600080fd5b82359150602083013580600f0b81146154b457600080fd5b809150509250929050565b600080604083850312156154d257600080fd5b82356154dd81614ef7565b915060208301356154b481615184565b60008060006040848603121561550257600080fd5b833561550d81614ef7565b925060208401356001600160401b038082111561552957600080fd5b818601915086601f83011261553d57600080fd5b81358181111561554c57600080fd5b87602082850101111561555e57600080fd5b6020830194508093505050509250925092565b6000806040838503121561558457600080fd5b8235915061510860208401614f82565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126155bb57600080fd5b81356001600160401b03808211156155d5576155d5615594565b604051601f8301601f19908116603f011681019082821181831017156155fd576155fd615594565b8160405283815286602085880101111561561657600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806080858703121561564c57600080fd5b843561565781614ef7565b9350602085013561566781614ef7565b92506040850135915060608501356001600160401b0381111561568957600080fd5b61537f878288016155aa565b6000806000606084860312156156aa57600080fd5b6156b38461538b565b9250602084013564ffffffffff811681146156cd57600080fd5b915060408401356151c981615184565b600080604083850312156156f057600080fd5b82356156fb81614ef7565b915060208301356154b481614ef7565b600181811c9082168061571f57607f821691505b60208210810361281157634e487b7160e01b600052602260045260246000fd5b60006040823603121561575157600080fd5b604080519081016001600160401b03808211838310171561577457615774615594565b816040528435915061578582614ef7565b9082526020840135908082111561579b57600080fd5b506157a8368286016155aa565b60208301525092915050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b6040810161582484615423565b9281526001600160401b039190911660209091015290565b60006020828403121561584e57600080fd5b81516128a181614fe2565b6000806040838503121561586c57600080fd5b825161587781614ef7565b60208401519092506154b481614fe2565b6060810161589585615423565b9381526001600160401b039290921660208301526001600160801b031660409091015290565b602080825260189082015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6001600160801b03828116828216039080821115611242576112426158ed565b600065ffffffffffff80831681851681830481118215151615615948576159486158ed565b02949350505050565b65ffffffffffff828116828216039080821115611242576112426158ed565b60006020828403121561598257600080fd5b81516128a181614ef7565b600f81810b9083900b0160016001607f1b03811360016001607f1b031982121715610dc657610dc66158ed565b6001600160801b03818116838216019080821115611242576112426158ed565b600f82810b9082900b0360016001607f1b0319811260016001607f1b0382131715610dc657610dc66158ed565b6000600f82900b6001607f1b8101615a2157615a216158ed565b60000392915050565b6001600160a01b03841681526040602082018190528101829052818360608301376000818301606090810191909152601f909201601f1916010192915050565b600060208284031215615a7c57600080fd5b5051919050565b81810381811115610dc657610dc66158ed565b6001600160401b03818116838216019080821115611242576112426158ed565b60008351615ac8818460208801614e94565b835190830190615adc818360208801614e94565b01949350505050565b60008251615af7818460208701614e94565b9190910192915050565b600060208284031215615b1357600080fd5b81516128a181615184565b600060018060a01b03808616835260018060801b03851660208401526060604084015280845116606084015250602083015160406080840152615b6460a0840182614eb8565b9695505050505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b6020810160048310615bc757615bc761540d565b91905290565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60006001600160401b038281166002600160401b03198101615c3c57615c3c6158ed565b6001019392505050565b6000816000190483118215151615615c6057615c606158ed565b500290565b634e487b7160e01b600052601260045260246000fd5b600082615c8a57615c8a615c65565b500490565b65ffffffffffff818116838216019080821115611242576112426158ed565b600065ffffffffffff80841680615cc757615cc7615c65565b92169190910492915050565b80820180821115610dc657610dc66158ed565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160401b03828116828216039080821115611242576112426158ed565b601f821115610f9a57600081815260208120601f850160051c81016020861015615d7f5750805b601f850160051c820191505b8181101561150357828155600101615d8b565b81516001600160401b03811115615db757615db7615594565b615dcb81615dc5845461570b565b84615d58565b602080601f831160018114615e005760008415615de85750858301515b600019600386901b1c1916600185901b178555611503565b600085815260208120601f198616915b82811015615e2f57888601518255948401946001909101908401615e10565b5085821015615e4d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600065ffffffffffff808316818103615c3c57615c3c6158ed565b6020808252601c908201527b115490cdcc8c4e881d1bdad95b88185b1c9958591e481b5a5b9d195960221b604082015260600190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906110ea90830184614eb8565b600060208284031215615ef357600080fd5b81516128a181614e61565b634e487b7160e01b600052603160045260246000fdfecc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efd108a4f6fc411b0a4df994fcad4ff1051f5d37f74abaf52fb1e1e2c54b32880fa2646970667358221220d782d9cfbb1748277b51a599a6d5e89b6f01306b0d1953707f8b4da0bcff38f564736f6c63430008100033
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.