Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multi Chain
Multichain Addresses
N/ALatest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 8081831 | 359 days 4 hrs ago | IN | Create: Seedchain | 0 ETH | 0.00647958 |
Latest 16 internal transactions
Advanced mode:
Parent Txn Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
9775901 | 62 days 6 hrs ago | 0.45290698 ETH | ||||
9775893 | 62 days 6 hrs ago | 0.00452906 ETH | ||||
8792339 | 236 days 3 hrs ago | 0.00053784 ETH | ||||
8792292 | 236 days 3 hrs ago | 0.00053784 ETH | ||||
8776076 | 238 days 23 hrs ago | 0.00052492 ETH | ||||
8552541 | 277 days 20 hrs ago | 0 ETH | ||||
8552496 | 277 days 21 hrs ago | 0 ETH | ||||
8305737 | 320 days 8 hrs ago | 0 ETH | ||||
8305731 | 320 days 8 hrs ago | 0 ETH | ||||
8208921 | 337 days 17 hrs ago | 0 ETH | ||||
8085581 | 358 days 14 hrs ago | 0 ETH | ||||
8085539 | 358 days 14 hrs ago | 0 ETH | ||||
8085527 | 358 days 14 hrs ago | 0 ETH | ||||
8085511 | 358 days 14 hrs ago | 0 ETH | ||||
8081855 | 359 days 4 hrs ago | 0 ETH | ||||
8081832 | 359 days 4 hrs ago | 0 ETH |
Loading...
Loading
Contract Name:
Seedchain
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity Standard Json-Input format)
// contracts/Seedchain.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts/interfaces/IERC721.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; // import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import "./ERC1155Upgradeable.sol"; import "./HotSwapV1.sol"; import "./PriceFacet.sol"; error AddressMatchesSender(); error ExceedsSupply(); error NotEnoughFunds(); error TypesAndAmountsDifferentLengths(); error ProjectDoesNotExist(); contract Seedchain is Initializable, OwnableUpgradeable, ERC1155Upgradeable { // event gas cost: 375 + 375 * numberOfIndexedParameters + numberOfUnindexedBits event Airdrop( address indexed addr, address indexed sender, uint256[] types, uint256[] quantities ); event Mint(address indexed addr, uint256[] types, uint256[] quantities); event MintForToken( address indexed contractAddr, uint256 tokenId, uint256[] types, uint256[] quantities ); event AirdropToHolder( address indexed holderAddr, address indexed contractAddr, uint256 tokenId, uint256[] types, uint256[] quantities ); mapping(uint256 => bool) public projects; string public baseURI; address public treasuryAddress; address payable public hotSwapAddress; address public stablecoinAddress; uint24 public swapFee; uint24 public bufferFee; address public priceFacetAddress; // Take note of the initializer modifiers. // - `initializerERC721A` for `ERC721AUpgradeable`. // - `initializer` for OpenZeppelin's `OwnableUpgradeable`. function initialize(string memory uri_, address payable _hotSwapAddress) public initializer onlyInitializing { treasuryAddress = owner(); // Goerli: 0x07865c6E87B9F70255377e024ace6630C1Eaa37F; // Mainnet: 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; stablecoinAddress = 0x07865c6E87B9F70255377e024ace6630C1Eaa37F; priceFacetAddress = 0xF1E6Adc83A3cE9157832a9AB7CF347211c1a1aFa; hotSwapAddress = _hotSwapAddress; swapFee = 3000; bufferFee = 3000; // 0.3% buffer __ERC1155_init(uri_); __Ownable_init(); } /** * @dev Register a new token type. This is limited to the contract owner. * * A tokenLimit of `0` represents an unlimited limit */ function registerProject(uint256 project) external onlyOwner { projects[project] = true; } /** * @dev Deregister a token type. */ function deregisterProject(uint256 project) external onlyOwner { delete projects[project]; } function setTreasuryAddress(address addr) public onlyOwner { treasuryAddress = addr; } function setHotSwapAddress(address payable addr) public onlyOwner { hotSwapAddress = addr; } function setStablecoinAddress(address addr) public onlyOwner { stablecoinAddress = addr; } function setPriceFacetAddress(address addr) public onlyOwner { priceFacetAddress = addr; } function setSwapFee(uint24 fee) public onlyOwner { swapFee = fee; } function setBufferFee(uint24 fee) public onlyOwner { bufferFee = fee; } function setBaseURI(string memory uri) public onlyOwner { _setURI(uri); } /** * Add buffer fee onto price. * * A buffer may be necessary to prevent random failures, * particularly on testnets as liquidity may get drained. */ function _getPrice(uint256 priceId) internal view returns (uint256) { uint256 price = PriceFacet(priceFacetAddress).getPrice(priceId, 1); uint256 absSwapFee = (price * bufferFee) / 1000000; return price + absSwapFee; } function getPrice(uint256 priceId) public view returns (uint256) { return _getPrice(priceId); } /** * Assumes all price facet prices are in USD and returns their value */ function _getUsdPrice(uint256 projectId) internal view returns (uint256) { PriceFacet priceFacet = PriceFacet(priceFacetAddress); return priceFacet.getRawPrice(projectId, 1) * 10000; // multiply by 10000 to get USDC cents } function _beforeTokenTransfer( address, address from, address, uint256[] memory, uint256[] memory, bytes memory ) internal pure override { require(from == address(0), "Cannot transfer"); } function _swap(uint256[] memory types, uint256[] memory amounts) internal { uint256 usdPrice = 0; // We get price from facet again in case conversion rate fluctates. // This guarantees we will only succeed the transaction if enough // ETH is sent to convert to the true USD price for (uint256 i = 0; i < types.length; i++) { usdPrice = usdPrice + _getUsdPrice(types[i]) * amounts[i]; } HotSwapV1 swapper = HotSwapV1(hotSwapAddress); // Swap ETH for a stablecoin, send to owner and refund remainder to sender swapper.swap{value: msg.value}( stablecoinAddress, usdPrice, treasuryAddress, msg.sender, swapFee ); } function _mint( address addr, uint256[] memory types, uint256[] memory amounts ) internal { if (types.length != amounts.length) revert TypesAndAmountsDifferentLengths(); uint256 totalPrice = 0; for (uint256 i = 0; i < types.length; i++) { totalPrice = totalPrice + _getPrice(types[i]) * amounts[i]; if (projects[types[i]] != true) revert ProjectDoesNotExist(); } if (msg.value < totalPrice) revert NotEnoughFunds(); _mintBatch(addr, types, amounts, ""); _swap(types, amounts); } /** * @dev Mint a number of tokens for each given type * * Requirements: * * - `types` must all be registered in projects * - `types` must match length of `amounts` */ function mint(uint256[] memory types, uint256[] memory amounts) external payable { _mint(msg.sender, types, amounts); emit Mint(msg.sender, types, amounts); } /** * @dev Mint a number of tokens for a given type * * Requirements: * * - `type` must all be registered in projects */ function mint(uint256 impactType, uint256 amount) external payable { uint256[] memory types = new uint256[](1); uint256[] memory amounts = new uint256[](1); types[0] = impactType; amounts[0] = amount; _mint(msg.sender, types, amounts); emit Mint(msg.sender, types, amounts); } /** * @dev Airdrop a number of tokens for a given type to a given address * * Requirements: * * - `address` must be different to sender * - `types` must all be registered in projects * - `types` must match length of `amounts` */ function airdrop( address addr, uint256[] memory types, uint256[] memory amounts ) external payable { // Prevent people airdropping to themselves. They should use mint instead. if (msg.sender == addr) revert AddressMatchesSender(); _mint(addr, types, amounts); emit Airdrop(addr, msg.sender, types, amounts); } /** * @dev Airdrop a number of tokens for a given type * * Requirements: * * - `type` must all be registered in projects */ function airdrop( address addr, uint256 impactType, uint256 amount ) external payable { uint256[] memory types = new uint256[](1); uint256[] memory amounts = new uint256[](1); types[0] = impactType; amounts[0] = amount; // Prevent people airdropping to themselves. They should use mint instead. if (msg.sender == addr) revert AddressMatchesSender(); _mint(addr, types, amounts); emit Airdrop(addr, msg.sender, types, amounts); } // TODO restrict to deployer, owner or preapproved list function mintForToken( address contractAddress, uint256 tokenId, uint256[] memory types, uint256[] memory amounts ) external payable { // TODO consider dropping this for contracts that don't implement this properly // require( // IERC165(contractAddress).supportsInterface( // type(IERC721).interfaceId // ), // "Address is not an ERC721 contract" // ); require( msg.sender == contractAddress || msg.sender == owner(), "Must be contract, deployer or owner" ); _mint(contractAddress, types, amounts); emit MintForToken(contractAddress, tokenId, types, amounts); } // TODO restrict to deployer, owner or preapproved list function airdropToHolder( address contractAddress, uint256 tokenId, uint256[] memory types, uint256[] memory amounts ) external payable { // TODO consider dropping this for contracts that don't implement this properly // NB When testing this on goerli, ensure to use a test contract // require( // IERC165(contractAddress).supportsInterface( // type(IERC721).interfaceId // ), // "Address is not an ERC721 contract" // ); require( msg.sender == contractAddress || msg.sender == owner(), "Must be contract, deployer or owner" ); IERC721 nftContract = IERC721(contractAddress); address holder = nftContract.ownerOf(tokenId); _mint(holder, types, amounts); emit AirdropToHolder(holder, contractAddress, tokenId, types, amounts); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC1155/ERC1155.sol) pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; /** * @dev Implementation of the basic standard multi-token. * See https://eips.ethereum.org/EIPS/eip-1155 * Based on the OpenZeppelin version, with safe acceptance restrictions removed: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC1155/ERC1155.sol */ contract ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable { using AddressUpgradeable for address; // Mapping from token ID to account balances mapping(uint256 => mapping(address => uint256)) private _balances; // Mapping from account to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json string private _uri; /** * @dev See {_setURI}. */ function __ERC1155_init(string memory uri_) internal onlyInitializing { __ERC1155_init_unchained(uri_); } function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing { _setURI(uri_); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) { return interfaceId == type(IERC1155Upgradeable).interfaceId || interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC1155MetadataURI-uri}. * * This implementation returns the same URI for *all* token types. It relies * on the token type ID substitution mechanism * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. * * Clients calling this function must replace the `\{id\}` substring with the * actual token type ID. */ function uri(uint256) public view virtual override returns (string memory) { return _uri; } /** * @dev See {IERC1155-balanceOf}. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) public view virtual override returns (uint256) { require( account != address(0), "ERC1155: address zero is not a valid owner" ); return _balances[id][account]; } /** * @dev See {IERC1155-balanceOfBatch}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] memory accounts, uint256[] memory ids) public view virtual override returns (uint256[] memory) { require( accounts.length == ids.length, "ERC1155: accounts and ids length mismatch" ); uint256[] memory batchBalances = new uint256[](accounts.length); for (uint256 i = 0; i < accounts.length; ++i) { batchBalances[i] = balanceOf(accounts[i], ids[i]); } return batchBalances; } /** * @dev See {IERC1155-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC1155-isApprovedForAll}. */ function isApprovedForAll(address account, address operator) public view virtual override returns (bool) { return _operatorApprovals[account][operator]; } /** * @dev See {IERC1155-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes memory data ) public virtual override { require( from == _msgSender() || isApprovedForAll(from, _msgSender()), "ERC1155: caller is not token owner or approved" ); _safeTransferFrom(from, to, id, amount, data); } /** * @dev See {IERC1155-safeBatchTransferFrom}. */ function safeBatchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) public virtual override { require( from == _msgSender() || isApprovedForAll(from, _msgSender()), "ERC1155: caller is not token owner or approved" ); _safeBatchTransferFrom(from, to, ids, amounts, data); } /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function _safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes memory data ) internal virtual { require(to != address(0), "ERC1155: transfer to the zero address"); address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); uint256[] memory amounts = _asSingletonArray(amount); _beforeTokenTransfer(operator, from, to, ids, amounts, data); uint256 fromBalance = _balances[id][from]; require( fromBalance >= amount, "ERC1155: insufficient balance for transfer" ); unchecked { _balances[id][from] = fromBalance - amount; } _balances[id][to] += amount; emit TransferSingle(operator, from, to, id, amount); _afterTokenTransfer(operator, from, to, ids, amounts, data); _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function _safeBatchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { require( ids.length == amounts.length, "ERC1155: ids and amounts length mismatch" ); require(to != address(0), "ERC1155: transfer to the zero address"); address operator = _msgSender(); _beforeTokenTransfer(operator, from, to, ids, amounts, data); for (uint256 i = 0; i < ids.length; ++i) { uint256 id = ids[i]; uint256 amount = amounts[i]; uint256 fromBalance = _balances[id][from]; require( fromBalance >= amount, "ERC1155: insufficient balance for transfer" ); unchecked { _balances[id][from] = fromBalance - amount; } _balances[id][to] += amount; } emit TransferBatch(operator, from, to, ids, amounts); _afterTokenTransfer(operator, from, to, ids, amounts, data); } /** * @dev Sets a new URI for all token types, by relying on the token type ID * substitution mechanism * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. * * By this mechanism, any occurrence of the `\{id\}` substring in either the * URI or any of the amounts in the JSON file at said URI will be replaced by * clients with the token type ID. * * For example, the `https://token-cdn-domain/\{id\}.json` URI would be * interpreted by clients as * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json` * for token type ID 0x4cce0. * * See {uri}. * * Because these URIs cannot be meaningfully represented by the {URI} event, * this function emits no events. */ function _setURI(string memory newuri) internal virtual { _uri = newuri; } /** * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function _mint( address to, uint256 id, uint256 amount, bytes memory data ) internal virtual { require(to != address(0), "ERC1155: mint to the zero address"); address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); uint256[] memory amounts = _asSingletonArray(amount); _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); _balances[id][to] += amount; emit TransferSingle(operator, address(0), to, id, amount); _afterTokenTransfer(operator, address(0), to, ids, amounts, data); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function _mintBatch( address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { require(to != address(0), "ERC1155: mint to the zero address"); require( ids.length == amounts.length, "ERC1155: ids and amounts length mismatch" ); address operator = _msgSender(); _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); for (uint256 i = 0; i < ids.length; i++) { _balances[ids[i]][to] += amounts[i]; } emit TransferBatch(operator, address(0), to, ids, amounts); _afterTokenTransfer(operator, address(0), to, ids, amounts, data); } /** * @dev Destroys `amount` tokens of token type `id` from `from` * * Emits a {TransferSingle} event. * * Requirements: * * - `from` cannot be the zero address. * - `from` must have at least `amount` tokens of token type `id`. */ function _burn( address from, uint256 id, uint256 amount ) internal virtual { require(from != address(0), "ERC1155: burn from the zero address"); address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); uint256[] memory amounts = _asSingletonArray(amount); _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); uint256 fromBalance = _balances[id][from]; require(fromBalance >= amount, "ERC1155: burn amount exceeds balance"); unchecked { _balances[id][from] = fromBalance - amount; } emit TransferSingle(operator, from, address(0), id, amount); _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. */ function _burnBatch( address from, uint256[] memory ids, uint256[] memory amounts ) internal virtual { require(from != address(0), "ERC1155: burn from the zero address"); require( ids.length == amounts.length, "ERC1155: ids and amounts length mismatch" ); address operator = _msgSender(); _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); for (uint256 i = 0; i < ids.length; i++) { uint256 id = ids[i]; uint256 amount = amounts[i]; uint256 fromBalance = _balances[id][from]; require( fromBalance >= amount, "ERC1155: burn amount exceeds balance" ); unchecked { _balances[id][from] = fromBalance - amount; } } emit TransferBatch(operator, from, address(0), ids, amounts); _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); } /** * @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, "ERC1155: setting approval status for self"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Hook that is called before any token transfer. This includes minting * and burning, as well as batched variants. * * The same hook is called on both single and batched variants. For single * transfers, the length of the `ids` and `amounts` arrays will be 1. * * Calling conditions (for each `id` and `amount` pair): * * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens * of token type `id` will be transferred to `to`. * - When `from` is zero, `amount` tokens of token type `id` will be minted * for `to`. * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` * will be burned. * - `from` and `to` are never both zero. * - `ids` and `amounts` have the same, non-zero length. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual {} /** * @dev Hook that is called after any token transfer. This includes minting * and burning, as well as batched variants. * * The same hook is called on both single and batched variants. For single * transfers, the length of the `id` and `amount` arrays will be 1. * * Calling conditions (for each `id` and `amount` pair): * * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens * of token type `id` will be transferred to `to`. * - When `from` is zero, `amount` tokens of token type `id` will be minted * for `to`. * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` * will be burned. * - `from` and `to` are never both zero. * - `ids` and `amounts` have the same, non-zero length. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual {} function _doSafeTransferAcceptanceCheck( address operator, address from, address to, uint256 id, uint256 amount, bytes memory data ) private { if (to.isContract()) { try IERC1155ReceiverUpgradeable(to).onERC1155Received( operator, from, id, amount, data ) returns (bytes4 response) { if ( response != IERC1155ReceiverUpgradeable.onERC1155Received.selector ) { revert("ERC1155: ERC1155Receiver rejected tokens"); } } catch Error(string memory reason) { revert(reason); } catch { revert("ERC1155: transfer to non-ERC1155Receiver implementer"); } } } function _doSafeBatchTransferAcceptanceCheck( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) private { if (to.isContract()) { try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived( operator, from, ids, amounts, data ) returns (bytes4 response) { if ( response != IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector ) { revert("ERC1155: ERC1155Receiver rejected tokens"); } } catch Error(string memory reason) { revert(reason); } catch { revert("ERC1155: transfer to non-ERC1155Receiver implementer"); } } } function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) { uint256[] memory array = new uint256[](1); array[0] = element; return array; } /** * @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[47] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155ReceiverUpgradeable is IERC165Upgradeable { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol) pragma solidity ^0.8.0; import "../IERC1155Upgradeable.sol"; /** * @dev Interface of the optional ERC1155MetadataExtension interface, as defined * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. * * _Available since v3.1._ */ interface IERC1155MetadataURIUpgradeable is IERC1155Upgradeable { /** * @dev Returns the URI for token type `id`. * * If the `\{id\}` substring is present in the URI, it must be replaced by * clients with the actual token type ID. */ function uri(uint256 id) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return 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 (last updated v4.8.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * 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 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.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.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 Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __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(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @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 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; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol) pragma solidity ^0.8.0; import "../token/ERC721/IERC721.sol";
// contracts/HotSwapV1.sol // SPDX-License-Identifier: MIT // // Utility contract that provides a convenience swap methods over uniswap // // - Payable methods that automatically convert ETH to WETH // - Automatic refunding of any leftover from swap to sender or another specified address pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/Address.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol"; import "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol"; import "./IWETH9.sol"; contract HotSwapV1 is Ownable { event Airdrop( address indexed addr, address indexed sender, uint256 indexed id, uint256[] types, uint256[] quantities ); address public weth9Address = 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6; // Goerli uint24 public defaultSwapFee = 3000; ISwapRouter public immutable swapRouter; constructor() { swapRouter = ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564); } // Goerli: 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6; // Mainnet: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; function setWeth9Address(address addr) public onlyOwner { weth9Address = addr; } // Enable contract to receive ETH receive() external payable {} // Mechanism to release funds that get sent here accidentally function withdrawAll() public onlyOwner { Address.sendValue(payable(owner()), address(this).balance); } function swap( address outAddress, uint256 amount, address recipient, address refundAddress, uint24 swapFee ) public payable virtual { IWETH9 weth = IWETH9(weth9Address); weth.deposit{value: msg.value}(); // Important to make sure the right value is sent, otherwise you might get a bad swap uint256 maximumEth = msg.value; // Don't need to transfer as contract already owns WETH TransferHelper.safeApprove( weth9Address, address(swapRouter), maximumEth ); ISwapRouter.ExactOutputSingleParams memory params = ISwapRouter .ExactOutputSingleParams({ tokenIn: weth9Address, tokenOut: outAddress, fee: swapFee, recipient: recipient, deadline: block.timestamp + 300, amountOut: amount, amountInMaximum: maximumEth, sqrtPriceLimitX96: 0 }); // Executes the swap returning the amountIn needed to spend to receive the desired amountOut. uint256 amountIn = swapRouter.exactOutputSingle(params); // Refund any excess if (amountIn < msg.value) { // Reset router approval TransferHelper.safeApprove(weth9Address, address(swapRouter), 0); uint256 remainder = msg.value - amountIn; weth.withdraw(remainder); Address.sendValue(payable(refundAddress), remainder); } } // Default swap fee function swap( address outAddress, uint256 amount, address recipient, address refundAddress ) public payable { return swap(outAddress, amount, recipient, refundAddress, defaultSwapFee); } // Default refund target to sender function swap( address outAddress, uint256 amount, address recipient ) public payable { return swap(outAddress, amount, recipient, msg.sender); } // Default recipient and refund target to sender function swap(address outAddress, uint256 amount) public payable { return swap(outAddress, amount, msg.sender); } }
// contracts/PriceFacet.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; error PricesAndQuantitiesDifferentLength(); error PriceNotFound(); error InvalidCurrency(); error Overflow(uint8 z, uint8 x); contract PriceFacet is Ownable { enum Currency { ETH, USD } struct Price { uint256 value; Currency currency; } struct PriceFeeds { AggregatorV3Interface ETHUSD; } PriceFeeds internal priceFeeds; mapping(uint256 => Price) public prices; constructor() { /** * Network: Goerli * Aggregator: ETH/USD * Address: 0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e */ priceFeeds.ETHUSD = AggregatorV3Interface( 0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e ); } function setPriceFeed(uint256 feedIndex, address newPriceFeed) public onlyOwner { if (feedIndex == 0) { priceFeeds.ETHUSD = AggregatorV3Interface(newPriceFeed); } } function getPriceFeed(uint256 feedIndex) public view onlyOwner returns (AggregatorV3Interface aggregator) { if (feedIndex == 0) { return priceFeeds.ETHUSD; } } function _getUSDRate() internal view returns (uint256 rate, uint8 decimalPlaces) { (, int256 price, , , ) = priceFeeds.ETHUSD.latestRoundData(); uint8 decimals = priceFeeds.ETHUSD.decimals(); return (uint256(price), decimals); } function _getPrice(uint256 priceId) internal view returns (uint256 price) { Price memory price_ = prices[priceId]; if (price_.currency == Currency.ETH) { return price_.value; } else { (uint256 rate, uint8 decimals) = _getUSDRate(); uint256 usdValue = price_.value; uint8 powerMultipler = 6; // needed to address rounding error uint256 weiPerDollar = (1 * 10**(18 + decimals + powerMultipler)) / rate; if (price_.currency == Currency.USD) { return ((weiPerDollar * usdValue) / (100 * 10**powerMultipler) + // Convert from cents to dollars and remove power multiplier 1); // Fix 1 Wei rounding error } } revert InvalidCurrency(); } function registerPrice( uint256 priceId, uint256 price, uint256 currencyIndex ) public onlyOwner { Currency currency; if (currencyIndex == 0) { currency = Currency.ETH; } else if (currencyIndex == 1) { currency = Currency.USD; } else { revert InvalidCurrency(); } prices[priceId] = Price(price, currency); } function deregisterPrice(uint256 priceId) public onlyOwner { delete prices[priceId]; } /** * Returns the latest price */ function getPrice(uint256 priceId, uint256 quantity) public view returns (uint256) { return _getPrice(priceId) * (quantity); } /** * Returns the unconverted price */ function getRawPrice(uint256 priceId, uint256 quantity) public view returns (uint256) { Price memory price = prices[priceId]; return price.value * quantity; } /** * Returns the price breakdown and the total price * * - `types` must match length of `amounts` */ function getPriceBreakdown( uint256[] memory priceIds, uint256[] memory quantities ) public view returns (uint256[] memory, uint256) { require( priceIds.length == quantities.length, "Prices and quantity arrays have a different length" ); uint256[] memory breakdown = new uint256[](priceIds.length); uint256 totalPrice = 0; for (uint256 i = 0; i < priceIds.length; i++) { uint256 price = _getPrice(priceIds[i]) * quantities[i]; breakdown[i] = price; totalPrice = totalPrice + price; } return (breakdown, totalPrice); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @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: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * 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 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 IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.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 Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @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 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); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; pragma abicoder v2; import '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol'; /// @title Router token swapping functionality /// @notice Functions for swapping tokens via Uniswap V3 interface ISwapRouter is IUniswapV3SwapCallback { struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } /// @notice Swaps `amountIn` of one token for as much as possible of another token /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata /// @return amountOut The amount of the received token function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); struct ExactInputParams { bytes path; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; } /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata /// @return amountOut The amount of the received token function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); struct ExactOutputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; uint160 sqrtPriceLimitX96; } /// @notice Swaps as little as possible of one token for `amountOut` of another token /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata /// @return amountIn The amount of the input token function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); struct ExactOutputParams { bytes path; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; } /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed) /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata /// @return amountIn The amount of the input token function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.6.0; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; library TransferHelper { /// @notice Transfers tokens from the targeted address to the given destination /// @notice Errors with 'STF' if transfer fails /// @param token The contract address of the token to be transferred /// @param from The originating address from which the tokens will be transferred /// @param to The destination address of the transfer /// @param value The amount to be transferred function safeTransferFrom( address token, address from, address to, uint256 value ) internal { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'STF'); } /// @notice Transfers tokens from msg.sender to a recipient /// @dev Errors with ST if transfer fails /// @param token The contract address of the token which will be transferred /// @param to The recipient of the transfer /// @param value The value of the transfer function safeTransfer( address token, address to, uint256 value ) internal { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'ST'); } /// @notice Approves the stipulated contract to spend the given allowance in the given token /// @dev Errors with 'SA' if transfer fails /// @param token The contract address of the token to be approved /// @param to The target of the approval /// @param value The amount of the given token the target will be allowed to spend function safeApprove( address token, address to, uint256 value ) internal { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'SA'); } /// @notice Transfers ETH to the recipient address /// @dev Fails with `STE` /// @param to The destination of the transfer /// @param value The value to be transferred function safeTransferETH(address to, uint256 value) internal { (bool success, ) = to.call{value: value}(new bytes(0)); require(success, 'STE'); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /// @title Interface for WETH9 interface IWETH9 is IERC20 { /// @notice Deposit ether to get wrapped ether function deposit() external payable; /// @notice Withdraw wrapped ether to get ether function withdraw(uint256) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /// @title Callback for IUniswapV3PoolActions#swap /// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface interface IUniswapV3SwapCallback { /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap. /// @dev In the implementation you must pay the pool tokens owed for the swap. /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped. /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token0 to the pool. /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token1 to the pool. /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call function uniswapV3SwapCallback( int256 amount0Delta, int256 amount1Delta, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); // getRoundData and latestRoundData should both raise "No data present" // if they do not have data to report, instead of returning unset values // which could be misinterpreted as actual reported values. function getRoundData(uint80 _roundId) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../HotSwapV1.sol"; /** * @title HotSwapV1Mock */ contract HotSwapV1Mock is HotSwapV1 { constructor() HotSwapV1() {} function swap( address outAddress, uint256 amount, address recipient, address refundAddress, uint24 swapFee ) public payable override {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; contract AggregatorV3Mock { function decimals() external view returns (uint8 decimals) { return uint8(8); // Mimicing real contract } /** * Returns the latest price */ function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ) { return (0, 130000000000, 0, 0, 0); // i.e. 1300 dollars per ETH } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "erc721a/contracts/ERC721A.sol"; /** * @title ERC721Mock */ contract ERC721Mock is ERC721A { constructor() ERC721A("Mock", "MOCK") {} function mint(address addr, uint256 quantity) external { _mint(addr, quantity); } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.2 // Creator: Chiru Labs pragma solidity ^0.8.4; import './IERC721A.sol'; /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721A * * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...) * starting from `_startTokenId()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Reference type for token approval. struct TokenApprovalRef { address value; } // ============================================================= // CONSTANTS // ============================================================= // Mask of an entry in packed address data. uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant _BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // STORAGE // ============================================================= // The next token ID to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => TokenApprovalRef) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 0; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_currentIndex - _startTokenId()` times. unchecked { return _currentIndex - _burnCounter - _startTokenId(); } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256) { // Counter underflow is impossible as `_currentIndex` does not decrement, // and it is initialized to `_startTokenId()`. unchecked { return _currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return _burnCounter; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) revert BalanceQueryForZeroAddress(); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @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, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) { uint256 curr = tokenId; unchecked { if (_startTokenId() <= curr) if (curr < _currentIndex) { uint256 packed = _packedOwnerships[curr]; // If not burned. if (packed & _BITMASK_BURNED == 0) { // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `curr` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. while (packed == 0) { packed = _packedOwnerships[--curr]; } return packed; } } } revert OwnerQueryForNonexistentToken(); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @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) public virtual override { address owner = ownerOf(tokenId); if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId].value; } /** * @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) public virtual override { if (operator == _msgSenderERC721A()) revert ApproveToCaller(); _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @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. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && // If within bounds, _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned. } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId]`. assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * 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 ) public virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @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 memory _data ) public virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * 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, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); uint256 toMasked; uint256 end = startTokenId + quantity; // Use assembly to loop and emit the `Transfer` event for gas savings. assembly { // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. toMasked := and(to, _BITMASK_ADDRESS) // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. startTokenId // `tokenId`. ) for { let tokenId := add(startTokenId, 1) } iszero(eq(tokenId, end)) { tokenId := add(tokenId, 1) } { // Emit the `Transfer` event. Similar to above. log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId) } } if (toMasked == 0) revert MintToZeroAddress(); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if (!_checkContractOnERC721Received(address(0), to, index++, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } while (index < end); // Reentrancy protection. if (_currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ''); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) revert OwnershipNotInitializedForExtraData(); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * 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, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), // but we allocate 0x80 bytes to keep the free memory pointer 32-byte word aliged. // We will need 1 32-byte word to store the length, // and 3 32-byte words to store a maximum of 78 digits. Total: 0x20 + 3 * 0x20 = 0x80. str := add(mload(0x40), 0x80) // Update the free memory pointer to allocate. mstore(0x40, str) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.2 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * The caller cannot approve to their own address. */ error ApproveToCaller(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @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`, * 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 be 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, bytes calldata data ) external; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * 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); // ============================================================= // IERC721Metadata // ============================================================= /** * @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); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
[{"inputs":[],"name":"AddressMatchesSender","type":"error"},{"inputs":[],"name":"NotEnoughFunds","type":"error"},{"inputs":[],"name":"ProjectDoesNotExist","type":"error"},{"inputs":[],"name":"TypesAndAmountsDifferentLengths","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"types","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"quantities","type":"uint256[]"}],"name":"Airdrop","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"holderAddr","type":"address"},{"indexed":true,"internalType":"address","name":"contractAddr","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"types","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"quantities","type":"uint256[]"}],"name":"AirdropToHolder","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","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":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"types","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"quantities","type":"uint256[]"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"contractAddr","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"types","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"quantities","type":"uint256[]"}],"name":"MintForToken","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":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256[]","name":"types","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"airdrop","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"impactType","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"airdrop","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256[]","name":"types","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"airdropToHolder","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bufferFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"project","type":"uint256"}],"name":"deregisterProject","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"priceId","type":"uint256"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hotSwapAddress","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"uri_","type":"string"},{"internalType":"address payable","name":"_hotSwapAddress","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"impactType","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"types","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256[]","name":"types","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"mintForToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceFacetAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"projects","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"project","type":"uint256"}],"name":"registerProject","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","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":"string","name":"uri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"fee","type":"uint24"}],"name":"setBufferFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"addr","type":"address"}],"name":"setHotSwapAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setPriceFacetAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setStablecoinAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"fee","type":"uint24"}],"name":"setSwapFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setTreasuryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stablecoinAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasuryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50614d7f806100206000396000f3fe60806040526004361061020e5760003560e01c806365e7e8d711610118578063c5f956af116100a0578063e985e9c51161006f578063e985e9c51461073f578063ed31a25d1461077c578063f242432a14610798578063f2fde38b146107c1578063f7831ba7146107ea5761020e565b8063c5f956af14610692578063e1bc2967146106bd578063e4c3a8f8146106d9578063e7572230146107025761020e565b80637ab4339d116100e75780637ab4339d146105c35780638da5cb5b146105ec5780639ecd050014610617578063a22cb46514610640578063c3cab35d146106695761020e565b806365e7e8d71461052f5780636605bfda146105585780636c0360eb14610581578063715018a6146105ac5761020e565b80633357ab901161019b57806354cf2aeb1161016a57806354cf2aeb1461046957806355f804b31461049457806357ab7f8d146104bd5780635f5f394f146104d9578063615737ef146105045761020e565b80633357ab90146103ba5780633716f078146103e55780633d5d190c146104105780634e1273f41461042c5761020e565b80631b2ef1ca116101e25780631b2ef1ca1461030757806326726e6b146103235780632eb2c2d61461034c5780632ed012321461037557806330982093146103915761020e565b8062fdd58e1461021357806301ffc9a7146102505780630e89341c1461028d578063107046bd146102ca575b600080fd5b34801561021f57600080fd5b5061023a60048036038101906102359190613134565b610813565b6040516102479190613183565b60405180910390f35b34801561025c57600080fd5b50610277600480360381019061027291906131f6565b6108dd565b604051610284919061323e565b60405180910390f35b34801561029957600080fd5b506102b460048036038101906102af9190613259565b6109bf565b6040516102c1919061331f565b60405180910390f35b3480156102d657600080fd5b506102f160048036038101906102ec9190613259565b610a53565b6040516102fe919061323e565b60405180910390f35b610321600480360381019061031c9190613341565b610a73565b005b34801561032f57600080fd5b5061034a60048036038101906103459190613259565b610bb2565b005b34801561035857600080fd5b50610373600480360381019061036e919061357e565b610be9565b005b61038f600480360381019061038a919061364d565b610c8a565b005b34801561039d57600080fd5b506103b860048036038101906103b39190613259565b610e43565b005b3480156103c657600080fd5b506103cf610e71565b6040516103dc919061370a565b60405180910390f35b3480156103f157600080fd5b506103fa610e86565b6040516104079190613734565b60405180910390f35b61042a6004803603810190610425919061374f565b610eac565b005b34801561043857600080fd5b50610453600480360381019061044e919061388a565b610f0b565b60405161046091906139c0565b60405180910390f35b34801561047557600080fd5b5061047e611024565b60405161048b919061370a565b60405180910390f35b3480156104a057600080fd5b506104bb60048036038101906104b69190613a83565b611039565b005b6104d760048036038101906104d29190613acc565b61104d565b005b3480156104e557600080fd5b506104ee61112a565b6040516104fb9190613b78565b60405180910390f35b34801561051057600080fd5b50610519611150565b6040516105269190613734565b60405180910390f35b34801561053b57600080fd5b5061055660048036038101906105519190613bbf565b611176565b005b34801561056457600080fd5b5061057f600480360381019061057a9190613bec565b6111a0565b005b34801561058d57600080fd5b506105966111ec565b6040516105a3919061331f565b60405180910390f35b3480156105b857600080fd5b506105c161127a565b005b3480156105cf57600080fd5b506105ea60048036038101906105e59190613c45565b61128e565b005b3480156105f857600080fd5b5061060161159b565b60405161060e9190613734565b60405180910390f35b34801561062357600080fd5b5061063e60048036038101906106399190613bec565b6115c5565b005b34801561064c57600080fd5b5061066760048036038101906106629190613ccd565b611611565b005b34801561067557600080fd5b50610690600480360381019061068b9190613d0d565b611627565b005b34801561069e57600080fd5b506106a7611673565b6040516106b49190613734565b60405180910390f35b6106d760048036038101906106d29190613d3a565b611699565b005b3480156106e557600080fd5b5061070060048036038101906106fb9190613bbf565b611856565b005b34801561070e57600080fd5b5061072960048036038101906107249190613259565b611880565b6040516107369190613183565b60405180910390f35b34801561074b57600080fd5b5061076660048036038101906107619190613d8d565b611892565b604051610773919061323e565b60405180910390f35b6107966004803603810190610791919061364d565b611926565b005b3480156107a457600080fd5b506107bf60048036038101906107ba9190613dcd565b611a34565b005b3480156107cd57600080fd5b506107e860048036038101906107e39190613bec565b611ad5565b005b3480156107f657600080fd5b50610811600480360381019061080c9190613bec565b611b59565b005b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610884576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087b90613ed6565b60405180910390fd5b6097600083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60007fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109a857507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806109b857506109b782611ba5565b5b9050919050565b6060609980546109ce90613f25565b80601f01602080910402602001604051908101604052809291908181526020018280546109fa90613f25565b8015610a475780601f10610a1c57610100808354040283529160200191610a47565b820191906000526020600020905b815481529060010190602001808311610a2a57829003601f168201915b50505050509050919050565b60c96020528060005260406000206000915054906101000a900460ff1681565b6000600167ffffffffffffffff811115610a9057610a8f613386565b5b604051908082528060200260200182016040528015610abe5781602001602082028036833780820191505090505b5090506000600167ffffffffffffffff811115610ade57610add613386565b5b604051908082528060200260200182016040528015610b0c5781602001602082028036833780820191505090505b5090508382600081518110610b2457610b23613f57565b5b6020026020010181815250508281600081518110610b4557610b44613f57565b5b602002602001018181525050610b5c338383611c0f565b3373ffffffffffffffffffffffffffffffffffffffff167f0329a7c1652297b926cc497fd75d078847dbaa7a5a782d651dba3fdf3e8b38da8383604051610ba4929190613f86565b60405180910390a250505050565b610bba611d9d565b600160c9600083815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b610bf1611e1b565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480610c375750610c3685610c31611e1b565b611892565b5b610c76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6d9061402f565b60405180910390fd5b610c838585858585611e23565b5050505050565b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610cf65750610cc761159b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610d35576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d2c906140c1565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff16636352211e866040518263ffffffff1660e01b8152600401610d759190613183565b60206040518083038186803b158015610d8d57600080fd5b505afa158015610da1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc591906140f6565b9050610dd2818585611c0f565b8573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f708341e2d24c705ee746951e3a8cbde086f794a68436365690da4af17968882a878787604051610e3393929190614123565b60405180910390a3505050505050565b610e4b611d9d565b60c9600082815260200190815260200160002060006101000a81549060ff021916905550565b60cd60179054906101000a900462ffffff1681565b60ce60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610eb7338383611c0f565b3373ffffffffffffffffffffffffffffffffffffffff167f0329a7c1652297b926cc497fd75d078847dbaa7a5a782d651dba3fdf3e8b38da8383604051610eff929190613f86565b60405180910390a25050565b60608151835114610f51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f48906141da565b60405180910390fd5b6000835167ffffffffffffffff811115610f6e57610f6d613386565b5b604051908082528060200260200182016040528015610f9c5781602001602082028036833780820191505090505b50905060005b845181101561101957610fe9858281518110610fc157610fc0613f57565b5b6020026020010151858381518110610fdc57610fdb613f57565b5b6020026020010151610813565b828281518110610ffc57610ffb613f57565b5b6020026020010181815250508061101290614229565b9050610fa2565b508091505092915050565b60cd60149054906101000a900462ffffff1681565b611041611d9d565b61104a8161213a565b50565b8273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156110b3576040517fc0daf8d500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110be838383611c0f565b3373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fd9958647173ab60063369eccaa36d7fda75b9872edb2fb97202831b236236545848460405161111d929190613f86565b60405180910390a3505050565b60cc60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60cd60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61117e611d9d565b8060cd60176101000a81548162ffffff021916908362ffffff16021790555050565b6111a8611d9d565b8060cb60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60ca80546111f990613f25565b80601f016020809104026020016040519081016040528092919081815260200182805461122590613f25565b80156112725780601f1061124757610100808354040283529160200191611272565b820191906000526020600020905b81548152906001019060200180831161125557829003601f168201915b505050505081565b611282611d9d565b61128c6000612154565b565b60008060019054906101000a900460ff161590508080156112bf5750600160008054906101000a900460ff1660ff16105b806112ec57506112ce3061221a565b1580156112eb5750600160008054906101000a900460ff1660ff16145b5b61132b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611322906142e4565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015611368576001600060016101000a81548160ff0219169083151502179055505b600060019054906101000a900460ff166113b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ae90614376565b60405180910390fd5b6113bf61159b565b60cb60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507307865c6e87b9f70255377e024ace6630c1eaa37f60cd60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073f1e6adc83a3ce9157832a9ab7cf347211c1a1afa60ce60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160cc60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610bb860cd60146101000a81548162ffffff021916908362ffffff160217905550610bb860cd60176101000a81548162ffffff021916908362ffffff1602179055506115358361223d565b61153d612298565b80156115965760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498600160405161158d91906143e8565b60405180910390a15b505050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6115cd611d9d565b8060cd60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61162361161c611e1b565b83836122f1565b5050565b61162f611d9d565b8060cc60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60cb60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600167ffffffffffffffff8111156116b6576116b5613386565b5b6040519080825280602002602001820160405280156116e45781602001602082028036833780820191505090505b5090506000600167ffffffffffffffff81111561170457611703613386565b5b6040519080825280602002602001820160405280156117325781602001602082028036833780820191505090505b509050838260008151811061174a57611749613f57565b5b602002602001018181525050828160008151811061176b5761176a613f57565b5b6020026020010181815250508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156117dd576040517fc0daf8d500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6117e8858383611c0f565b3373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fd9958647173ab60063369eccaa36d7fda75b9872edb2fb97202831b2362365458484604051611847929190613f86565b60405180910390a35050505050565b61185e611d9d565b8060cd60146101000a81548162ffffff021916908362ffffff16021790555050565b600061188b8261245e565b9050919050565b6000609860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480611992575061196361159b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6119d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c8906140c1565b60405180910390fd5b6119dc848383611c0f565b8373ffffffffffffffffffffffffffffffffffffffff167fc224b885dfb496553cd523ebc16f9035b948cbe0579a3904fdef68dd6824daf9848484604051611a2693929190614123565b60405180910390a250505050565b611a3c611e1b565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480611a825750611a8185611a7c611e1b565b611892565b5b611ac1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ab89061402f565b60405180910390fd5b611ace858585858561255a565b5050505050565b611add611d9d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611b4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4490614475565b60405180910390fd5b611b5681612154565b50565b611b61611d9d565b8060ce60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b8051825114611c4a576040517f9e474eb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b8351811015611d3757828181518110611c6a57611c69613f57565b5b6020026020010151611c95858381518110611c8857611c87613f57565b5b602002602001015161245e565b611c9f9190614495565b82611caa91906144ef565b91506001151560c96000868481518110611cc757611cc6613f57565b5b6020026020010151815260200190815260200160002060009054906101000a900460ff16151514611d24576040517f38fde52b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8080611d2f90614229565b915050611c4e565b5080341015611d72576040517f81b5ad6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d8d848484604051806020016040528060008152506127f9565b611d978383612a18565b50505050565b611da5611e1b565b73ffffffffffffffffffffffffffffffffffffffff16611dc361159b565b73ffffffffffffffffffffffffffffffffffffffff1614611e19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e1090614591565b60405180910390fd5b565b600033905090565b8151835114611e67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e5e90614623565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611ed7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ece906146b5565b60405180910390fd5b6000611ee1611e1b565b9050611ef1818787878787612b84565b60005b84518110156120a5576000858281518110611f1257611f11613f57565b5b602002602001015190506000858381518110611f3157611f30613f57565b5b6020026020010151905060006097600084815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fca90614747565b60405180910390fd5b8181036097600085815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816097600085815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461208a91906144ef565b925050819055505050508061209e90614229565b9050611ef4565b508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb878760405161211c929190613f86565b60405180910390a4612132818787878787612bfb565b505050505050565b8060999080519060200190612150929190612fe9565b5050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff1661228c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228390614376565b60405180910390fd5b61229581612c03565b50565b600060019054906101000a900460ff166122e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122de90614376565b60405180910390fd5b6122ef612c5e565b565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612360576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612357906147d9565b60405180910390fd5b80609860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612451919061323e565b60405180910390a3505050565b60008060ce60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635cf4ee918460016040518363ffffffff1660e01b81526004016124bf92919061482a565b60206040518083038186803b1580156124d757600080fd5b505afa1580156124eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250f9190614868565b90506000620f424060cd60179054906101000a900462ffffff1662ffffff16836125399190614495565b61254391906148c4565b9050808261255191906144ef565b92505050919050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156125ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125c1906146b5565b60405180910390fd5b60006125d4611e1b565b905060006125e185612cbf565b905060006125ee85612cbf565b90506125fe838989858589612b84565b60006097600088815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905085811015612696576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161268d90614747565b60405180910390fd5b8581036097600089815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550856097600089815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461274d91906144ef565b925050819055508773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628a8a6040516127ca9291906148f5565b60405180910390a46127e0848a8a86868a612bfb565b6127ee848a8a8a8a8a612d39565b505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415612869576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161286090614990565b60405180910390fd5b81518351146128ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128a490614623565b60405180910390fd5b60006128b7611e1b565b90506128c881600087878787612b84565b60005b8451811015612982578381815181106128e7576128e6613f57565b5b60200260200101516097600087848151811061290657612905613f57565b5b6020026020010151815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461296891906144ef565b92505081905550808061297a90614229565b9150506128cb565b508473ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516129fa929190613f86565b60405180910390a4612a1181600087878787612bfb565b5050505050565b6000805b8351811015612a8d57828181518110612a3857612a37613f57565b5b6020026020010151612a63858381518110612a5657612a55613f57565b5b6020026020010151612f20565b612a6d9190614495565b82612a7891906144ef565b91508080612a8590614229565b915050612a1c565b50600060cc60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663d69f02ac3460cd60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168560cb60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff163360cd60149054906101000a900462ffffff166040518763ffffffff1660e01b8152600401612b4c9594939291906149b0565b6000604051808303818588803b158015612b6557600080fd5b505af1158015612b79573d6000803e3d6000fd5b505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614612bf3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bea90614a4f565b60405180910390fd5b505050505050565b505050505050565b600060019054906101000a900460ff16612c52576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c4990614376565b60405180910390fd5b612c5b8161213a565b50565b600060019054906101000a900460ff16612cad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ca490614376565b60405180910390fd5b612cbd612cb8611e1b565b612154565b565b60606000600167ffffffffffffffff811115612cde57612cdd613386565b5b604051908082528060200260200182016040528015612d0c5781602001602082028036833780820191505090505b5090508281600081518110612d2457612d23613f57565b5b60200260200101818152505080915050919050565b612d588473ffffffffffffffffffffffffffffffffffffffff1661221a565b15612f18578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b8152600401612d9e959493929190614ac4565b602060405180830381600087803b158015612db857600080fd5b505af1925050508015612de957506040513d601f19601f82011682018060405250810190612de69190614b33565b60015b612e8f57612df5614b6d565b806308c379a01415612e525750612e0a614b8f565b80612e155750612e54565b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e49919061331f565b60405180910390fd5b505b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e8690614c97565b60405180910390fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612f16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0d90614d29565b60405180910390fd5b505b505050505050565b60008060ce60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506127108173ffffffffffffffffffffffffffffffffffffffff1663698ae4308560016040518363ffffffff1660e01b8152600401612f8792919061482a565b60206040518083038186803b158015612f9f57600080fd5b505afa158015612fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fd79190614868565b612fe19190614495565b915050919050565b828054612ff590613f25565b90600052602060002090601f016020900481019282613017576000855561305e565b82601f1061303057805160ff191683800117855561305e565b8280016001018555821561305e579182015b8281111561305d578251825591602001919060010190613042565b5b50905061306b919061306f565b5090565b5b80821115613088576000816000905550600101613070565b5090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006130cb826130a0565b9050919050565b6130db816130c0565b81146130e657600080fd5b50565b6000813590506130f8816130d2565b92915050565b6000819050919050565b613111816130fe565b811461311c57600080fd5b50565b60008135905061312e81613108565b92915050565b6000806040838503121561314b5761314a613096565b5b6000613159858286016130e9565b925050602061316a8582860161311f565b9150509250929050565b61317d816130fe565b82525050565b60006020820190506131986000830184613174565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6131d38161319e565b81146131de57600080fd5b50565b6000813590506131f0816131ca565b92915050565b60006020828403121561320c5761320b613096565b5b600061321a848285016131e1565b91505092915050565b60008115159050919050565b61323881613223565b82525050565b6000602082019050613253600083018461322f565b92915050565b60006020828403121561326f5761326e613096565b5b600061327d8482850161311f565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156132c05780820151818401526020810190506132a5565b838111156132cf576000848401525b50505050565b6000601f19601f8301169050919050565b60006132f182613286565b6132fb8185613291565b935061330b8185602086016132a2565b613314816132d5565b840191505092915050565b6000602082019050818103600083015261333981846132e6565b905092915050565b6000806040838503121561335857613357613096565b5b60006133668582860161311f565b92505060206133778582860161311f565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6133be826132d5565b810181811067ffffffffffffffff821117156133dd576133dc613386565b5b80604052505050565b60006133f061308c565b90506133fc82826133b5565b919050565b600067ffffffffffffffff82111561341c5761341b613386565b5b602082029050602081019050919050565b600080fd5b600061344561344084613401565b6133e6565b905080838252602082019050602084028301858111156134685761346761342d565b5b835b81811015613491578061347d888261311f565b84526020840193505060208101905061346a565b5050509392505050565b600082601f8301126134b0576134af613381565b5b81356134c0848260208601613432565b91505092915050565b600080fd5b600067ffffffffffffffff8211156134e9576134e8613386565b5b6134f2826132d5565b9050602081019050919050565b82818337600083830152505050565b600061352161351c846134ce565b6133e6565b90508281526020810184848401111561353d5761353c6134c9565b5b6135488482856134ff565b509392505050565b600082601f83011261356557613564613381565b5b813561357584826020860161350e565b91505092915050565b600080600080600060a0868803121561359a57613599613096565b5b60006135a8888289016130e9565b95505060206135b9888289016130e9565b945050604086013567ffffffffffffffff8111156135da576135d961309b565b5b6135e68882890161349b565b935050606086013567ffffffffffffffff8111156136075761360661309b565b5b6136138882890161349b565b925050608086013567ffffffffffffffff8111156136345761363361309b565b5b61364088828901613550565b9150509295509295909350565b6000806000806080858703121561366757613666613096565b5b6000613675878288016130e9565b94505060206136868782880161311f565b935050604085013567ffffffffffffffff8111156136a7576136a661309b565b5b6136b38782880161349b565b925050606085013567ffffffffffffffff8111156136d4576136d361309b565b5b6136e08782880161349b565b91505092959194509250565b600062ffffff82169050919050565b613704816136ec565b82525050565b600060208201905061371f60008301846136fb565b92915050565b61372e816130c0565b82525050565b60006020820190506137496000830184613725565b92915050565b6000806040838503121561376657613765613096565b5b600083013567ffffffffffffffff8111156137845761378361309b565b5b6137908582860161349b565b925050602083013567ffffffffffffffff8111156137b1576137b061309b565b5b6137bd8582860161349b565b9150509250929050565b600067ffffffffffffffff8211156137e2576137e1613386565b5b602082029050602081019050919050565b6000613806613801846137c7565b6133e6565b905080838252602082019050602084028301858111156138295761382861342d565b5b835b81811015613852578061383e88826130e9565b84526020840193505060208101905061382b565b5050509392505050565b600082601f83011261387157613870613381565b5b81356138818482602086016137f3565b91505092915050565b600080604083850312156138a1576138a0613096565b5b600083013567ffffffffffffffff8111156138bf576138be61309b565b5b6138cb8582860161385c565b925050602083013567ffffffffffffffff8111156138ec576138eb61309b565b5b6138f88582860161349b565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613937816130fe565b82525050565b6000613949838361392e565b60208301905092915050565b6000602082019050919050565b600061396d82613902565b613977818561390d565b93506139828361391e565b8060005b838110156139b357815161399a888261393d565b97506139a583613955565b925050600181019050613986565b5085935050505092915050565b600060208201905081810360008301526139da8184613962565b905092915050565b600067ffffffffffffffff8211156139fd576139fc613386565b5b613a06826132d5565b9050602081019050919050565b6000613a26613a21846139e2565b6133e6565b905082815260208101848484011115613a4257613a416134c9565b5b613a4d8482856134ff565b509392505050565b600082601f830112613a6a57613a69613381565b5b8135613a7a848260208601613a13565b91505092915050565b600060208284031215613a9957613a98613096565b5b600082013567ffffffffffffffff811115613ab757613ab661309b565b5b613ac384828501613a55565b91505092915050565b600080600060608486031215613ae557613ae4613096565b5b6000613af3868287016130e9565b935050602084013567ffffffffffffffff811115613b1457613b1361309b565b5b613b208682870161349b565b925050604084013567ffffffffffffffff811115613b4157613b4061309b565b5b613b4d8682870161349b565b9150509250925092565b6000613b62826130a0565b9050919050565b613b7281613b57565b82525050565b6000602082019050613b8d6000830184613b69565b92915050565b613b9c816136ec565b8114613ba757600080fd5b50565b600081359050613bb981613b93565b92915050565b600060208284031215613bd557613bd4613096565b5b6000613be384828501613baa565b91505092915050565b600060208284031215613c0257613c01613096565b5b6000613c10848285016130e9565b91505092915050565b613c2281613b57565b8114613c2d57600080fd5b50565b600081359050613c3f81613c19565b92915050565b60008060408385031215613c5c57613c5b613096565b5b600083013567ffffffffffffffff811115613c7a57613c7961309b565b5b613c8685828601613a55565b9250506020613c9785828601613c30565b9150509250929050565b613caa81613223565b8114613cb557600080fd5b50565b600081359050613cc781613ca1565b92915050565b60008060408385031215613ce457613ce3613096565b5b6000613cf2858286016130e9565b9250506020613d0385828601613cb8565b9150509250929050565b600060208284031215613d2357613d22613096565b5b6000613d3184828501613c30565b91505092915050565b600080600060608486031215613d5357613d52613096565b5b6000613d61868287016130e9565b9350506020613d728682870161311f565b9250506040613d838682870161311f565b9150509250925092565b60008060408385031215613da457613da3613096565b5b6000613db2858286016130e9565b9250506020613dc3858286016130e9565b9150509250929050565b600080600080600060a08688031215613de957613de8613096565b5b6000613df7888289016130e9565b9550506020613e08888289016130e9565b9450506040613e198882890161311f565b9350506060613e2a8882890161311f565b925050608086013567ffffffffffffffff811115613e4b57613e4a61309b565b5b613e5788828901613550565b9150509295509295909350565b7f455243313135353a2061646472657373207a65726f206973206e6f742061207660008201527f616c6964206f776e657200000000000000000000000000000000000000000000602082015250565b6000613ec0602a83613291565b9150613ecb82613e64565b604082019050919050565b60006020820190508181036000830152613eef81613eb3565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613f3d57607f821691505b60208210811415613f5157613f50613ef6565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006040820190508181036000830152613fa08185613962565b90508181036020830152613fb48184613962565b90509392505050565b7f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60008201527f6572206f7220617070726f766564000000000000000000000000000000000000602082015250565b6000614019602e83613291565b915061402482613fbd565b604082019050919050565b600060208201905081810360008301526140488161400c565b9050919050565b7f4d75737420626520636f6e74726163742c206465706c6f796572206f72206f7760008201527f6e65720000000000000000000000000000000000000000000000000000000000602082015250565b60006140ab602383613291565b91506140b68261404f565b604082019050919050565b600060208201905081810360008301526140da8161409e565b9050919050565b6000815190506140f0816130d2565b92915050565b60006020828403121561410c5761410b613096565b5b600061411a848285016140e1565b91505092915050565b60006060820190506141386000830186613174565b818103602083015261414a8185613962565b9050818103604083015261415e8184613962565b9050949350505050565b7f455243313135353a206163636f756e747320616e6420696473206c656e67746860008201527f206d69736d617463680000000000000000000000000000000000000000000000602082015250565b60006141c4602983613291565b91506141cf82614168565b604082019050919050565b600060208201905081810360008301526141f3816141b7565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614234826130fe565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614267576142666141fa565b5b600182019050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006142ce602e83613291565b91506142d982614272565b604082019050919050565b600060208201905081810360008301526142fd816142c1565b9050919050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b6000614360602b83613291565b915061436b82614304565b604082019050919050565b6000602082019050818103600083015261438f81614353565b9050919050565b6000819050919050565b600060ff82169050919050565b6000819050919050565b60006143d26143cd6143c884614396565b6143ad565b6143a0565b9050919050565b6143e2816143b7565b82525050565b60006020820190506143fd60008301846143d9565b92915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061445f602683613291565b915061446a82614403565b604082019050919050565b6000602082019050818103600083015261448e81614452565b9050919050565b60006144a0826130fe565b91506144ab836130fe565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156144e4576144e36141fa565b5b828202905092915050565b60006144fa826130fe565b9150614505836130fe565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561453a576145396141fa565b5b828201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061457b602083613291565b915061458682614545565b602082019050919050565b600060208201905081810360008301526145aa8161456e565b9050919050565b7f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060008201527f6d69736d61746368000000000000000000000000000000000000000000000000602082015250565b600061460d602883613291565b9150614618826145b1565b604082019050919050565b6000602082019050818103600083015261463c81614600565b9050919050565b7f455243313135353a207472616e7366657220746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b600061469f602583613291565b91506146aa82614643565b604082019050919050565b600060208201905081810360008301526146ce81614692565b9050919050565b7f455243313135353a20696e73756666696369656e742062616c616e636520666f60008201527f72207472616e7366657200000000000000000000000000000000000000000000602082015250565b6000614731602a83613291565b915061473c826146d5565b604082019050919050565b6000602082019050818103600083015261476081614724565b9050919050565b7f455243313135353a2073657474696e6720617070726f76616c2073746174757360008201527f20666f722073656c660000000000000000000000000000000000000000000000602082015250565b60006147c3602983613291565b91506147ce82614767565b604082019050919050565b600060208201905081810360008301526147f2816147b6565b9050919050565b600061481461480f61480a84614396565b6143ad565b6130fe565b9050919050565b614824816147f9565b82525050565b600060408201905061483f6000830185613174565b61484c602083018461481b565b9392505050565b60008151905061486281613108565b92915050565b60006020828403121561487e5761487d613096565b5b600061488c84828501614853565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006148cf826130fe565b91506148da836130fe565b9250826148ea576148e9614895565b5b828204905092915050565b600060408201905061490a6000830185613174565b6149176020830184613174565b9392505050565b7f455243313135353a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b600061497a602183613291565b91506149858261491e565b604082019050919050565b600060208201905081810360008301526149a98161496d565b9050919050565b600060a0820190506149c56000830188613725565b6149d26020830187613174565b6149df6040830186613725565b6149ec6060830185613725565b6149f960808301846136fb565b9695505050505050565b7f43616e6e6f74207472616e736665720000000000000000000000000000000000600082015250565b6000614a39600f83613291565b9150614a4482614a03565b602082019050919050565b60006020820190508181036000830152614a6881614a2c565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000614a9682614a6f565b614aa08185614a7a565b9350614ab08185602086016132a2565b614ab9816132d5565b840191505092915050565b600060a082019050614ad96000830188613725565b614ae66020830187613725565b614af36040830186613174565b614b006060830185613174565b8181036080830152614b128184614a8b565b90509695505050505050565b600081519050614b2d816131ca565b92915050565b600060208284031215614b4957614b48613096565b5b6000614b5784828501614b1e565b91505092915050565b60008160e01c9050919050565b600060033d1115614b8c5760046000803e614b89600051614b60565b90505b90565b600060443d1015614b9f57614c22565b614ba761308c565b60043d036004823e80513d602482011167ffffffffffffffff82111715614bcf575050614c22565b808201805167ffffffffffffffff811115614bed5750505050614c22565b80602083010160043d038501811115614c0a575050505050614c22565b614c19826020018501866133b5565b82955050505050505b90565b7f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560008201527f526563656976657220696d706c656d656e746572000000000000000000000000602082015250565b6000614c81603483613291565b9150614c8c82614c25565b604082019050919050565b60006020820190508181036000830152614cb081614c74565b9050919050565b7f455243313135353a204552433131353552656365697665722072656a6563746560008201527f6420746f6b656e73000000000000000000000000000000000000000000000000602082015250565b6000614d13602883613291565b9150614d1e82614cb7565b604082019050919050565b60006020820190508181036000830152614d4281614d06565b905091905056fea2646970667358221220b81eea17938f807f657b56294700816e336a20fcc65613b42441faba73b919cf64736f6c63430008090033
Deployed Bytecode
0x60806040526004361061020e5760003560e01c806365e7e8d711610118578063c5f956af116100a0578063e985e9c51161006f578063e985e9c51461073f578063ed31a25d1461077c578063f242432a14610798578063f2fde38b146107c1578063f7831ba7146107ea5761020e565b8063c5f956af14610692578063e1bc2967146106bd578063e4c3a8f8146106d9578063e7572230146107025761020e565b80637ab4339d116100e75780637ab4339d146105c35780638da5cb5b146105ec5780639ecd050014610617578063a22cb46514610640578063c3cab35d146106695761020e565b806365e7e8d71461052f5780636605bfda146105585780636c0360eb14610581578063715018a6146105ac5761020e565b80633357ab901161019b57806354cf2aeb1161016a57806354cf2aeb1461046957806355f804b31461049457806357ab7f8d146104bd5780635f5f394f146104d9578063615737ef146105045761020e565b80633357ab90146103ba5780633716f078146103e55780633d5d190c146104105780634e1273f41461042c5761020e565b80631b2ef1ca116101e25780631b2ef1ca1461030757806326726e6b146103235780632eb2c2d61461034c5780632ed012321461037557806330982093146103915761020e565b8062fdd58e1461021357806301ffc9a7146102505780630e89341c1461028d578063107046bd146102ca575b600080fd5b34801561021f57600080fd5b5061023a60048036038101906102359190613134565b610813565b6040516102479190613183565b60405180910390f35b34801561025c57600080fd5b50610277600480360381019061027291906131f6565b6108dd565b604051610284919061323e565b60405180910390f35b34801561029957600080fd5b506102b460048036038101906102af9190613259565b6109bf565b6040516102c1919061331f565b60405180910390f35b3480156102d657600080fd5b506102f160048036038101906102ec9190613259565b610a53565b6040516102fe919061323e565b60405180910390f35b610321600480360381019061031c9190613341565b610a73565b005b34801561032f57600080fd5b5061034a60048036038101906103459190613259565b610bb2565b005b34801561035857600080fd5b50610373600480360381019061036e919061357e565b610be9565b005b61038f600480360381019061038a919061364d565b610c8a565b005b34801561039d57600080fd5b506103b860048036038101906103b39190613259565b610e43565b005b3480156103c657600080fd5b506103cf610e71565b6040516103dc919061370a565b60405180910390f35b3480156103f157600080fd5b506103fa610e86565b6040516104079190613734565b60405180910390f35b61042a6004803603810190610425919061374f565b610eac565b005b34801561043857600080fd5b50610453600480360381019061044e919061388a565b610f0b565b60405161046091906139c0565b60405180910390f35b34801561047557600080fd5b5061047e611024565b60405161048b919061370a565b60405180910390f35b3480156104a057600080fd5b506104bb60048036038101906104b69190613a83565b611039565b005b6104d760048036038101906104d29190613acc565b61104d565b005b3480156104e557600080fd5b506104ee61112a565b6040516104fb9190613b78565b60405180910390f35b34801561051057600080fd5b50610519611150565b6040516105269190613734565b60405180910390f35b34801561053b57600080fd5b5061055660048036038101906105519190613bbf565b611176565b005b34801561056457600080fd5b5061057f600480360381019061057a9190613bec565b6111a0565b005b34801561058d57600080fd5b506105966111ec565b6040516105a3919061331f565b60405180910390f35b3480156105b857600080fd5b506105c161127a565b005b3480156105cf57600080fd5b506105ea60048036038101906105e59190613c45565b61128e565b005b3480156105f857600080fd5b5061060161159b565b60405161060e9190613734565b60405180910390f35b34801561062357600080fd5b5061063e60048036038101906106399190613bec565b6115c5565b005b34801561064c57600080fd5b5061066760048036038101906106629190613ccd565b611611565b005b34801561067557600080fd5b50610690600480360381019061068b9190613d0d565b611627565b005b34801561069e57600080fd5b506106a7611673565b6040516106b49190613734565b60405180910390f35b6106d760048036038101906106d29190613d3a565b611699565b005b3480156106e557600080fd5b5061070060048036038101906106fb9190613bbf565b611856565b005b34801561070e57600080fd5b5061072960048036038101906107249190613259565b611880565b6040516107369190613183565b60405180910390f35b34801561074b57600080fd5b5061076660048036038101906107619190613d8d565b611892565b604051610773919061323e565b60405180910390f35b6107966004803603810190610791919061364d565b611926565b005b3480156107a457600080fd5b506107bf60048036038101906107ba9190613dcd565b611a34565b005b3480156107cd57600080fd5b506107e860048036038101906107e39190613bec565b611ad5565b005b3480156107f657600080fd5b50610811600480360381019061080c9190613bec565b611b59565b005b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610884576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087b90613ed6565b60405180910390fd5b6097600083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60007fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109a857507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806109b857506109b782611ba5565b5b9050919050565b6060609980546109ce90613f25565b80601f01602080910402602001604051908101604052809291908181526020018280546109fa90613f25565b8015610a475780601f10610a1c57610100808354040283529160200191610a47565b820191906000526020600020905b815481529060010190602001808311610a2a57829003601f168201915b50505050509050919050565b60c96020528060005260406000206000915054906101000a900460ff1681565b6000600167ffffffffffffffff811115610a9057610a8f613386565b5b604051908082528060200260200182016040528015610abe5781602001602082028036833780820191505090505b5090506000600167ffffffffffffffff811115610ade57610add613386565b5b604051908082528060200260200182016040528015610b0c5781602001602082028036833780820191505090505b5090508382600081518110610b2457610b23613f57565b5b6020026020010181815250508281600081518110610b4557610b44613f57565b5b602002602001018181525050610b5c338383611c0f565b3373ffffffffffffffffffffffffffffffffffffffff167f0329a7c1652297b926cc497fd75d078847dbaa7a5a782d651dba3fdf3e8b38da8383604051610ba4929190613f86565b60405180910390a250505050565b610bba611d9d565b600160c9600083815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b610bf1611e1b565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480610c375750610c3685610c31611e1b565b611892565b5b610c76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6d9061402f565b60405180910390fd5b610c838585858585611e23565b5050505050565b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610cf65750610cc761159b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610d35576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d2c906140c1565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff16636352211e866040518263ffffffff1660e01b8152600401610d759190613183565b60206040518083038186803b158015610d8d57600080fd5b505afa158015610da1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc591906140f6565b9050610dd2818585611c0f565b8573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f708341e2d24c705ee746951e3a8cbde086f794a68436365690da4af17968882a878787604051610e3393929190614123565b60405180910390a3505050505050565b610e4b611d9d565b60c9600082815260200190815260200160002060006101000a81549060ff021916905550565b60cd60179054906101000a900462ffffff1681565b60ce60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610eb7338383611c0f565b3373ffffffffffffffffffffffffffffffffffffffff167f0329a7c1652297b926cc497fd75d078847dbaa7a5a782d651dba3fdf3e8b38da8383604051610eff929190613f86565b60405180910390a25050565b60608151835114610f51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f48906141da565b60405180910390fd5b6000835167ffffffffffffffff811115610f6e57610f6d613386565b5b604051908082528060200260200182016040528015610f9c5781602001602082028036833780820191505090505b50905060005b845181101561101957610fe9858281518110610fc157610fc0613f57565b5b6020026020010151858381518110610fdc57610fdb613f57565b5b6020026020010151610813565b828281518110610ffc57610ffb613f57565b5b6020026020010181815250508061101290614229565b9050610fa2565b508091505092915050565b60cd60149054906101000a900462ffffff1681565b611041611d9d565b61104a8161213a565b50565b8273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156110b3576040517fc0daf8d500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110be838383611c0f565b3373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fd9958647173ab60063369eccaa36d7fda75b9872edb2fb97202831b236236545848460405161111d929190613f86565b60405180910390a3505050565b60cc60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60cd60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61117e611d9d565b8060cd60176101000a81548162ffffff021916908362ffffff16021790555050565b6111a8611d9d565b8060cb60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60ca80546111f990613f25565b80601f016020809104026020016040519081016040528092919081815260200182805461122590613f25565b80156112725780601f1061124757610100808354040283529160200191611272565b820191906000526020600020905b81548152906001019060200180831161125557829003601f168201915b505050505081565b611282611d9d565b61128c6000612154565b565b60008060019054906101000a900460ff161590508080156112bf5750600160008054906101000a900460ff1660ff16105b806112ec57506112ce3061221a565b1580156112eb5750600160008054906101000a900460ff1660ff16145b5b61132b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611322906142e4565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015611368576001600060016101000a81548160ff0219169083151502179055505b600060019054906101000a900460ff166113b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ae90614376565b60405180910390fd5b6113bf61159b565b60cb60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507307865c6e87b9f70255377e024ace6630c1eaa37f60cd60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073f1e6adc83a3ce9157832a9ab7cf347211c1a1afa60ce60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160cc60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610bb860cd60146101000a81548162ffffff021916908362ffffff160217905550610bb860cd60176101000a81548162ffffff021916908362ffffff1602179055506115358361223d565b61153d612298565b80156115965760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498600160405161158d91906143e8565b60405180910390a15b505050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6115cd611d9d565b8060cd60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61162361161c611e1b565b83836122f1565b5050565b61162f611d9d565b8060cc60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60cb60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600167ffffffffffffffff8111156116b6576116b5613386565b5b6040519080825280602002602001820160405280156116e45781602001602082028036833780820191505090505b5090506000600167ffffffffffffffff81111561170457611703613386565b5b6040519080825280602002602001820160405280156117325781602001602082028036833780820191505090505b509050838260008151811061174a57611749613f57565b5b602002602001018181525050828160008151811061176b5761176a613f57565b5b6020026020010181815250508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156117dd576040517fc0daf8d500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6117e8858383611c0f565b3373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fd9958647173ab60063369eccaa36d7fda75b9872edb2fb97202831b2362365458484604051611847929190613f86565b60405180910390a35050505050565b61185e611d9d565b8060cd60146101000a81548162ffffff021916908362ffffff16021790555050565b600061188b8261245e565b9050919050565b6000609860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480611992575061196361159b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6119d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c8906140c1565b60405180910390fd5b6119dc848383611c0f565b8373ffffffffffffffffffffffffffffffffffffffff167fc224b885dfb496553cd523ebc16f9035b948cbe0579a3904fdef68dd6824daf9848484604051611a2693929190614123565b60405180910390a250505050565b611a3c611e1b565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480611a825750611a8185611a7c611e1b565b611892565b5b611ac1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ab89061402f565b60405180910390fd5b611ace858585858561255a565b5050505050565b611add611d9d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611b4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4490614475565b60405180910390fd5b611b5681612154565b50565b611b61611d9d565b8060ce60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b8051825114611c4a576040517f9e474eb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b8351811015611d3757828181518110611c6a57611c69613f57565b5b6020026020010151611c95858381518110611c8857611c87613f57565b5b602002602001015161245e565b611c9f9190614495565b82611caa91906144ef565b91506001151560c96000868481518110611cc757611cc6613f57565b5b6020026020010151815260200190815260200160002060009054906101000a900460ff16151514611d24576040517f38fde52b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8080611d2f90614229565b915050611c4e565b5080341015611d72576040517f81b5ad6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d8d848484604051806020016040528060008152506127f9565b611d978383612a18565b50505050565b611da5611e1b565b73ffffffffffffffffffffffffffffffffffffffff16611dc361159b565b73ffffffffffffffffffffffffffffffffffffffff1614611e19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e1090614591565b60405180910390fd5b565b600033905090565b8151835114611e67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e5e90614623565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611ed7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ece906146b5565b60405180910390fd5b6000611ee1611e1b565b9050611ef1818787878787612b84565b60005b84518110156120a5576000858281518110611f1257611f11613f57565b5b602002602001015190506000858381518110611f3157611f30613f57565b5b6020026020010151905060006097600084815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fca90614747565b60405180910390fd5b8181036097600085815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816097600085815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461208a91906144ef565b925050819055505050508061209e90614229565b9050611ef4565b508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb878760405161211c929190613f86565b60405180910390a4612132818787878787612bfb565b505050505050565b8060999080519060200190612150929190612fe9565b5050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff1661228c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228390614376565b60405180910390fd5b61229581612c03565b50565b600060019054906101000a900460ff166122e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122de90614376565b60405180910390fd5b6122ef612c5e565b565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612360576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612357906147d9565b60405180910390fd5b80609860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612451919061323e565b60405180910390a3505050565b60008060ce60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635cf4ee918460016040518363ffffffff1660e01b81526004016124bf92919061482a565b60206040518083038186803b1580156124d757600080fd5b505afa1580156124eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250f9190614868565b90506000620f424060cd60179054906101000a900462ffffff1662ffffff16836125399190614495565b61254391906148c4565b9050808261255191906144ef565b92505050919050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156125ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125c1906146b5565b60405180910390fd5b60006125d4611e1b565b905060006125e185612cbf565b905060006125ee85612cbf565b90506125fe838989858589612b84565b60006097600088815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905085811015612696576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161268d90614747565b60405180910390fd5b8581036097600089815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550856097600089815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461274d91906144ef565b925050819055508773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628a8a6040516127ca9291906148f5565b60405180910390a46127e0848a8a86868a612bfb565b6127ee848a8a8a8a8a612d39565b505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415612869576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161286090614990565b60405180910390fd5b81518351146128ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128a490614623565b60405180910390fd5b60006128b7611e1b565b90506128c881600087878787612b84565b60005b8451811015612982578381815181106128e7576128e6613f57565b5b60200260200101516097600087848151811061290657612905613f57565b5b6020026020010151815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461296891906144ef565b92505081905550808061297a90614229565b9150506128cb565b508473ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516129fa929190613f86565b60405180910390a4612a1181600087878787612bfb565b5050505050565b6000805b8351811015612a8d57828181518110612a3857612a37613f57565b5b6020026020010151612a63858381518110612a5657612a55613f57565b5b6020026020010151612f20565b612a6d9190614495565b82612a7891906144ef565b91508080612a8590614229565b915050612a1c565b50600060cc60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663d69f02ac3460cd60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168560cb60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff163360cd60149054906101000a900462ffffff166040518763ffffffff1660e01b8152600401612b4c9594939291906149b0565b6000604051808303818588803b158015612b6557600080fd5b505af1158015612b79573d6000803e3d6000fd5b505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614612bf3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bea90614a4f565b60405180910390fd5b505050505050565b505050505050565b600060019054906101000a900460ff16612c52576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c4990614376565b60405180910390fd5b612c5b8161213a565b50565b600060019054906101000a900460ff16612cad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ca490614376565b60405180910390fd5b612cbd612cb8611e1b565b612154565b565b60606000600167ffffffffffffffff811115612cde57612cdd613386565b5b604051908082528060200260200182016040528015612d0c5781602001602082028036833780820191505090505b5090508281600081518110612d2457612d23613f57565b5b60200260200101818152505080915050919050565b612d588473ffffffffffffffffffffffffffffffffffffffff1661221a565b15612f18578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b8152600401612d9e959493929190614ac4565b602060405180830381600087803b158015612db857600080fd5b505af1925050508015612de957506040513d601f19601f82011682018060405250810190612de69190614b33565b60015b612e8f57612df5614b6d565b806308c379a01415612e525750612e0a614b8f565b80612e155750612e54565b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e49919061331f565b60405180910390fd5b505b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e8690614c97565b60405180910390fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612f16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0d90614d29565b60405180910390fd5b505b505050505050565b60008060ce60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506127108173ffffffffffffffffffffffffffffffffffffffff1663698ae4308560016040518363ffffffff1660e01b8152600401612f8792919061482a565b60206040518083038186803b158015612f9f57600080fd5b505afa158015612fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fd79190614868565b612fe19190614495565b915050919050565b828054612ff590613f25565b90600052602060002090601f016020900481019282613017576000855561305e565b82601f1061303057805160ff191683800117855561305e565b8280016001018555821561305e579182015b8281111561305d578251825591602001919060010190613042565b5b50905061306b919061306f565b5090565b5b80821115613088576000816000905550600101613070565b5090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006130cb826130a0565b9050919050565b6130db816130c0565b81146130e657600080fd5b50565b6000813590506130f8816130d2565b92915050565b6000819050919050565b613111816130fe565b811461311c57600080fd5b50565b60008135905061312e81613108565b92915050565b6000806040838503121561314b5761314a613096565b5b6000613159858286016130e9565b925050602061316a8582860161311f565b9150509250929050565b61317d816130fe565b82525050565b60006020820190506131986000830184613174565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6131d38161319e565b81146131de57600080fd5b50565b6000813590506131f0816131ca565b92915050565b60006020828403121561320c5761320b613096565b5b600061321a848285016131e1565b91505092915050565b60008115159050919050565b61323881613223565b82525050565b6000602082019050613253600083018461322f565b92915050565b60006020828403121561326f5761326e613096565b5b600061327d8482850161311f565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156132c05780820151818401526020810190506132a5565b838111156132cf576000848401525b50505050565b6000601f19601f8301169050919050565b60006132f182613286565b6132fb8185613291565b935061330b8185602086016132a2565b613314816132d5565b840191505092915050565b6000602082019050818103600083015261333981846132e6565b905092915050565b6000806040838503121561335857613357613096565b5b60006133668582860161311f565b92505060206133778582860161311f565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6133be826132d5565b810181811067ffffffffffffffff821117156133dd576133dc613386565b5b80604052505050565b60006133f061308c565b90506133fc82826133b5565b919050565b600067ffffffffffffffff82111561341c5761341b613386565b5b602082029050602081019050919050565b600080fd5b600061344561344084613401565b6133e6565b905080838252602082019050602084028301858111156134685761346761342d565b5b835b81811015613491578061347d888261311f565b84526020840193505060208101905061346a565b5050509392505050565b600082601f8301126134b0576134af613381565b5b81356134c0848260208601613432565b91505092915050565b600080fd5b600067ffffffffffffffff8211156134e9576134e8613386565b5b6134f2826132d5565b9050602081019050919050565b82818337600083830152505050565b600061352161351c846134ce565b6133e6565b90508281526020810184848401111561353d5761353c6134c9565b5b6135488482856134ff565b509392505050565b600082601f83011261356557613564613381565b5b813561357584826020860161350e565b91505092915050565b600080600080600060a0868803121561359a57613599613096565b5b60006135a8888289016130e9565b95505060206135b9888289016130e9565b945050604086013567ffffffffffffffff8111156135da576135d961309b565b5b6135e68882890161349b565b935050606086013567ffffffffffffffff8111156136075761360661309b565b5b6136138882890161349b565b925050608086013567ffffffffffffffff8111156136345761363361309b565b5b61364088828901613550565b9150509295509295909350565b6000806000806080858703121561366757613666613096565b5b6000613675878288016130e9565b94505060206136868782880161311f565b935050604085013567ffffffffffffffff8111156136a7576136a661309b565b5b6136b38782880161349b565b925050606085013567ffffffffffffffff8111156136d4576136d361309b565b5b6136e08782880161349b565b91505092959194509250565b600062ffffff82169050919050565b613704816136ec565b82525050565b600060208201905061371f60008301846136fb565b92915050565b61372e816130c0565b82525050565b60006020820190506137496000830184613725565b92915050565b6000806040838503121561376657613765613096565b5b600083013567ffffffffffffffff8111156137845761378361309b565b5b6137908582860161349b565b925050602083013567ffffffffffffffff8111156137b1576137b061309b565b5b6137bd8582860161349b565b9150509250929050565b600067ffffffffffffffff8211156137e2576137e1613386565b5b602082029050602081019050919050565b6000613806613801846137c7565b6133e6565b905080838252602082019050602084028301858111156138295761382861342d565b5b835b81811015613852578061383e88826130e9565b84526020840193505060208101905061382b565b5050509392505050565b600082601f83011261387157613870613381565b5b81356138818482602086016137f3565b91505092915050565b600080604083850312156138a1576138a0613096565b5b600083013567ffffffffffffffff8111156138bf576138be61309b565b5b6138cb8582860161385c565b925050602083013567ffffffffffffffff8111156138ec576138eb61309b565b5b6138f88582860161349b565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613937816130fe565b82525050565b6000613949838361392e565b60208301905092915050565b6000602082019050919050565b600061396d82613902565b613977818561390d565b93506139828361391e565b8060005b838110156139b357815161399a888261393d565b97506139a583613955565b925050600181019050613986565b5085935050505092915050565b600060208201905081810360008301526139da8184613962565b905092915050565b600067ffffffffffffffff8211156139fd576139fc613386565b5b613a06826132d5565b9050602081019050919050565b6000613a26613a21846139e2565b6133e6565b905082815260208101848484011115613a4257613a416134c9565b5b613a4d8482856134ff565b509392505050565b600082601f830112613a6a57613a69613381565b5b8135613a7a848260208601613a13565b91505092915050565b600060208284031215613a9957613a98613096565b5b600082013567ffffffffffffffff811115613ab757613ab661309b565b5b613ac384828501613a55565b91505092915050565b600080600060608486031215613ae557613ae4613096565b5b6000613af3868287016130e9565b935050602084013567ffffffffffffffff811115613b1457613b1361309b565b5b613b208682870161349b565b925050604084013567ffffffffffffffff811115613b4157613b4061309b565b5b613b4d8682870161349b565b9150509250925092565b6000613b62826130a0565b9050919050565b613b7281613b57565b82525050565b6000602082019050613b8d6000830184613b69565b92915050565b613b9c816136ec565b8114613ba757600080fd5b50565b600081359050613bb981613b93565b92915050565b600060208284031215613bd557613bd4613096565b5b6000613be384828501613baa565b91505092915050565b600060208284031215613c0257613c01613096565b5b6000613c10848285016130e9565b91505092915050565b613c2281613b57565b8114613c2d57600080fd5b50565b600081359050613c3f81613c19565b92915050565b60008060408385031215613c5c57613c5b613096565b5b600083013567ffffffffffffffff811115613c7a57613c7961309b565b5b613c8685828601613a55565b9250506020613c9785828601613c30565b9150509250929050565b613caa81613223565b8114613cb557600080fd5b50565b600081359050613cc781613ca1565b92915050565b60008060408385031215613ce457613ce3613096565b5b6000613cf2858286016130e9565b9250506020613d0385828601613cb8565b9150509250929050565b600060208284031215613d2357613d22613096565b5b6000613d3184828501613c30565b91505092915050565b600080600060608486031215613d5357613d52613096565b5b6000613d61868287016130e9565b9350506020613d728682870161311f565b9250506040613d838682870161311f565b9150509250925092565b60008060408385031215613da457613da3613096565b5b6000613db2858286016130e9565b9250506020613dc3858286016130e9565b9150509250929050565b600080600080600060a08688031215613de957613de8613096565b5b6000613df7888289016130e9565b9550506020613e08888289016130e9565b9450506040613e198882890161311f565b9350506060613e2a8882890161311f565b925050608086013567ffffffffffffffff811115613e4b57613e4a61309b565b5b613e5788828901613550565b9150509295509295909350565b7f455243313135353a2061646472657373207a65726f206973206e6f742061207660008201527f616c6964206f776e657200000000000000000000000000000000000000000000602082015250565b6000613ec0602a83613291565b9150613ecb82613e64565b604082019050919050565b60006020820190508181036000830152613eef81613eb3565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613f3d57607f821691505b60208210811415613f5157613f50613ef6565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006040820190508181036000830152613fa08185613962565b90508181036020830152613fb48184613962565b90509392505050565b7f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60008201527f6572206f7220617070726f766564000000000000000000000000000000000000602082015250565b6000614019602e83613291565b915061402482613fbd565b604082019050919050565b600060208201905081810360008301526140488161400c565b9050919050565b7f4d75737420626520636f6e74726163742c206465706c6f796572206f72206f7760008201527f6e65720000000000000000000000000000000000000000000000000000000000602082015250565b60006140ab602383613291565b91506140b68261404f565b604082019050919050565b600060208201905081810360008301526140da8161409e565b9050919050565b6000815190506140f0816130d2565b92915050565b60006020828403121561410c5761410b613096565b5b600061411a848285016140e1565b91505092915050565b60006060820190506141386000830186613174565b818103602083015261414a8185613962565b9050818103604083015261415e8184613962565b9050949350505050565b7f455243313135353a206163636f756e747320616e6420696473206c656e67746860008201527f206d69736d617463680000000000000000000000000000000000000000000000602082015250565b60006141c4602983613291565b91506141cf82614168565b604082019050919050565b600060208201905081810360008301526141f3816141b7565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614234826130fe565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614267576142666141fa565b5b600182019050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006142ce602e83613291565b91506142d982614272565b604082019050919050565b600060208201905081810360008301526142fd816142c1565b9050919050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b6000614360602b83613291565b915061436b82614304565b604082019050919050565b6000602082019050818103600083015261438f81614353565b9050919050565b6000819050919050565b600060ff82169050919050565b6000819050919050565b60006143d26143cd6143c884614396565b6143ad565b6143a0565b9050919050565b6143e2816143b7565b82525050565b60006020820190506143fd60008301846143d9565b92915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061445f602683613291565b915061446a82614403565b604082019050919050565b6000602082019050818103600083015261448e81614452565b9050919050565b60006144a0826130fe565b91506144ab836130fe565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156144e4576144e36141fa565b5b828202905092915050565b60006144fa826130fe565b9150614505836130fe565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561453a576145396141fa565b5b828201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061457b602083613291565b915061458682614545565b602082019050919050565b600060208201905081810360008301526145aa8161456e565b9050919050565b7f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060008201527f6d69736d61746368000000000000000000000000000000000000000000000000602082015250565b600061460d602883613291565b9150614618826145b1565b604082019050919050565b6000602082019050818103600083015261463c81614600565b9050919050565b7f455243313135353a207472616e7366657220746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b600061469f602583613291565b91506146aa82614643565b604082019050919050565b600060208201905081810360008301526146ce81614692565b9050919050565b7f455243313135353a20696e73756666696369656e742062616c616e636520666f60008201527f72207472616e7366657200000000000000000000000000000000000000000000602082015250565b6000614731602a83613291565b915061473c826146d5565b604082019050919050565b6000602082019050818103600083015261476081614724565b9050919050565b7f455243313135353a2073657474696e6720617070726f76616c2073746174757360008201527f20666f722073656c660000000000000000000000000000000000000000000000602082015250565b60006147c3602983613291565b91506147ce82614767565b604082019050919050565b600060208201905081810360008301526147f2816147b6565b9050919050565b600061481461480f61480a84614396565b6143ad565b6130fe565b9050919050565b614824816147f9565b82525050565b600060408201905061483f6000830185613174565b61484c602083018461481b565b9392505050565b60008151905061486281613108565b92915050565b60006020828403121561487e5761487d613096565b5b600061488c84828501614853565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006148cf826130fe565b91506148da836130fe565b9250826148ea576148e9614895565b5b828204905092915050565b600060408201905061490a6000830185613174565b6149176020830184613174565b9392505050565b7f455243313135353a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b600061497a602183613291565b91506149858261491e565b604082019050919050565b600060208201905081810360008301526149a98161496d565b9050919050565b600060a0820190506149c56000830188613725565b6149d26020830187613174565b6149df6040830186613725565b6149ec6060830185613725565b6149f960808301846136fb565b9695505050505050565b7f43616e6e6f74207472616e736665720000000000000000000000000000000000600082015250565b6000614a39600f83613291565b9150614a4482614a03565b602082019050919050565b60006020820190508181036000830152614a6881614a2c565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000614a9682614a6f565b614aa08185614a7a565b9350614ab08185602086016132a2565b614ab9816132d5565b840191505092915050565b600060a082019050614ad96000830188613725565b614ae66020830187613725565b614af36040830186613174565b614b006060830185613174565b8181036080830152614b128184614a8b565b90509695505050505050565b600081519050614b2d816131ca565b92915050565b600060208284031215614b4957614b48613096565b5b6000614b5784828501614b1e565b91505092915050565b60008160e01c9050919050565b600060033d1115614b8c5760046000803e614b89600051614b60565b90505b90565b600060443d1015614b9f57614c22565b614ba761308c565b60043d036004823e80513d602482011167ffffffffffffffff82111715614bcf575050614c22565b808201805167ffffffffffffffff811115614bed5750505050614c22565b80602083010160043d038501811115614c0a575050505050614c22565b614c19826020018501866133b5565b82955050505050505b90565b7f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560008201527f526563656976657220696d706c656d656e746572000000000000000000000000602082015250565b6000614c81603483613291565b9150614c8c82614c25565b604082019050919050565b60006020820190508181036000830152614cb081614c74565b9050919050565b7f455243313135353a204552433131353552656365697665722072656a6563746560008201527f6420746f6b656e73000000000000000000000000000000000000000000000000602082015250565b6000614d13602883613291565b9150614d1e82614cb7565b604082019050919050565b60006020820190508181036000830152614d4281614d06565b905091905056fea2646970667358221220b81eea17938f807f657b56294700816e336a20fcc65613b42441faba73b919cf64736f6c63430008090033
Deployed Bytecode Sourcemap
600:9503:24:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3023:305:20;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1986:393;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2778:103;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1325:40:24;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6626:331;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2561:102;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;5086:426:20;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;9173:928:24;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2722:104;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1543:23;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1573:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6266:199;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3485:542:20;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1516:21:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3436:85;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;7236:376;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1435:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1478:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3347:83;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2832:98;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1371:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2071:101:1;;;;;;;;;;;;;:::i;:::-;;1779:618:24;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1441:85:1;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3046:102:24;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4095:181:20;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2936:104:24;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1399:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7776:528;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3262:79;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3960:107;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4343:210:20;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8370:737:24;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4620:394:20;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2321:198:1;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3154:102:24;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3023:305:20;3149:7;3212:1;3193:21;;:7;:21;;;;3172:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;3299:9;:13;3309:2;3299:13;;;;;;;;;;;:22;3313:7;3299:22;;;;;;;;;;;;;;;;3292:29;;3023:305;;;;:::o;1986:393::-;2150:4;2204:37;2189:52;;;:11;:52;;;;:131;;;;2272:48;2257:63;;;:11;:63;;;;2189:131;:183;;;;2336:36;2360:11;2336:23;:36::i;:::-;2189:183;2170:202;;1986:393;;;:::o;2778:103::-;2838:13;2870:4;2863:11;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2778:103;;;:::o;1325:40:24:-;;;;;;;;;;;;;;;;;;;;;;:::o;6626:331::-;6703:22;6742:1;6728:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6703:41;;6754:24;6795:1;6781:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6754:43;;6819:10;6808:5;6814:1;6808:8;;;;;;;;:::i;:::-;;;;;;;:21;;;;;6852:6;6839:7;6847:1;6839:10;;;;;;;;:::i;:::-;;;;;;;:19;;;;;6869:33;6875:10;6887:5;6894:7;6869:5;:33::i;:::-;6923:10;6918:32;;;6935:5;6942:7;6918:32;;;;;;;:::i;:::-;;;;;;;;6693:264;;6626:331;;:::o;2561:102::-;1334:13:1;:11;:13::i;:::-;2652:4:24::1;2632:8;:17;2641:7;2632:17;;;;;;;;;;;;:24;;;;;;;;;;;;;;;;;;2561:102:::0;:::o;5086:426:20:-;5319:12;:10;:12::i;:::-;5311:20;;:4;:20;;;:60;;;;5335:36;5352:4;5358:12;:10;:12::i;:::-;5335:16;:36::i;:::-;5311:60;5290:153;;;;;;;;;;;;:::i;:::-;;;;;;;;;5453:52;5476:4;5482:2;5486:3;5491:7;5500:4;5453:22;:52::i;:::-;5086:426;;;;;:::o;9173:928:24:-;9759:15;9745:29;;:10;:29;;;:54;;;;9792:7;:5;:7::i;:::-;9778:21;;:10;:21;;;9745:54;9724:136;;;;;;;;;;;;:::i;:::-;;;;;;;;;9871:19;9901:15;9871:46;;9928:14;9945:11;:19;;;9965:7;9945:28;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9928:45;;9984:29;9990:6;9998:5;10005:7;9984:5;:29::i;:::-;10053:15;10029:65;;10045:6;10029:65;;;10070:7;10079:5;10086:7;10029:65;;;;;;;;:::i;:::-;;;;;;;;9345:756;;9173:928;;;;:::o;2722:104::-;1334:13:1;:11;:13::i;:::-;2802:8:24::1;:17;2811:7;2802:17;;;;;;;;;;;;2795:24;;;;;;;;;;;2722:104:::0;:::o;1543:23::-;;;;;;;;;;;;;:::o;1573:32::-;;;;;;;;;;;;;:::o;6266:199::-;6377:33;6383:10;6395:5;6402:7;6377:5;:33::i;:::-;6431:10;6426:32;;;6443:5;6450:7;6426:32;;;;;;;:::i;:::-;;;;;;;;6266:199;;:::o;3485:542:20:-;3636:16;3708:3;:10;3689:8;:15;:29;3668:117;;;;;;;;;;;;:::i;:::-;;;;;;;;;3796:30;3843:8;:15;3829:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3796:63;;3875:9;3870:120;3894:8;:15;3890:1;:19;3870:120;;;3949:30;3959:8;3968:1;3959:11;;;;;;;;:::i;:::-;;;;;;;;3972:3;3976:1;3972:6;;;;;;;;:::i;:::-;;;;;;;;3949:9;:30::i;:::-;3930:13;3944:1;3930:16;;;;;;;;:::i;:::-;;;;;;;:49;;;;;3911:3;;;;:::i;:::-;;;3870:120;;;;4007:13;4000:20;;;3485:542;;;;:::o;1516:21:24:-;;;;;;;;;;;;;:::o;3436:85::-;1334:13:1;:11;:13::i;:::-;3502:12:24::1;3510:3;3502:7;:12::i;:::-;3436:85:::0;:::o;7236:376::-;7475:4;7461:18;;:10;:18;;;7457:53;;;7488:22;;;;;;;;;;;;;;7457:53;7521:27;7527:4;7533:5;7540:7;7521:5;:27::i;:::-;7578:10;7564:41;;7572:4;7564:41;;;7590:5;7597:7;7564:41;;;;;;;:::i;:::-;;;;;;;;7236:376;;;:::o;1435:37::-;;;;;;;;;;;;;:::o;1478:32::-;;;;;;;;;;;;;:::o;3347:83::-;1334:13:1;:11;:13::i;:::-;3420:3:24::1;3408:9;;:15;;;;;;;;;;;;;;;;;;3347:83:::0;:::o;2832:98::-;1334:13:1;:11;:13::i;:::-;2919:4:24::1;2901:15;;:22;;;;;;;;;;;;;;;;;;2832:98:::0;:::o;1371:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;2071:101:1:-;1334:13;:11;:13::i;:::-;2135:30:::1;2162:1;2135:18;:30::i;:::-;2071:101::o:0;1779:618:24:-;3268:19:2;3291:13;;;;;;;;;;;3290:14;3268:36;;3336:14;:34;;;;;3369:1;3354:12;;;;;;;;;;:16;;;3336:34;3335:108;;;;3377:44;3415:4;3377:29;:44::i;:::-;3376:45;:66;;;;;3441:1;3425:12;;;;;;;;;;:17;;;3376:66;3335:108;3314:201;;;;;;;;;;;;:::i;:::-;;;;;;;;;3540:1;3525:12;;:16;;;;;;;;;;;;;;;;;;3555:14;3551:65;;;3601:4;3585:13;;:20;;;;;;;;;;;;;;;;;;3551:65;5363:13:::1;;;;;;;;;;;5355:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;1944:7:24::2;:5;:7::i;:::-;1926:15;;:25;;;;;;;;;;;;;;;;;;2109:42;2089:17;;:62;;;;;;;;;;;;;;;;;;2182:42;2162:17;;:62;;;;;;;;;;;;;;;;;;2252:15;2235:14;;:32;;;;;;;;;;;;;;;;;;2288:4;2278:7;;:14;;;;;;;;;;;;;;;;;;2314:4;2302:9;;:16;;;;;;;;;;;;;;;;;;2344:20;2359:4;2344:14;:20::i;:::-;2374:16;:14;:16::i;:::-;3640:14:2::0;3636:99;;;3686:5;3670:13;;:21;;;;;;;;;;;;;;;;;;3710:14;3722:1;3710:14;;;;;;:::i;:::-;;;;;;;;3636:99;3258:483;1779:618:24;;:::o;1441:85:1:-;1487:7;1513:6;;;;;;;;;;;1506:13;;1441:85;:::o;3046:102:24:-;1334:13:1;:11;:13::i;:::-;3137:4:24::1;3117:17;;:24;;;;;;;;;;;;;;;;;;3046:102:::0;:::o;4095:181:20:-;4217:52;4236:12;:10;:12::i;:::-;4250:8;4260;4217:18;:52::i;:::-;4095:181;;:::o;2936:104:24:-;1334:13:1;:11;:13::i;:::-;3029:4:24::1;3012:14;;:21;;;;;;;;;;;;;;;;;;2936:104:::0;:::o;1399:30::-;;;;;;;;;;;;;:::o;7776:528::-;7900:22;7939:1;7925:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7900:41;;7951:24;7992:1;7978:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7951:43;;8016:10;8005:5;8011:1;8005:8;;;;;;;;:::i;:::-;;;;;;;:21;;;;;8049:6;8036:7;8044:1;8036:10;;;;;;;;:::i;:::-;;;;;;;:19;;;;;8167:4;8153:18;;:10;:18;;;8149:53;;;8180:22;;;;;;;;;;;;;;8149:53;8213:27;8219:4;8225:5;8232:7;8213:5;:27::i;:::-;8270:10;8256:41;;8264:4;8256:41;;;8282:5;8289:7;8256:41;;;;;;;:::i;:::-;;;;;;;;7890:414;;7776:528;;;:::o;3262:79::-;1334:13:1;:11;:13::i;:::-;3331:3:24::1;3321:7;;:13;;;;;;;;;;;;;;;;;;3262:79:::0;:::o;3960:107::-;4016:7;4042:18;4052:7;4042:9;:18::i;:::-;4035:25;;3960:107;;;:::o;4343:210:20:-;4482:4;4509:18;:27;4528:7;4509:27;;;;;;;;;;;;;;;:37;4537:8;4509:37;;;;;;;;;;;;;;;;;;;;;;;;;4502:44;;4343:210;;;;:::o;8370:737:24:-;8880:15;8866:29;;:10;:29;;;:54;;;;8913:7;:5;:7::i;:::-;8899:21;;:10;:21;;;8866:54;8845:136;;;;;;;;;;;;:::i;:::-;;;;;;;;;8992:38;8998:15;9015:5;9022:7;8992:5;:38::i;:::-;9059:15;9046:54;;;9076:7;9085:5;9092:7;9046:54;;;;;;;;:::i;:::-;;;;;;;;8370:737;;;;:::o;4620:394:20:-;4828:12;:10;:12::i;:::-;4820:20;;:4;:20;;;:60;;;;4844:36;4861:4;4867:12;:10;:12::i;:::-;4844:16;:36::i;:::-;4820:60;4799:153;;;;;;;;;;;;:::i;:::-;;;;;;;;;4962:45;4980:4;4986:2;4990;4994:6;5002:4;4962:17;:45::i;:::-;4620:394;;;;;:::o;2321:198:1:-;1334:13;:11;:13::i;:::-;2429:1:::1;2409:22;;:8;:22;;;;2401:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;2484:28;2503:8;2484:18;:28::i;:::-;2321:198:::0;:::o;3154:102:24:-;1334:13:1;:11;:13::i;:::-;3245:4:24::1;3225:17;;:24;;;;;;;;;;;;;;;;;;3154:102:::0;:::o;1060:166:8:-;1145:4;1183:36;1168:51;;;:11;:51;;;;1161:58;;1060:166;;;:::o;5445:608:24:-;5593:7;:14;5577:5;:12;:30;5573:88;;5628:33;;;;;;;;;;;;;;5573:88;5672:18;5710:9;5705:201;5729:5;:12;5725:1;:16;5705:201;;;5810:7;5818:1;5810:10;;;;;;;;:::i;:::-;;;;;;;;5788:19;5798:5;5804:1;5798:8;;;;;;;;:::i;:::-;;;;;;;;5788:9;:19::i;:::-;:32;;;;:::i;:::-;5775:10;:45;;;;:::i;:::-;5762:58;;5861:4;5839:26;;:8;:18;5848:5;5854:1;5848:8;;;;;;;;:::i;:::-;;;;;;;;5839:18;;;;;;;;;;;;;;;;;;;;;:26;;;5835:60;;5874:21;;;;;;;;;;;;;;5835:60;5743:3;;;;;:::i;:::-;;;;5705:201;;;;5932:10;5920:9;:22;5916:51;;;5951:16;;;;;;;;;;;;;;5916:51;5978:36;5989:4;5995:5;6002:7;5978:36;;;;;;;;;;;;:10;:36::i;:::-;6025:21;6031:5;6038:7;6025:5;:21::i;:::-;5563:490;5445:608;;;:::o;1599:130:1:-;1673:12;:10;:12::i;:::-;1662:23;;:7;:5;:7::i;:::-;:23;;;1654:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;1599:130::o;850:96:7:-;903:7;929:10;922:17;;850:96;:::o;7289:1109:20:-;7522:7;:14;7508:3;:10;:28;7487:115;;;;;;;;;;;;:::i;:::-;;;;;;;;;7634:1;7620:16;;:2;:16;;;;7612:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;7689:16;7708:12;:10;:12::i;:::-;7689:31;;7731:60;7752:8;7762:4;7768:2;7772:3;7777:7;7786:4;7731:20;:60::i;:::-;7807:9;7802:457;7826:3;:10;7822:1;:14;7802:457;;;7857:10;7870:3;7874:1;7870:6;;;;;;;;:::i;:::-;;;;;;;;7857:19;;7890:14;7907:7;7915:1;7907:10;;;;;;;;:::i;:::-;;;;;;;;7890:27;;7932:19;7954:9;:13;7964:2;7954:13;;;;;;;;;;;:19;7968:4;7954:19;;;;;;;;;;;;;;;;7932:41;;8027:6;8012:11;:21;;7987:122;;;;;;;;;;;;:::i;:::-;;;;;;;;;8187:6;8173:11;:20;8151:9;:13;8161:2;8151:13;;;;;;;;;;;:19;8165:4;8151:19;;;;;;;;;;;;;;;:42;;;;8242:6;8221:9;:13;8231:2;8221:13;;;;;;;;;;;:17;8235:2;8221:17;;;;;;;;;;;;;;;;:27;;;;;;;:::i;:::-;;;;;;;;7843:416;;;7838:3;;;;:::i;:::-;;;7802:457;;;;8304:2;8274:47;;8298:4;8274:47;;8288:8;8274:47;;;8308:3;8313:7;8274:47;;;;;;;:::i;:::-;;;;;;;;8332:59;8352:8;8362:4;8368:2;8372:3;8377:7;8386:4;8332:19;:59::i;:::-;7477:921;7289:1109;;;;;:::o;9221:86::-;9294:6;9287:4;:13;;;;;;;;;;;;:::i;:::-;;9221:86;:::o;2673:187:1:-;2746:16;2765:6;;;;;;;;;;;2746:25;;2790:8;2781:6;;:17;;;;;;;;;;;;;;;;;;2844:8;2813:40;;2834:8;2813:40;;;;;;;;;;;;2736:124;2673:187;:::o;1186:320:6:-;1246:4;1498:1;1476:7;:19;;;:23;1469:30;;1186:320;;;:::o;1666:117:20:-;5363:13:2;;;;;;;;;;;5355:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;1746:30:20::1;1771:4;1746:24;:30::i;:::-;1666:117:::0;:::o;1003:95:1:-;5363:13:2;;;;;;;;;;;5355:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;1065:26:1::1;:24;:26::i;:::-;1003:95::o:0;13897:323:20:-;14047:8;14038:17;;:5;:17;;;;14030:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;14149:8;14111:18;:25;14130:5;14111:25;;;;;;;;;;;;;;;:35;14137:8;14111:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;14194:8;14172:41;;14187:5;14172:41;;;14204:8;14172:41;;;;;;:::i;:::-;;;;;;;;13897:323;;;:::o;3707:247:24:-;3766:7;3785:13;3812:17;;;;;;;;;;;3801:38;;;3840:7;3849:1;3801:50;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3785:66;;3861:18;3904:7;3891:9;;;;;;;;;;;3883:17;;:5;:17;;;;:::i;:::-;3882:29;;;;:::i;:::-;3861:50;;3937:10;3929:5;:18;;;;:::i;:::-;3922:25;;;;3707:247;;;:::o;5962:981:20:-;6157:1;6143:16;;:2;:16;;;;6135:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;6212:16;6231:12;:10;:12::i;:::-;6212:31;;6253:20;6276:21;6294:2;6276:17;:21::i;:::-;6253:44;;6307:24;6334:25;6352:6;6334:17;:25::i;:::-;6307:52;;6370:60;6391:8;6401:4;6407:2;6411:3;6416:7;6425:4;6370:20;:60::i;:::-;6441:19;6463:9;:13;6473:2;6463:13;;;;;;;;;;;:19;6477:4;6463:19;;;;;;;;;;;;;;;;6441:41;;6528:6;6513:11;:21;;6492:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;6672:6;6658:11;:20;6636:9;:13;6646:2;6636:13;;;;;;;;;;;:19;6650:4;6636:19;;;;;;;;;;;;;;;:42;;;;6719:6;6698:9;:13;6708:2;6698:13;;;;;;;;;;;:17;6712:2;6698:17;;;;;;;;;;;;;;;;:27;;;;;;;:::i;:::-;;;;;;;;6772:2;6741:46;;6766:4;6741:46;;6756:8;6741:46;;;6776:2;6780:6;6741:46;;;;;;;:::i;:::-;;;;;;;;6798:59;6818:8;6828:4;6834:2;6838:3;6843:7;6852:4;6798:19;:59::i;:::-;6868:68;6899:8;6909:4;6915:2;6919;6923:6;6931:4;6868:30;:68::i;:::-;6125:818;;;;5962:981;;;;;:::o;10694:733::-;10880:1;10866:16;;:2;:16;;;;10858:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;10965:7;:14;10951:3;:10;:28;10930:115;;;;;;;;;;;;:::i;:::-;;;;;;;;;11056:16;11075:12;:10;:12::i;:::-;11056:31;;11098:66;11119:8;11137:1;11141:2;11145:3;11150:7;11159:4;11098:20;:66::i;:::-;11180:9;11175:101;11199:3;:10;11195:1;:14;11175:101;;;11255:7;11263:1;11255:10;;;;;;;;:::i;:::-;;;;;;;;11230:9;:17;11240:3;11244:1;11240:6;;;;;;;;:::i;:::-;;;;;;;;11230:17;;;;;;;;;;;:21;11248:2;11230:21;;;;;;;;;;;;;;;;:35;;;;;;;:::i;:::-;;;;;;;;11211:3;;;;;:::i;:::-;;;;11175:101;;;;11327:2;11291:53;;11323:1;11291:53;;11305:8;11291:53;;;11331:3;11336:7;11291:53;;;;;;;:::i;:::-;;;;;;;;11355:65;11375:8;11393:1;11397:2;11401:3;11406:7;11415:4;11355:19;:65::i;:::-;10848:579;10694:733;;;;:::o;4670:769:24:-;4754:16;4996:9;4991:125;5015:5;:12;5011:1;:16;4991:125;;;5095:7;5103:1;5095:10;;;;;;;;:::i;:::-;;;;;;;;5070:22;5083:5;5089:1;5083:8;;;;;;;;:::i;:::-;;;;;;;;5070:12;:22::i;:::-;:35;;;;:::i;:::-;5059:8;:46;;;;:::i;:::-;5048:57;;5029:3;;;;;:::i;:::-;;;;4991:125;;;;5126:17;5156:14;;;;;;;;;;;5126:45;;5265:7;:12;;;5285:9;5309:17;;;;;;;;;;;5340:8;5362:15;;;;;;;;;;;5391:10;5415:7;;;;;;;;;;;5265:167;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4744:695;;4670:769;;:::o;4412:252::-;4635:1;4619:18;;:4;:18;;;4611:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;4412:252;;;;;;:::o;16303:213:20:-;;;;;;;:::o;1789:130::-;5363:13:2;;;;;;;;;;;5355:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;1899:13:20::1;1907:4;1899:7;:13::i;:::-;1789:130:::0;:::o;1104:111:1:-;5363:13:2;;;;;;;;;;;5355:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;1176:32:1::1;1195:12;:10;:12::i;:::-;1176:18;:32::i;:::-;1104:111::o:0;18473:221:20:-;18563:16;18595:22;18634:1;18620:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18595:41;;18657:7;18646:5;18652:1;18646:8;;;;;;;;:::i;:::-;;;;;;;:18;;;;;18682:5;18675:12;;;18473:221;;;:::o;16522:951::-;16729:15;:2;:13;;;:15::i;:::-;16725:742;;;16808:2;16780:49;;;16851:8;16881:4;16907:2;16931:6;16959:4;16780:201;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;16760:697;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;17333:6;17326:14;;;;;;;;;;;:::i;:::-;;;;;;;;16760:697;;;17380:62;;;;;;;;;;:::i;:::-;;;;;;;;16760:697;17095:54;;;17063:86;;;:8;:86;;;;17038:221;;17190:50;;;;;;;;;;:::i;:::-;;;;;;;;17038:221;16994:279;16725:742;16522:951;;;;;;:::o;4162:244:24:-;4226:7;4245:21;4280:17;;;;;;;;;;;4245:53;;4355:5;4316:10;:22;;;4339:9;4350:1;4316:36;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;;;;:::i;:::-;4309:51;;;4162:244;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:75:30:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:126;371:7;411:42;404:5;400:54;389:65;;334:126;;;:::o;466:96::-;503:7;532:24;550:5;532:24;:::i;:::-;521:35;;466:96;;;:::o;568:122::-;641:24;659:5;641:24;:::i;:::-;634:5;631:35;621:63;;680:1;677;670:12;621:63;568:122;:::o;696:139::-;742:5;780:6;767:20;758:29;;796:33;823:5;796:33;:::i;:::-;696:139;;;;:::o;841:77::-;878:7;907:5;896:16;;841:77;;;:::o;924:122::-;997:24;1015:5;997:24;:::i;:::-;990:5;987:35;977:63;;1036:1;1033;1026:12;977:63;924:122;:::o;1052:139::-;1098:5;1136:6;1123:20;1114:29;;1152:33;1179:5;1152:33;:::i;:::-;1052:139;;;;:::o;1197:474::-;1265:6;1273;1322:2;1310:9;1301:7;1297:23;1293:32;1290:119;;;1328:79;;:::i;:::-;1290:119;1448:1;1473:53;1518:7;1509:6;1498:9;1494:22;1473:53;:::i;:::-;1463:63;;1419:117;1575:2;1601:53;1646:7;1637:6;1626:9;1622:22;1601:53;:::i;:::-;1591:63;;1546:118;1197:474;;;;;:::o;1677:118::-;1764:24;1782:5;1764:24;:::i;:::-;1759:3;1752:37;1677:118;;:::o;1801:222::-;1894:4;1932:2;1921:9;1917:18;1909:26;;1945:71;2013:1;2002:9;1998:17;1989:6;1945:71;:::i;:::-;1801:222;;;;:::o;2029:149::-;2065:7;2105:66;2098:5;2094:78;2083:89;;2029:149;;;:::o;2184:120::-;2256:23;2273:5;2256:23;:::i;:::-;2249:5;2246:34;2236:62;;2294:1;2291;2284:12;2236:62;2184:120;:::o;2310:137::-;2355:5;2393:6;2380:20;2371:29;;2409:32;2435:5;2409:32;:::i;:::-;2310:137;;;;:::o;2453:327::-;2511:6;2560:2;2548:9;2539:7;2535:23;2531:32;2528:119;;;2566:79;;:::i;:::-;2528:119;2686:1;2711:52;2755:7;2746:6;2735:9;2731:22;2711:52;:::i;:::-;2701:62;;2657:116;2453:327;;;;:::o;2786:90::-;2820:7;2863:5;2856:13;2849:21;2838:32;;2786:90;;;:::o;2882:109::-;2963:21;2978:5;2963:21;:::i;:::-;2958:3;2951:34;2882:109;;:::o;2997:210::-;3084:4;3122:2;3111:9;3107:18;3099:26;;3135:65;3197:1;3186:9;3182:17;3173:6;3135:65;:::i;:::-;2997:210;;;;:::o;3213:329::-;3272:6;3321:2;3309:9;3300:7;3296:23;3292:32;3289:119;;;3327:79;;:::i;:::-;3289:119;3447:1;3472:53;3517:7;3508:6;3497:9;3493:22;3472:53;:::i;:::-;3462:63;;3418:117;3213:329;;;;:::o;3548:99::-;3600:6;3634:5;3628:12;3618:22;;3548:99;;;:::o;3653:169::-;3737:11;3771:6;3766:3;3759:19;3811:4;3806:3;3802:14;3787:29;;3653:169;;;;:::o;3828:307::-;3896:1;3906:113;3920:6;3917:1;3914:13;3906:113;;;4005:1;4000:3;3996:11;3990:18;3986:1;3981:3;3977:11;3970:39;3942:2;3939:1;3935:10;3930:15;;3906:113;;;4037:6;4034:1;4031:13;4028:101;;;4117:1;4108:6;4103:3;4099:16;4092:27;4028:101;3877:258;3828:307;;;:::o;4141:102::-;4182:6;4233:2;4229:7;4224:2;4217:5;4213:14;4209:28;4199:38;;4141:102;;;:::o;4249:364::-;4337:3;4365:39;4398:5;4365:39;:::i;:::-;4420:71;4484:6;4479:3;4420:71;:::i;:::-;4413:78;;4500:52;4545:6;4540:3;4533:4;4526:5;4522:16;4500:52;:::i;:::-;4577:29;4599:6;4577:29;:::i;:::-;4572:3;4568:39;4561:46;;4341:272;4249:364;;;;:::o;4619:313::-;4732:4;4770:2;4759:9;4755:18;4747:26;;4819:9;4813:4;4809:20;4805:1;4794:9;4790:17;4783:47;4847:78;4920:4;4911:6;4847:78;:::i;:::-;4839:86;;4619:313;;;;:::o;4938:474::-;5006:6;5014;5063:2;5051:9;5042:7;5038:23;5034:32;5031:119;;;5069:79;;:::i;:::-;5031:119;5189:1;5214:53;5259:7;5250:6;5239:9;5235:22;5214:53;:::i;:::-;5204:63;;5160:117;5316:2;5342:53;5387:7;5378:6;5367:9;5363:22;5342:53;:::i;:::-;5332:63;;5287:118;4938:474;;;;;:::o;5418:117::-;5527:1;5524;5517:12;5541:180;5589:77;5586:1;5579:88;5686:4;5683:1;5676:15;5710:4;5707:1;5700:15;5727:281;5810:27;5832:4;5810:27;:::i;:::-;5802:6;5798:40;5940:6;5928:10;5925:22;5904:18;5892:10;5889:34;5886:62;5883:88;;;5951:18;;:::i;:::-;5883:88;5991:10;5987:2;5980:22;5770:238;5727:281;;:::o;6014:129::-;6048:6;6075:20;;:::i;:::-;6065:30;;6104:33;6132:4;6124:6;6104:33;:::i;:::-;6014:129;;;:::o;6149:311::-;6226:4;6316:18;6308:6;6305:30;6302:56;;;6338:18;;:::i;:::-;6302:56;6388:4;6380:6;6376:17;6368:25;;6448:4;6442;6438:15;6430:23;;6149:311;;;:::o;6466:117::-;6575:1;6572;6565:12;6606:710;6702:5;6727:81;6743:64;6800:6;6743:64;:::i;:::-;6727:81;:::i;:::-;6718:90;;6828:5;6857:6;6850:5;6843:21;6891:4;6884:5;6880:16;6873:23;;6944:4;6936:6;6932:17;6924:6;6920:30;6973:3;6965:6;6962:15;6959:122;;;6992:79;;:::i;:::-;6959:122;7107:6;7090:220;7124:6;7119:3;7116:15;7090:220;;;7199:3;7228:37;7261:3;7249:10;7228:37;:::i;:::-;7223:3;7216:50;7295:4;7290:3;7286:14;7279:21;;7166:144;7150:4;7145:3;7141:14;7134:21;;7090:220;;;7094:21;6708:608;;6606:710;;;;;:::o;7339:370::-;7410:5;7459:3;7452:4;7444:6;7440:17;7436:27;7426:122;;7467:79;;:::i;:::-;7426:122;7584:6;7571:20;7609:94;7699:3;7691:6;7684:4;7676:6;7672:17;7609:94;:::i;:::-;7600:103;;7416:293;7339:370;;;;:::o;7715:117::-;7824:1;7821;7814:12;7838:307;7899:4;7989:18;7981:6;7978:30;7975:56;;;8011:18;;:::i;:::-;7975:56;8049:29;8071:6;8049:29;:::i;:::-;8041:37;;8133:4;8127;8123:15;8115:23;;7838:307;;;:::o;8151:154::-;8235:6;8230:3;8225;8212:30;8297:1;8288:6;8283:3;8279:16;8272:27;8151:154;;;:::o;8311:410::-;8388:5;8413:65;8429:48;8470:6;8429:48;:::i;:::-;8413:65;:::i;:::-;8404:74;;8501:6;8494:5;8487:21;8539:4;8532:5;8528:16;8577:3;8568:6;8563:3;8559:16;8556:25;8553:112;;;8584:79;;:::i;:::-;8553:112;8674:41;8708:6;8703:3;8698;8674:41;:::i;:::-;8394:327;8311:410;;;;;:::o;8740:338::-;8795:5;8844:3;8837:4;8829:6;8825:17;8821:27;8811:122;;8852:79;;:::i;:::-;8811:122;8969:6;8956:20;8994:78;9068:3;9060:6;9053:4;9045:6;9041:17;8994:78;:::i;:::-;8985:87;;8801:277;8740:338;;;;:::o;9084:1509::-;9238:6;9246;9254;9262;9270;9319:3;9307:9;9298:7;9294:23;9290:33;9287:120;;;9326:79;;:::i;:::-;9287:120;9446:1;9471:53;9516:7;9507:6;9496:9;9492:22;9471:53;:::i;:::-;9461:63;;9417:117;9573:2;9599:53;9644:7;9635:6;9624:9;9620:22;9599:53;:::i;:::-;9589:63;;9544:118;9729:2;9718:9;9714:18;9701:32;9760:18;9752:6;9749:30;9746:117;;;9782:79;;:::i;:::-;9746:117;9887:78;9957:7;9948:6;9937:9;9933:22;9887:78;:::i;:::-;9877:88;;9672:303;10042:2;10031:9;10027:18;10014:32;10073:18;10065:6;10062:30;10059:117;;;10095:79;;:::i;:::-;10059:117;10200:78;10270:7;10261:6;10250:9;10246:22;10200:78;:::i;:::-;10190:88;;9985:303;10355:3;10344:9;10340:19;10327:33;10387:18;10379:6;10376:30;10373:117;;;10409:79;;:::i;:::-;10373:117;10514:62;10568:7;10559:6;10548:9;10544:22;10514:62;:::i;:::-;10504:72;;10298:288;9084:1509;;;;;;;;:::o;10599:1185::-;10735:6;10743;10751;10759;10808:3;10796:9;10787:7;10783:23;10779:33;10776:120;;;10815:79;;:::i;:::-;10776:120;10935:1;10960:53;11005:7;10996:6;10985:9;10981:22;10960:53;:::i;:::-;10950:63;;10906:117;11062:2;11088:53;11133:7;11124:6;11113:9;11109:22;11088:53;:::i;:::-;11078:63;;11033:118;11218:2;11207:9;11203:18;11190:32;11249:18;11241:6;11238:30;11235:117;;;11271:79;;:::i;:::-;11235:117;11376:78;11446:7;11437:6;11426:9;11422:22;11376:78;:::i;:::-;11366:88;;11161:303;11531:2;11520:9;11516:18;11503:32;11562:18;11554:6;11551:30;11548:117;;;11584:79;;:::i;:::-;11548:117;11689:78;11759:7;11750:6;11739:9;11735:22;11689:78;:::i;:::-;11679:88;;11474:303;10599:1185;;;;;;;:::o;11790:91::-;11826:7;11866:8;11859:5;11855:20;11844:31;;11790:91;;;:::o;11887:115::-;11972:23;11989:5;11972:23;:::i;:::-;11967:3;11960:36;11887:115;;:::o;12008:218::-;12099:4;12137:2;12126:9;12122:18;12114:26;;12150:69;12216:1;12205:9;12201:17;12192:6;12150:69;:::i;:::-;12008:218;;;;:::o;12232:118::-;12319:24;12337:5;12319:24;:::i;:::-;12314:3;12307:37;12232:118;;:::o;12356:222::-;12449:4;12487:2;12476:9;12472:18;12464:26;;12500:71;12568:1;12557:9;12553:17;12544:6;12500:71;:::i;:::-;12356:222;;;;:::o;12584:894::-;12702:6;12710;12759:2;12747:9;12738:7;12734:23;12730:32;12727:119;;;12765:79;;:::i;:::-;12727:119;12913:1;12902:9;12898:17;12885:31;12943:18;12935:6;12932:30;12929:117;;;12965:79;;:::i;:::-;12929:117;13070:78;13140:7;13131:6;13120:9;13116:22;13070:78;:::i;:::-;13060:88;;12856:302;13225:2;13214:9;13210:18;13197:32;13256:18;13248:6;13245:30;13242:117;;;13278:79;;:::i;:::-;13242:117;13383:78;13453:7;13444:6;13433:9;13429:22;13383:78;:::i;:::-;13373:88;;13168:303;12584:894;;;;;:::o;13484:311::-;13561:4;13651:18;13643:6;13640:30;13637:56;;;13673:18;;:::i;:::-;13637:56;13723:4;13715:6;13711:17;13703:25;;13783:4;13777;13773:15;13765:23;;13484:311;;;:::o;13818:710::-;13914:5;13939:81;13955:64;14012:6;13955:64;:::i;:::-;13939:81;:::i;:::-;13930:90;;14040:5;14069:6;14062:5;14055:21;14103:4;14096:5;14092:16;14085:23;;14156:4;14148:6;14144:17;14136:6;14132:30;14185:3;14177:6;14174:15;14171:122;;;14204:79;;:::i;:::-;14171:122;14319:6;14302:220;14336:6;14331:3;14328:15;14302:220;;;14411:3;14440:37;14473:3;14461:10;14440:37;:::i;:::-;14435:3;14428:50;14507:4;14502:3;14498:14;14491:21;;14378:144;14362:4;14357:3;14353:14;14346:21;;14302:220;;;14306:21;13920:608;;13818:710;;;;;:::o;14551:370::-;14622:5;14671:3;14664:4;14656:6;14652:17;14648:27;14638:122;;14679:79;;:::i;:::-;14638:122;14796:6;14783:20;14821:94;14911:3;14903:6;14896:4;14888:6;14884:17;14821:94;:::i;:::-;14812:103;;14628:293;14551:370;;;;:::o;14927:894::-;15045:6;15053;15102:2;15090:9;15081:7;15077:23;15073:32;15070:119;;;15108:79;;:::i;:::-;15070:119;15256:1;15245:9;15241:17;15228:31;15286:18;15278:6;15275:30;15272:117;;;15308:79;;:::i;:::-;15272:117;15413:78;15483:7;15474:6;15463:9;15459:22;15413:78;:::i;:::-;15403:88;;15199:302;15568:2;15557:9;15553:18;15540:32;15599:18;15591:6;15588:30;15585:117;;;15621:79;;:::i;:::-;15585:117;15726:78;15796:7;15787:6;15776:9;15772:22;15726:78;:::i;:::-;15716:88;;15511:303;14927:894;;;;;:::o;15827:114::-;15894:6;15928:5;15922:12;15912:22;;15827:114;;;:::o;15947:184::-;16046:11;16080:6;16075:3;16068:19;16120:4;16115:3;16111:14;16096:29;;15947:184;;;;:::o;16137:132::-;16204:4;16227:3;16219:11;;16257:4;16252:3;16248:14;16240:22;;16137:132;;;:::o;16275:108::-;16352:24;16370:5;16352:24;:::i;:::-;16347:3;16340:37;16275:108;;:::o;16389:179::-;16458:10;16479:46;16521:3;16513:6;16479:46;:::i;:::-;16557:4;16552:3;16548:14;16534:28;;16389:179;;;;:::o;16574:113::-;16644:4;16676;16671:3;16667:14;16659:22;;16574:113;;;:::o;16723:732::-;16842:3;16871:54;16919:5;16871:54;:::i;:::-;16941:86;17020:6;17015:3;16941:86;:::i;:::-;16934:93;;17051:56;17101:5;17051:56;:::i;:::-;17130:7;17161:1;17146:284;17171:6;17168:1;17165:13;17146:284;;;17247:6;17241:13;17274:63;17333:3;17318:13;17274:63;:::i;:::-;17267:70;;17360:60;17413:6;17360:60;:::i;:::-;17350:70;;17206:224;17193:1;17190;17186:9;17181:14;;17146:284;;;17150:14;17446:3;17439:10;;16847:608;;;16723:732;;;;:::o;17461:373::-;17604:4;17642:2;17631:9;17627:18;17619:26;;17691:9;17685:4;17681:20;17677:1;17666:9;17662:17;17655:47;17719:108;17822:4;17813:6;17719:108;:::i;:::-;17711:116;;17461:373;;;;:::o;17840:308::-;17902:4;17992:18;17984:6;17981:30;17978:56;;;18014:18;;:::i;:::-;17978:56;18052:29;18074:6;18052:29;:::i;:::-;18044:37;;18136:4;18130;18126:15;18118:23;;17840:308;;;:::o;18154:412::-;18232:5;18257:66;18273:49;18315:6;18273:49;:::i;:::-;18257:66;:::i;:::-;18248:75;;18346:6;18339:5;18332:21;18384:4;18377:5;18373:16;18422:3;18413:6;18408:3;18404:16;18401:25;18398:112;;;18429:79;;:::i;:::-;18398:112;18519:41;18553:6;18548:3;18543;18519:41;:::i;:::-;18238:328;18154:412;;;;;:::o;18586:340::-;18642:5;18691:3;18684:4;18676:6;18672:17;18668:27;18658:122;;18699:79;;:::i;:::-;18658:122;18816:6;18803:20;18841:79;18916:3;18908:6;18901:4;18893:6;18889:17;18841:79;:::i;:::-;18832:88;;18648:278;18586:340;;;;:::o;18932:509::-;19001:6;19050:2;19038:9;19029:7;19025:23;19021:32;19018:119;;;19056:79;;:::i;:::-;19018:119;19204:1;19193:9;19189:17;19176:31;19234:18;19226:6;19223:30;19220:117;;;19256:79;;:::i;:::-;19220:117;19361:63;19416:7;19407:6;19396:9;19392:22;19361:63;:::i;:::-;19351:73;;19147:287;18932:509;;;;:::o;19447:1039::-;19574:6;19582;19590;19639:2;19627:9;19618:7;19614:23;19610:32;19607:119;;;19645:79;;:::i;:::-;19607:119;19765:1;19790:53;19835:7;19826:6;19815:9;19811:22;19790:53;:::i;:::-;19780:63;;19736:117;19920:2;19909:9;19905:18;19892:32;19951:18;19943:6;19940:30;19937:117;;;19973:79;;:::i;:::-;19937:117;20078:78;20148:7;20139:6;20128:9;20124:22;20078:78;:::i;:::-;20068:88;;19863:303;20233:2;20222:9;20218:18;20205:32;20264:18;20256:6;20253:30;20250:117;;;20286:79;;:::i;:::-;20250:117;20391:78;20461:7;20452:6;20441:9;20437:22;20391:78;:::i;:::-;20381:88;;20176:303;19447:1039;;;;;:::o;20492:104::-;20537:7;20566:24;20584:5;20566:24;:::i;:::-;20555:35;;20492:104;;;:::o;20602:142::-;20705:32;20731:5;20705:32;:::i;:::-;20700:3;20693:45;20602:142;;:::o;20750:254::-;20859:4;20897:2;20886:9;20882:18;20874:26;;20910:87;20994:1;20983:9;20979:17;20970:6;20910:87;:::i;:::-;20750:254;;;;:::o;21010:120::-;21082:23;21099:5;21082:23;:::i;:::-;21075:5;21072:34;21062:62;;21120:1;21117;21110:12;21062:62;21010:120;:::o;21136:137::-;21181:5;21219:6;21206:20;21197:29;;21235:32;21261:5;21235:32;:::i;:::-;21136:137;;;;:::o;21279:327::-;21337:6;21386:2;21374:9;21365:7;21361:23;21357:32;21354:119;;;21392:79;;:::i;:::-;21354:119;21512:1;21537:52;21581:7;21572:6;21561:9;21557:22;21537:52;:::i;:::-;21527:62;;21483:116;21279:327;;;;:::o;21612:329::-;21671:6;21720:2;21708:9;21699:7;21695:23;21691:32;21688:119;;;21726:79;;:::i;:::-;21688:119;21846:1;21871:53;21916:7;21907:6;21896:9;21892:22;21871:53;:::i;:::-;21861:63;;21817:117;21612:329;;;;:::o;21947:138::-;22028:32;22054:5;22028:32;:::i;:::-;22021:5;22018:43;22008:71;;22075:1;22072;22065:12;22008:71;21947:138;:::o;22091:155::-;22145:5;22183:6;22170:20;22161:29;;22199:41;22234:5;22199:41;:::i;:::-;22091:155;;;;:::o;22252:670::-;22338:6;22346;22395:2;22383:9;22374:7;22370:23;22366:32;22363:119;;;22401:79;;:::i;:::-;22363:119;22549:1;22538:9;22534:17;22521:31;22579:18;22571:6;22568:30;22565:117;;;22601:79;;:::i;:::-;22565:117;22706:63;22761:7;22752:6;22741:9;22737:22;22706:63;:::i;:::-;22696:73;;22492:287;22818:2;22844:61;22897:7;22888:6;22877:9;22873:22;22844:61;:::i;:::-;22834:71;;22789:126;22252:670;;;;;:::o;22928:116::-;22998:21;23013:5;22998:21;:::i;:::-;22991:5;22988:32;22978:60;;23034:1;23031;23024:12;22978:60;22928:116;:::o;23050:133::-;23093:5;23131:6;23118:20;23109:29;;23147:30;23171:5;23147:30;:::i;:::-;23050:133;;;;:::o;23189:468::-;23254:6;23262;23311:2;23299:9;23290:7;23286:23;23282:32;23279:119;;;23317:79;;:::i;:::-;23279:119;23437:1;23462:53;23507:7;23498:6;23487:9;23483:22;23462:53;:::i;:::-;23452:63;;23408:117;23564:2;23590:50;23632:7;23623:6;23612:9;23608:22;23590:50;:::i;:::-;23580:60;;23535:115;23189:468;;;;;:::o;23663:345::-;23730:6;23779:2;23767:9;23758:7;23754:23;23750:32;23747:119;;;23785:79;;:::i;:::-;23747:119;23905:1;23930:61;23983:7;23974:6;23963:9;23959:22;23930:61;:::i;:::-;23920:71;;23876:125;23663:345;;;;:::o;24014:619::-;24091:6;24099;24107;24156:2;24144:9;24135:7;24131:23;24127:32;24124:119;;;24162:79;;:::i;:::-;24124:119;24282:1;24307:53;24352:7;24343:6;24332:9;24328:22;24307:53;:::i;:::-;24297:63;;24253:117;24409:2;24435:53;24480:7;24471:6;24460:9;24456:22;24435:53;:::i;:::-;24425:63;;24380:118;24537:2;24563:53;24608:7;24599:6;24588:9;24584:22;24563:53;:::i;:::-;24553:63;;24508:118;24014:619;;;;;:::o;24639:474::-;24707:6;24715;24764:2;24752:9;24743:7;24739:23;24735:32;24732:119;;;24770:79;;:::i;:::-;24732:119;24890:1;24915:53;24960:7;24951:6;24940:9;24936:22;24915:53;:::i;:::-;24905:63;;24861:117;25017:2;25043:53;25088:7;25079:6;25068:9;25064:22;25043:53;:::i;:::-;25033:63;;24988:118;24639:474;;;;;:::o;25119:1089::-;25223:6;25231;25239;25247;25255;25304:3;25292:9;25283:7;25279:23;25275:33;25272:120;;;25311:79;;:::i;:::-;25272:120;25431:1;25456:53;25501:7;25492:6;25481:9;25477:22;25456:53;:::i;:::-;25446:63;;25402:117;25558:2;25584:53;25629:7;25620:6;25609:9;25605:22;25584:53;:::i;:::-;25574:63;;25529:118;25686:2;25712:53;25757:7;25748:6;25737:9;25733:22;25712:53;:::i;:::-;25702:63;;25657:118;25814:2;25840:53;25885:7;25876:6;25865:9;25861:22;25840:53;:::i;:::-;25830:63;;25785:118;25970:3;25959:9;25955:19;25942:33;26002:18;25994:6;25991:30;25988:117;;;26024:79;;:::i;:::-;25988:117;26129:62;26183:7;26174:6;26163:9;26159:22;26129:62;:::i;:::-;26119:72;;25913:288;25119:1089;;;;;;;;:::o;26214:229::-;26354:34;26350:1;26342:6;26338:14;26331:58;26423:12;26418:2;26410:6;26406:15;26399:37;26214:229;:::o;26449:366::-;26591:3;26612:67;26676:2;26671:3;26612:67;:::i;:::-;26605:74;;26688:93;26777:3;26688:93;:::i;:::-;26806:2;26801:3;26797:12;26790:19;;26449:366;;;:::o;26821:419::-;26987:4;27025:2;27014:9;27010:18;27002:26;;27074:9;27068:4;27064:20;27060:1;27049:9;27045:17;27038:47;27102:131;27228:4;27102:131;:::i;:::-;27094:139;;26821:419;;;:::o;27246:180::-;27294:77;27291:1;27284:88;27391:4;27388:1;27381:15;27415:4;27412:1;27405:15;27432:320;27476:6;27513:1;27507:4;27503:12;27493:22;;27560:1;27554:4;27550:12;27581:18;27571:81;;27637:4;27629:6;27625:17;27615:27;;27571:81;27699:2;27691:6;27688:14;27668:18;27665:38;27662:84;;;27718:18;;:::i;:::-;27662:84;27483:269;27432:320;;;:::o;27758:180::-;27806:77;27803:1;27796:88;27903:4;27900:1;27893:15;27927:4;27924:1;27917:15;27944:634;28165:4;28203:2;28192:9;28188:18;28180:26;;28252:9;28246:4;28242:20;28238:1;28227:9;28223:17;28216:47;28280:108;28383:4;28374:6;28280:108;:::i;:::-;28272:116;;28435:9;28429:4;28425:20;28420:2;28409:9;28405:18;28398:48;28463:108;28566:4;28557:6;28463:108;:::i;:::-;28455:116;;27944:634;;;;;:::o;28584:233::-;28724:34;28720:1;28712:6;28708:14;28701:58;28793:16;28788:2;28780:6;28776:15;28769:41;28584:233;:::o;28823:366::-;28965:3;28986:67;29050:2;29045:3;28986:67;:::i;:::-;28979:74;;29062:93;29151:3;29062:93;:::i;:::-;29180:2;29175:3;29171:12;29164:19;;28823:366;;;:::o;29195:419::-;29361:4;29399:2;29388:9;29384:18;29376:26;;29448:9;29442:4;29438:20;29434:1;29423:9;29419:17;29412:47;29476:131;29602:4;29476:131;:::i;:::-;29468:139;;29195:419;;;:::o;29620:222::-;29760:34;29756:1;29748:6;29744:14;29737:58;29829:5;29824:2;29816:6;29812:15;29805:30;29620:222;:::o;29848:366::-;29990:3;30011:67;30075:2;30070:3;30011:67;:::i;:::-;30004:74;;30087:93;30176:3;30087:93;:::i;:::-;30205:2;30200:3;30196:12;30189:19;;29848:366;;;:::o;30220:419::-;30386:4;30424:2;30413:9;30409:18;30401:26;;30473:9;30467:4;30463:20;30459:1;30448:9;30444:17;30437:47;30501:131;30627:4;30501:131;:::i;:::-;30493:139;;30220:419;;;:::o;30645:143::-;30702:5;30733:6;30727:13;30718:22;;30749:33;30776:5;30749:33;:::i;:::-;30645:143;;;;:::o;30794:351::-;30864:6;30913:2;30901:9;30892:7;30888:23;30884:32;30881:119;;;30919:79;;:::i;:::-;30881:119;31039:1;31064:64;31120:7;31111:6;31100:9;31096:22;31064:64;:::i;:::-;31054:74;;31010:128;30794:351;;;;:::o;31151:744::-;31400:4;31438:2;31427:9;31423:18;31415:26;;31451:71;31519:1;31508:9;31504:17;31495:6;31451:71;:::i;:::-;31569:9;31563:4;31559:20;31554:2;31543:9;31539:18;31532:48;31597:108;31700:4;31691:6;31597:108;:::i;:::-;31589:116;;31752:9;31746:4;31742:20;31737:2;31726:9;31722:18;31715:48;31780:108;31883:4;31874:6;31780:108;:::i;:::-;31772:116;;31151:744;;;;;;:::o;31901:228::-;32041:34;32037:1;32029:6;32025:14;32018:58;32110:11;32105:2;32097:6;32093:15;32086:36;31901:228;:::o;32135:366::-;32277:3;32298:67;32362:2;32357:3;32298:67;:::i;:::-;32291:74;;32374:93;32463:3;32374:93;:::i;:::-;32492:2;32487:3;32483:12;32476:19;;32135:366;;;:::o;32507:419::-;32673:4;32711:2;32700:9;32696:18;32688:26;;32760:9;32754:4;32750:20;32746:1;32735:9;32731:17;32724:47;32788:131;32914:4;32788:131;:::i;:::-;32780:139;;32507:419;;;:::o;32932:180::-;32980:77;32977:1;32970:88;33077:4;33074:1;33067:15;33101:4;33098:1;33091:15;33118:233;33157:3;33180:24;33198:5;33180:24;:::i;:::-;33171:33;;33226:66;33219:5;33216:77;33213:103;;;33296:18;;:::i;:::-;33213:103;33343:1;33336:5;33332:13;33325:20;;33118:233;;;:::o;33357:::-;33497:34;33493:1;33485:6;33481:14;33474:58;33566:16;33561:2;33553:6;33549:15;33542:41;33357:233;:::o;33596:366::-;33738:3;33759:67;33823:2;33818:3;33759:67;:::i;:::-;33752:74;;33835:93;33924:3;33835:93;:::i;:::-;33953:2;33948:3;33944:12;33937:19;;33596:366;;;:::o;33968:419::-;34134:4;34172:2;34161:9;34157:18;34149:26;;34221:9;34215:4;34211:20;34207:1;34196:9;34192:17;34185:47;34249:131;34375:4;34249:131;:::i;:::-;34241:139;;33968:419;;;:::o;34393:230::-;34533:34;34529:1;34521:6;34517:14;34510:58;34602:13;34597:2;34589:6;34585:15;34578:38;34393:230;:::o;34629:366::-;34771:3;34792:67;34856:2;34851:3;34792:67;:::i;:::-;34785:74;;34868:93;34957:3;34868:93;:::i;:::-;34986:2;34981:3;34977:12;34970:19;;34629:366;;;:::o;35001:419::-;35167:4;35205:2;35194:9;35190:18;35182:26;;35254:9;35248:4;35244:20;35240:1;35229:9;35225:17;35218:47;35282:131;35408:4;35282:131;:::i;:::-;35274:139;;35001:419;;;:::o;35426:85::-;35471:7;35500:5;35489:16;;35426:85;;;:::o;35517:86::-;35552:7;35592:4;35585:5;35581:16;35570:27;;35517:86;;;:::o;35609:60::-;35637:3;35658:5;35651:12;;35609:60;;;:::o;35675:154::-;35731:9;35764:59;35780:42;35789:32;35815:5;35789:32;:::i;:::-;35780:42;:::i;:::-;35764:59;:::i;:::-;35751:72;;35675:154;;;:::o;35835:143::-;35928:43;35965:5;35928:43;:::i;:::-;35923:3;35916:56;35835:143;;:::o;35984:234::-;36083:4;36121:2;36110:9;36106:18;36098:26;;36134:77;36208:1;36197:9;36193:17;36184:6;36134:77;:::i;:::-;35984:234;;;;:::o;36224:225::-;36364:34;36360:1;36352:6;36348:14;36341:58;36433:8;36428:2;36420:6;36416:15;36409:33;36224:225;:::o;36455:366::-;36597:3;36618:67;36682:2;36677:3;36618:67;:::i;:::-;36611:74;;36694:93;36783:3;36694:93;:::i;:::-;36812:2;36807:3;36803:12;36796:19;;36455:366;;;:::o;36827:419::-;36993:4;37031:2;37020:9;37016:18;37008:26;;37080:9;37074:4;37070:20;37066:1;37055:9;37051:17;37044:47;37108:131;37234:4;37108:131;:::i;:::-;37100:139;;36827:419;;;:::o;37252:348::-;37292:7;37315:20;37333:1;37315:20;:::i;:::-;37310:25;;37349:20;37367:1;37349:20;:::i;:::-;37344:25;;37537:1;37469:66;37465:74;37462:1;37459:81;37454:1;37447:9;37440:17;37436:105;37433:131;;;37544:18;;:::i;:::-;37433:131;37592:1;37589;37585:9;37574:20;;37252:348;;;;:::o;37606:305::-;37646:3;37665:20;37683:1;37665:20;:::i;:::-;37660:25;;37699:20;37717:1;37699:20;:::i;:::-;37694:25;;37853:1;37785:66;37781:74;37778:1;37775:81;37772:107;;;37859:18;;:::i;:::-;37772:107;37903:1;37900;37896:9;37889:16;;37606:305;;;;:::o;37917:182::-;38057:34;38053:1;38045:6;38041:14;38034:58;37917:182;:::o;38105:366::-;38247:3;38268:67;38332:2;38327:3;38268:67;:::i;:::-;38261:74;;38344:93;38433:3;38344:93;:::i;:::-;38462:2;38457:3;38453:12;38446:19;;38105:366;;;:::o;38477:419::-;38643:4;38681:2;38670:9;38666:18;38658:26;;38730:9;38724:4;38720:20;38716:1;38705:9;38701:17;38694:47;38758:131;38884:4;38758:131;:::i;:::-;38750:139;;38477:419;;;:::o;38902:227::-;39042:34;39038:1;39030:6;39026:14;39019:58;39111:10;39106:2;39098:6;39094:15;39087:35;38902:227;:::o;39135:366::-;39277:3;39298:67;39362:2;39357:3;39298:67;:::i;:::-;39291:74;;39374:93;39463:3;39374:93;:::i;:::-;39492:2;39487:3;39483:12;39476:19;;39135:366;;;:::o;39507:419::-;39673:4;39711:2;39700:9;39696:18;39688:26;;39760:9;39754:4;39750:20;39746:1;39735:9;39731:17;39724:47;39788:131;39914:4;39788:131;:::i;:::-;39780:139;;39507:419;;;:::o;39932:224::-;40072:34;40068:1;40060:6;40056:14;40049:58;40141:7;40136:2;40128:6;40124:15;40117:32;39932:224;:::o;40162:366::-;40304:3;40325:67;40389:2;40384:3;40325:67;:::i;:::-;40318:74;;40401:93;40490:3;40401:93;:::i;:::-;40519:2;40514:3;40510:12;40503:19;;40162:366;;;:::o;40534:419::-;40700:4;40738:2;40727:9;40723:18;40715:26;;40787:9;40781:4;40777:20;40773:1;40762:9;40758:17;40751:47;40815:131;40941:4;40815:131;:::i;:::-;40807:139;;40534:419;;;:::o;40959:229::-;41099:34;41095:1;41087:6;41083:14;41076:58;41168:12;41163:2;41155:6;41151:15;41144:37;40959:229;:::o;41194:366::-;41336:3;41357:67;41421:2;41416:3;41357:67;:::i;:::-;41350:74;;41433:93;41522:3;41433:93;:::i;:::-;41551:2;41546:3;41542:12;41535:19;;41194:366;;;:::o;41566:419::-;41732:4;41770:2;41759:9;41755:18;41747:26;;41819:9;41813:4;41809:20;41805:1;41794:9;41790:17;41783:47;41847:131;41973:4;41847:131;:::i;:::-;41839:139;;41566:419;;;:::o;41991:228::-;42131:34;42127:1;42119:6;42115:14;42108:58;42200:11;42195:2;42187:6;42183:15;42176:36;41991:228;:::o;42225:366::-;42367:3;42388:67;42452:2;42447:3;42388:67;:::i;:::-;42381:74;;42464:93;42553:3;42464:93;:::i;:::-;42582:2;42577:3;42573:12;42566:19;;42225:366;;;:::o;42597:419::-;42763:4;42801:2;42790:9;42786:18;42778:26;;42850:9;42844:4;42840:20;42836:1;42825:9;42821:17;42814:47;42878:131;43004:4;42878:131;:::i;:::-;42870:139;;42597:419;;;:::o;43022:158::-;43080:9;43113:61;43131:42;43140:32;43166:5;43140:32;:::i;:::-;43131:42;:::i;:::-;43113:61;:::i;:::-;43100:74;;43022:158;;;:::o;43186:147::-;43281:45;43320:5;43281:45;:::i;:::-;43276:3;43269:58;43186:147;;:::o;43339:348::-;43468:4;43506:2;43495:9;43491:18;43483:26;;43519:71;43587:1;43576:9;43572:17;43563:6;43519:71;:::i;:::-;43600:80;43676:2;43665:9;43661:18;43652:6;43600:80;:::i;:::-;43339:348;;;;;:::o;43693:143::-;43750:5;43781:6;43775:13;43766:22;;43797:33;43824:5;43797:33;:::i;:::-;43693:143;;;;:::o;43842:351::-;43912:6;43961:2;43949:9;43940:7;43936:23;43932:32;43929:119;;;43967:79;;:::i;:::-;43929:119;44087:1;44112:64;44168:7;44159:6;44148:9;44144:22;44112:64;:::i;:::-;44102:74;;44058:128;43842:351;;;;:::o;44199:180::-;44247:77;44244:1;44237:88;44344:4;44341:1;44334:15;44368:4;44365:1;44358:15;44385:185;44425:1;44442:20;44460:1;44442:20;:::i;:::-;44437:25;;44476:20;44494:1;44476:20;:::i;:::-;44471:25;;44515:1;44505:35;;44520:18;;:::i;:::-;44505:35;44562:1;44559;44555:9;44550:14;;44385:185;;;;:::o;44576:332::-;44697:4;44735:2;44724:9;44720:18;44712:26;;44748:71;44816:1;44805:9;44801:17;44792:6;44748:71;:::i;:::-;44829:72;44897:2;44886:9;44882:18;44873:6;44829:72;:::i;:::-;44576:332;;;;;:::o;44914:220::-;45054:34;45050:1;45042:6;45038:14;45031:58;45123:3;45118:2;45110:6;45106:15;45099:28;44914:220;:::o;45140:366::-;45282:3;45303:67;45367:2;45362:3;45303:67;:::i;:::-;45296:74;;45379:93;45468:3;45379:93;:::i;:::-;45497:2;45492:3;45488:12;45481:19;;45140:366;;;:::o;45512:419::-;45678:4;45716:2;45705:9;45701:18;45693:26;;45765:9;45759:4;45755:20;45751:1;45740:9;45736:17;45729:47;45793:131;45919:4;45793:131;:::i;:::-;45785:139;;45512:419;;;:::o;45937:660::-;46140:4;46178:3;46167:9;46163:19;46155:27;;46192:71;46260:1;46249:9;46245:17;46236:6;46192:71;:::i;:::-;46273:72;46341:2;46330:9;46326:18;46317:6;46273:72;:::i;:::-;46355;46423:2;46412:9;46408:18;46399:6;46355:72;:::i;:::-;46437;46505:2;46494:9;46490:18;46481:6;46437:72;:::i;:::-;46519:71;46585:3;46574:9;46570:19;46561:6;46519:71;:::i;:::-;45937:660;;;;;;;;:::o;46603:165::-;46743:17;46739:1;46731:6;46727:14;46720:41;46603:165;:::o;46774:366::-;46916:3;46937:67;47001:2;46996:3;46937:67;:::i;:::-;46930:74;;47013:93;47102:3;47013:93;:::i;:::-;47131:2;47126:3;47122:12;47115:19;;46774:366;;;:::o;47146:419::-;47312:4;47350:2;47339:9;47335:18;47327:26;;47399:9;47393:4;47389:20;47385:1;47374:9;47370:17;47363:47;47427:131;47553:4;47427:131;:::i;:::-;47419:139;;47146:419;;;:::o;47571:98::-;47622:6;47656:5;47650:12;47640:22;;47571:98;;;:::o;47675:168::-;47758:11;47792:6;47787:3;47780:19;47832:4;47827:3;47823:14;47808:29;;47675:168;;;;:::o;47849:360::-;47935:3;47963:38;47995:5;47963:38;:::i;:::-;48017:70;48080:6;48075:3;48017:70;:::i;:::-;48010:77;;48096:52;48141:6;48136:3;48129:4;48122:5;48118:16;48096:52;:::i;:::-;48173:29;48195:6;48173:29;:::i;:::-;48168:3;48164:39;48157:46;;47939:270;47849:360;;;;:::o;48215:751::-;48438:4;48476:3;48465:9;48461:19;48453:27;;48490:71;48558:1;48547:9;48543:17;48534:6;48490:71;:::i;:::-;48571:72;48639:2;48628:9;48624:18;48615:6;48571:72;:::i;:::-;48653;48721:2;48710:9;48706:18;48697:6;48653:72;:::i;:::-;48735;48803:2;48792:9;48788:18;48779:6;48735:72;:::i;:::-;48855:9;48849:4;48845:20;48839:3;48828:9;48824:19;48817:49;48883:76;48954:4;48945:6;48883:76;:::i;:::-;48875:84;;48215:751;;;;;;;;:::o;48972:141::-;49028:5;49059:6;49053:13;49044:22;;49075:32;49101:5;49075:32;:::i;:::-;48972:141;;;;:::o;49119:349::-;49188:6;49237:2;49225:9;49216:7;49212:23;49208:32;49205:119;;;49243:79;;:::i;:::-;49205:119;49363:1;49388:63;49443:7;49434:6;49423:9;49419:22;49388:63;:::i;:::-;49378:73;;49334:127;49119:349;;;;:::o;49474:106::-;49518:8;49567:5;49562:3;49558:15;49537:36;;49474:106;;;:::o;49586:183::-;49621:3;49659:1;49641:16;49638:23;49635:128;;;49697:1;49694;49691;49676:23;49719:34;49750:1;49744:8;49719:34;:::i;:::-;49712:41;;49635:128;49586:183;:::o;49775:711::-;49814:3;49852:4;49834:16;49831:26;49828:39;;;49860:5;;49828:39;49889:20;;:::i;:::-;49964:1;49946:16;49942:24;49939:1;49933:4;49918:49;49997:4;49991:11;50096:16;50089:4;50081:6;50077:17;50074:39;50041:18;50033:6;50030:30;50014:113;50011:146;;;50142:5;;;;50011:146;50188:6;50182:4;50178:17;50224:3;50218:10;50251:18;50243:6;50240:30;50237:43;;;50273:5;;;;;;50237:43;50321:6;50314:4;50309:3;50305:14;50301:27;50380:1;50362:16;50358:24;50352:4;50348:35;50343:3;50340:44;50337:57;;;50387:5;;;;;;;50337:57;50404;50452:6;50446:4;50442:17;50434:6;50430:30;50424:4;50404:57;:::i;:::-;50477:3;50470:10;;49818:668;;;;;49775:711;;:::o;50492:239::-;50632:34;50628:1;50620:6;50616:14;50609:58;50701:22;50696:2;50688:6;50684:15;50677:47;50492:239;:::o;50737:366::-;50879:3;50900:67;50964:2;50959:3;50900:67;:::i;:::-;50893:74;;50976:93;51065:3;50976:93;:::i;:::-;51094:2;51089:3;51085:12;51078:19;;50737:366;;;:::o;51109:419::-;51275:4;51313:2;51302:9;51298:18;51290:26;;51362:9;51356:4;51352:20;51348:1;51337:9;51333:17;51326:47;51390:131;51516:4;51390:131;:::i;:::-;51382:139;;51109:419;;;:::o;51534:227::-;51674:34;51670:1;51662:6;51658:14;51651:58;51743:10;51738:2;51730:6;51726:15;51719:35;51534:227;:::o;51767:366::-;51909:3;51930:67;51994:2;51989:3;51930:67;:::i;:::-;51923:74;;52006:93;52095:3;52006:93;:::i;:::-;52124:2;52119:3;52115:12;52108:19;;51767:366;;;:::o;52139:419::-;52305:4;52343:2;52332:9;52328:18;52320:26;;52392:9;52386:4;52382:20;52378:1;52367:9;52363:17;52356:47;52420:131;52546:4;52420:131;:::i;:::-;52412:139;;52139:419;;;:::o
Swarm Source
ipfs://b81eea17938f807f657b56294700816e336a20fcc65613b42441faba73b919cf
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.