More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 1,448 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Sweep | 67262479 | 49 days ago | IN | 0 POL | 0.03273791 | ||||
Sweep | 65070243 | 104 days ago | IN | 0 POL | 0.03572655 | ||||
Sweep | 64590005 | 116 days ago | IN | 0 POL | 0.16209842 | ||||
Sweep | 64589995 | 116 days ago | IN | 0 POL | 0.15273446 | ||||
Sweep | 64589985 | 116 days ago | IN | 0 POL | 0.15607216 | ||||
Buy Tickets | 64589978 | 116 days ago | IN | 20 POL | 0.04749236 | ||||
Sweep | 64552001 | 117 days ago | IN | 0 POL | 0.0588698 | ||||
Sweep | 64551992 | 117 days ago | IN | 0 POL | 0.06084183 | ||||
Sweep | 64551983 | 117 days ago | IN | 0 POL | 0.06084019 | ||||
Sweep | 64551975 | 117 days ago | IN | 0 POL | 0.06084019 | ||||
Sweep | 64551966 | 117 days ago | IN | 0 POL | 0.06498327 | ||||
Buy Tickets | 64551811 | 117 days ago | IN | 20 POL | 0.02107139 | ||||
Sweep | 57877036 | 284 days ago | IN | 0 POL | 0.03252032 | ||||
Buy Tickets | 57877026 | 284 days ago | IN | 4 POL | 0.00692072 | ||||
Buy Tickets | 57872648 | 284 days ago | IN | 4 POL | 0.01107297 | ||||
Sweep | 57866400 | 284 days ago | IN | 0 POL | 0.03449295 | ||||
Buy Tickets | 57866395 | 284 days ago | IN | 4 POL | 0.01153435 | ||||
Buy Tickets | 57863281 | 284 days ago | IN | 2 POL | 0.00961195 | ||||
Buy Tickets | 57851719 | 285 days ago | IN | 2 POL | 0.0132322 | ||||
Sweep | 57607060 | 291 days ago | IN | 0 POL | 0.03561422 | ||||
Buy Tickets | 57607057 | 291 days ago | IN | 2 POL | 0.0132322 | ||||
Sweep | 57339401 | 298 days ago | IN | 0 POL | 0.0426199 | ||||
Buy Tickets | 57339391 | 298 days ago | IN | 6 POL | 0.00859661 | ||||
Buy Tickets | 57336240 | 298 days ago | IN | 2 POL | 0.0084686 | ||||
Buy Tickets | 57073942 | 305 days ago | IN | 4 POL | 0.01153435 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
67373876 | 46 days ago | Contract Creation | 0 POL | |||
65159165 | 102 days ago | Contract Creation | 0 POL | |||
64600625 | 116 days ago | Contract Creation | 0 POL | |||
64589978 | 116 days ago | 0.5 POL | ||||
64589978 | 116 days ago | 1.5 POL | ||||
64589978 | 116 days ago | 18 POL | ||||
64551811 | 117 days ago | 0.5 POL | ||||
64551811 | 117 days ago | 1.5 POL | ||||
64551811 | 117 days ago | 18 POL | ||||
57879455 | 284 days ago | Contract Creation | 0 POL | |||
57877026 | 284 days ago | 0.1 POL | ||||
57877026 | 284 days ago | 0.3 POL | ||||
57877026 | 284 days ago | 3.6 POL | ||||
57872648 | 284 days ago | 0.1 POL | ||||
57872648 | 284 days ago | 0.3 POL | ||||
57872648 | 284 days ago | 3.6 POL | ||||
57866395 | 284 days ago | 0.1 POL | ||||
57866395 | 284 days ago | 0.3 POL | ||||
57866395 | 284 days ago | 3.6 POL | ||||
57863281 | 284 days ago | 0.05 POL | ||||
57863281 | 284 days ago | 0.15 POL | ||||
57863281 | 284 days ago | 1.8 POL | ||||
57851719 | 285 days ago | 0.05 POL | ||||
57851719 | 285 days ago | 0.15 POL | ||||
57851719 | 285 days ago | 1.8 POL |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
PixelSweeperPlayerPotV3
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; import {IERC721Enumerable} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; import {PixelSweeperPlayerPotV3Base, IRareboardSweeper, BurnableTicket, IERC721} from "./PixelSweeperPlayerPotV3Base.sol"; contract PixelSweeperPlayerPotV3 is PixelSweeperPlayerPotV3Base { address public immutable vault; constructor( address _owner, IRareboardSweeper _sweeper, address _collection, uint256 _ticketPrice, FundConfig memory _fundConfig, bool _ticketsRollOver, string memory _ticketNamePrefix, string memory _ticketSymbolPrefix, address _vault ) PixelSweeperPlayerPotV3Base( _owner, _sweeper, _collection, _ticketPrice, _fundConfig, _ticketsRollOver, _ticketNamePrefix, _ticketSymbolPrefix ) { vault = _vault; } /* -----------------------*/ /* --- User interface --- */ /* -----------------------*/ /** * @notice Buy tickets to enter the current player pot * @param amount amount of tickets to be bought * @param recipient ticket recipient * @param discountIds ids of discounts to check and apply */ function buyTickets( uint256 amount, address recipient, uint256[] calldata discountIds ) external payable { uint256 cost = _buyTickets(amount, recipient, discountIds); require(msg.value >= cost, "Insufficient funds send"); if (msg.value > cost) { Address.sendValue(payable(msg.sender), msg.value - cost); } } /* ------------------------*/ /* --- Owner interface --- */ /* ------------------------*/ function unpause() public virtual override onlyOwner { require(vault == address(0) || IERC721(collection).isApprovedForAll(vault, address(prizeStrategy)), "strategy-not-approved-by-vault"); super.unpause(); } /** * @notice Add additional prize for the next draw, which will be taken out of the vault. * @param prizes amount of prizes to be added */ function addPrizeFromVault(uint256 prizes) external { require(vault != address(0) && msg.sender == vault, "only-vault"); for (uint256 i = 0; i < prizes; ++i) { super._addPrize(0, 0); prizeStrategy.addOnetimeAward(collection); } } /* ---------------------------*/ /* --- Internal interface --- */ /* ---------------------------*/ function _addPrize( uint256 tokenId, uint256 price ) internal virtual override { super._addPrize(tokenId, price); require(address(prizeStrategy) != address(0), "no-prize-strategy"); if (vault != address(0)) { IERC721(collection).safeTransferFrom(address(this), vault, tokenId); } prizeStrategy.addOnetimeAward(collection); } function _beforePrizePoolAward(uint256, uint256) internal virtual override { if (vault == address(0)) return; // since we transfer all prizes on _addPrize, everything in here at this point is missing from both // oneTimeAward and nftsSwept uint256 prizes = IERC721(collection).balanceOf(address(this)); for (uint256 i = 0; i < prizes; ++i) { try IERC721Enumerable(collection).tokenOfOwnerByIndex(address(this), prizes - 1 - i) returns (uint256 tokenId) { _addPrize(tokenId, 0); } catch { // owner has to recover the NFT and donate it manually break; } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; import {ERC165, IERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import {IERC721Enumerable} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; import {Pausable} from "@openzeppelin/contracts/security/Pausable.sol"; import {ITicket} from "../../token/ITicket.sol"; import {IControlledBurnableToken} from "../../token-upgradeable/IControlledBurnableToken.sol"; import {BurnableTicketFactoryInternal} from "../../token-upgradeable/BurnableTicketFactoryInternal.sol"; import {BurnableTicket, ITicket} from "../../token-upgradeable/BurnableTicket.sol"; import {ITokenController} from "../../token/ITokenController.sol"; import {ITicketProvider} from "../../token/ITicketProvider.sol"; import {IDynamicPeriodicPrizeStrategy} from "../../prize-strategy/strategies/IDynamicPeriodicPrizeStrategy.sol"; import {IPeriodicPrizeStrategyListener} from "../../prize-strategy/IPeriodicPrizeStrategyListener.sol"; import {IBeforeAwardListener} from "../../prize-strategy/IBeforeAwardListener.sol"; import {IRareboardSweeper} from "../../../sweeper/v2/IRareboardSweeper.sol"; import {EmergencyWithdrawable} from "../../../sweeper/utils/EmergencyWithdrawable.sol"; import {Discounts} from "./Discounts.sol"; import {PriceConversion} from "./PriceConversion.sol"; abstract contract PixelSweeperPlayerPotV3Base is EmergencyWithdrawable, ReentrancyGuard, ERC165, IERC721Receiver, BurnableTicketFactoryInternal, ITicketProvider, IPeriodicPrizeStrategyListener, IBeforeAwardListener, Pausable, Discounts, PriceConversion { using ERC165Checker for address; using Strings for uint256; struct Round { uint256 roundId; uint256 ticketPrice; BurnableTicket ticket; uint256 ticketsSold; uint256 nftsSweept; } struct FundConfig { address treasury; address partner; uint32 treasurySplit; uint32 partnerSplit; uint32 sweepSplit; } /// @dev Event emitted when executorsOnly is changed event ExecutorsOnlySet(bool executorsOnly); /// @dev Event emitted when a executor is added/removed from the whitelist event ExecutorSet(address indexed user, bool isExecutor); /// @dev Event emitted when the Prize Strategy is set event PrizeStrategySet(address indexed prizeStrategy); /// @dev Event emitted when new ticket price is set event TicketPriceSet(uint256 price); /// @dev Event emitted when fund receivers are changed event FundConfigSet(FundConfig fundConfig); /// @dev Event emitted when tickets are bought event TicketsBought( uint256 indexed rountId, address indexed buyer, address indexed recipient, uint256 amount ); event PrizeAdded(uint256 tokenId, uint256 price, uint256 nftsSwept); address public immutable collection; bool public immutable ticketsRollOver; uint256 private constant FUND_SPLIT_BASE = 10000; /// @dev The Prize Strategy that this Prize Pool is bound to. IDynamicPeriodicPrizeStrategy public prizeStrategy; /// @dev Sweeper used by player pot IRareboardSweeper public immutable sweeper; /// @dev Sweeping funds used to fund sweeps for playerpot address public immutable sweepingFunds; /// @dev current round id uint256 public roundId; /// @dev ticket price for next round uint256 public ticketPrice; /// @dev Record for all past and current rounds mapping(uint256 => Round) public rounds; /// @dev Receiver addresses for ticket sale funds FundConfig public fundConfig; mapping(address => bool) public isExectutor; bool public executorsOnly; /// @dev Prefix for ticket name, /// i.e. "PixelSweeper PlayerPot - Kreepy Kritters - Ticket #" string private ticketNamePrefix; /// @dev Prefix for ticket symbol, /// i.e. "SWPR-P KK #" string private ticketSymbolPrefix; bool private ignoringOnReceive; modifier ignoreOnReceived() { ignoringOnReceive = true; _; ignoringOnReceive = false; } constructor( address _owner, IRareboardSweeper _sweeper, address _collection, uint256 _ticketPrice, FundConfig memory _fundConfig, bool _ticketsRollOver, string memory _ticketNamePrefix, string memory _ticketSymbolPrefix ) { _transferOwnership(_owner); sweeper = _sweeper; collection = _collection; ticketPrice = _ticketPrice; ticketsRollOver = _ticketsRollOver; ticketNamePrefix = _ticketNamePrefix; ticketSymbolPrefix = _ticketSymbolPrefix; sweepingFunds = sweeper.createSweepingFunds(collection, address(this)); require(sweepingFunds != address(0), "Setup failed"); _setFundConfig(_fundConfig); _pause(); _prepareNextRound(); } // ------------------------- // User interface // ------------------------- /// @notice Donate `tokenIds` to the prize pool for this round. function donatePrizes( uint256[] calldata tokenIds ) external ignoreOnReceived { require(address(prizeStrategy) != address(0), "No strategy set"); for (uint256 i = 0; i < tokenIds.length; ++i) { uint256 tokenId = tokenIds[i]; IERC721(collection).transferFrom( msg.sender, address(this), tokenId ); _addPrize(tokenId, 0); } } // ------------------------- // Sweep executor interface // ------------------------- /// @notice Sweep the floor and add to the award function sweep( address _collection, uint256 _tokenId, uint256 _price, bytes calldata _data, uint256 _timestamp, bytes memory _signature ) external ignoreOnReceived { require(_collection == collection, "Only main collection"); require(!executorsOnly || isExectutor[_msgSender()], "Only executors"); sweeper.sweep( _collection, _tokenId, _price, _data, _timestamp, _signature, address(this) ); _addPrize(_tokenId, _price); } // ------------------------- // ITokenController interface // ------------------------- /// @notice hook used by tickets function beforeTokenTransfer( address from, address to, uint256 ) external view override { require(from != to, "Self transfer"); require( from == address(0) || to == address(0), "Tickets non transferable" ); require( address(prizeStrategy) == address(0) || prizeStrategy.awardNotInProgress(), "Award in progress" ); } // ------------------------- // IPeriodicPrizeStrategyListener interface // ------------------------- /// @notice hook to get notified before prize will be awarded function beforePrizePoolAwarded(uint256 randomNumber, uint256 prizePeriodStartAt) external override { require(_msgSender() == address(prizeStrategy), "only prize strategy"); _beforePrizePoolAward(randomNumber, prizePeriodStartAt); } /// @notice hook to get notified once prize was awarded function afterPrizePoolAwarded(uint256, uint256) external override { require(_msgSender() == address(prizeStrategy), "only prize strategy"); _prepareNextRound(); } // ------------------------- // Owner interface // ------------------------- /// @notice Set the receivers and split of ticket sale funds function setFundConfig(FundConfig memory _fundConfig) external onlyOwner { _setFundConfig(_fundConfig); } /// @notice Set to only allow whitelisted executors to sweep function setExecutorsOnly(bool _executorsOnly) external onlyOwner { executorsOnly = _executorsOnly; emit ExecutorsOnlySet(_executorsOnly); } /// @notice Allow/disallow executor to sweep function setExecutor( address executor, bool _isExecutor ) external onlyOwner { isExectutor[executor] = _isExecutor; emit ExecutorSet(executor, _isExecutor); } /// @notice Sets the prize strategy of the prize pool. Only callable by the owner. /// @param _prizeStrategy The new prize strategy function setPrizeStrategy( IDynamicPeriodicPrizeStrategy _prizeStrategy ) external onlyOwner whenPaused { _setPrizeStrategy(_prizeStrategy); } /// @notice Sets the price per ticket. Does not effect current round. Only callable by the owner. /// @param _ticketPrice The new ticket price function setTicketPrice(uint256 _ticketPrice) external onlyOwner { ticketPrice = _ticketPrice; emit TicketPriceSet(_ticketPrice); } /** * @notice Configure the Eth (value token) to usd price feed. * @param feed chainlink price feed */ function setEthUsdPriceFeed(address feed) external onlyOwner { _setEthUsdFeed(feed); } /// @notice Pauses ticket sale /// @dev Callable by owner, pausing the contract is used to complete the setup and for migration purposes. function pause() external onlyOwner { _pause(); } /// @notice Resume normal operations /// @dev Callable by owner function unpause() public virtual onlyOwner { require(address(prizeStrategy) != address(0), "no-prize-startegy"); require( address(prizeStrategy.periodicPrizeStrategyListener()) == address(this), "not-set-as-after-listener" ); require( address(prizeStrategy.beforeAwardListener()) == address(this), "not-set-as-before-listener" ); _unpause(); } /// @notice Add or change a discount config. /// @dev Callable by owner function setDiscount(DiscountConfig memory discount) external onlyOwner { _setDiscount(discount); } /// @notice Remove a discount config. /// @dev Callable by owner function removeDiscount(uint256 id) external onlyOwner { _removeDiscount(id); } // ------------------------- // View interface // ------------------------- /// @notice Get the current ticket balance of user and totalSupply. function currentTicketBalance( address _user ) external view returns (uint256 balance, uint256 totalSupply) { BurnableTicket _ticket = rounds[roundId].ticket; balance = _ticket.balanceOf(_user); totalSupply = _ticket.totalSupply(); } function currentRound() external view returns (Round memory) { return rounds[roundId]; } function ticket() external view override returns (ITicket) { return rounds[roundId].ticket; } function calculateCost( address user, uint256 tickets, uint256[] calldata discountIds ) external view returns ( uint256 cost, uint256[] memory discountedTicketss, uint256[] memory discountFactors ) { return _discountedCost( roundId, user, rounds[roundId].ticketPrice, tickets, discountIds ); } function supportsInterface( bytes4 interfaceId ) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IPeriodicPrizeStrategyListener).interfaceId || interfaceId == type(IBeforeAwardListener).interfaceId || super.supportsInterface(interfaceId); } function onERC721Received( address, address, uint256 tokenId, bytes memory ) public virtual override returns (bytes4) { require(msg.sender == collection, "Only collection"); if (!ignoringOnReceive) { _addPrize(tokenId, 0); } return this.onERC721Received.selector; } // ------------------------- // Internal interface // ------------------------- function _beforePrizePoolAward(uint256, uint256) internal virtual { // check if nft was transfered to this contract without using donate, sweep or safeTransfer uint256 prizes = IERC721(collection).balanceOf(address(this)); if (prizes > rounds[roundId].nftsSweept) { rounds[roundId].nftsSweept = prizes; } } function _buyTickets( uint256 amount, address recipient, uint256[] calldata discountIds ) internal nonReentrant whenNotPaused returns (uint256 cost) { address buyer = _msgSender(); cost = _useDiscounted( roundId, buyer, rounds[roundId].ticketPrice, amount, discountIds ); BurnableTicket ticket_ = rounds[roundId].ticket; ticket_.controllerMint(recipient, amount * 1 ether); emit TicketsBought(roundId, buyer, recipient, amount * 1 ether); _distributeFunds(cost); } function _addPrize(uint256 tokenId, uint256 price) internal virtual { rounds[roundId].nftsSweept += 1; emit PrizeAdded(tokenId, price, rounds[roundId].nftsSweept); } function _setPrizeStrategy( IDynamicPeriodicPrizeStrategy _prizeStrategy ) internal { require( address(_prizeStrategy) != address(0), "prizeStrategy-not-zero" ); require( address(_prizeStrategy).supportsInterface( type(IDynamicPeriodicPrizeStrategy).interfaceId ), "prizeStrategy-invalid" ); if (address(prizeStrategy) != address(0)) { IERC721(collection).setApprovalForAll( address(prizeStrategy), false ); } IERC721(collection).setApprovalForAll(address(_prizeStrategy), true); prizeStrategy = _prizeStrategy; emit PrizeStrategySet(address(_prizeStrategy)); } function _prepareNextRound() internal { BurnableTicket lastTicket = rounds[roundId].ticket; bool rollOverTicket = ticketsRollOver && address(lastTicket) != address(0) && rounds[roundId].nftsSweept == 0; if (!rollOverTicket && address(lastTicket) != address(0)) { rounds[roundId].ticketsSold = lastTicket.totalSupply(); lastTicket.setBurnable(true); } if (!rollOverTicket) { Round storage round = rounds[++roundId]; string memory id = roundId.toString(); string memory name = string( abi.encodePacked(ticketNamePrefix, id) ); string memory symbol = string(abi.encodePacked(ticketSymbolPrefix, id)); BurnableTicket ticket_ = _createTicket( name, symbol ); round.ticket = ticket_; round.roundId = roundId; round.ticketPrice = ticketPrice; } } function _setFundConfig(FundConfig memory _fundConfig) internal { require( _fundConfig.sweepSplit + _fundConfig.treasurySplit + _fundConfig.partnerSplit == FUND_SPLIT_BASE, "Invalid Split" ); require(_fundConfig.treasury != address(0), "Invalid fund address"); require(_fundConfig.partner != address(0), "Invalid fund address"); emit FundConfigSet(_fundConfig); fundConfig = _fundConfig; } function _distributeFunds(uint256 _value) internal { address treasury = fundConfig.treasury; (address partner, uint32 partnerSplit, uint32 sweepSplit) = ( fundConfig.partner, fundConfig.partnerSplit, fundConfig.sweepSplit ); uint256 valueSweep = (_value * uint256(sweepSplit)) / FUND_SPLIT_BASE; uint256 valuePartner = (_value * uint256(partnerSplit)) / FUND_SPLIT_BASE; uint256 valueTreasury = _value - valueSweep - valuePartner; Address.sendValue(payable(sweepingFunds), valueSweep); Address.sendValue(payable(treasury), valueTreasury); Address.sendValue(payable(partner), valuePartner); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @title Interface that allows a user to draw an address using a random number interface ITicket { /// @notice Selects a user using a random number. The random number will be uniformly bounded to the ticket totalSupply. /// @param randomNumber The random number to use to select a user. /// @return The winner function draw(uint256 randomNumber) external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IControlledToken.sol"; /// @title Controlled ERC20 Token /// @notice ERC20 Tokens with a controller for minting & burning interface IControlledBurnableToken is IControlledToken { function setBurnable(bool _burnable) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol"; import {BurnableTicket, ITokenController} from "./BurnableTicket.sol"; /// @title Controlled ERC20 Token Factory /// @notice Minimal proxy pattern for creating new Controlled ERC20 Tokens abstract contract BurnableTicketFactoryInternal is ITokenController { /// @notice Contract template for deploying proxied tokens address private immutable instance; /// @notice Initializes the Factory with an instance of the Controlled ERC20 Token constructor() { instance = address(new BurnableTicket()); } /// @notice Creates a new Controlled ERC20 Token as a proxy of the template instance /// @return A reference to the new proxied Controlled ERC20 Token function _createTicket( string memory name, string memory symbol ) internal returns (BurnableTicket) { BurnableTicket clone = BurnableTicket(Clones.clone(instance)); clone.initialize(name, symbol, this); return clone; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./NonTransferableTicketUpgradeable.sol"; contract BurnableTicket is NonTransferableTicketUpgradeable { bool public burnable; function setBurnable(bool _burnable) external onlyController { burnable = _burnable; } function burnTickets() external { require(burnable, "Not burnable yet"); address from = msg.sender; uint256 balance = balanceOf(from); _burn(from, balance); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @title Interface of hooks for ControlledToken to call back to the controller. interface ITokenController { /// @dev Controller hook to provide notifications & rule validations on token transfers to the controller. /// This includes minting and burning. /// @param from Address of the account sending the tokens (address(0x0) on minting) /// @param to Address of the account receiving the tokens (address(0x0) on burning) /// @param amount Amount of tokens being transferred function beforeTokenTransfer(address from, address to, uint256 amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./ITicket.sol"; interface ITicketProvider { function ticket() external view returns (ITicket); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IPeriodicPrizeStrategy.sol"; interface IDynamicPeriodicPrizeStrategy is IPeriodicPrizeStrategy { function addOnetimeAward(address collection_) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; /* solium-disable security/no-block-members */ interface IPeriodicPrizeStrategyListener is IERC165 { function afterPrizePoolAwarded(uint256 randomNumber, uint256 prizePeriodStartedAt) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; /// @notice The interface for the Periodic Prize Strategy before award listener. This listener will be called immediately before the award is distributed. interface IBeforeAwardListener is IERC165 { /// @notice Called immediately before the award is distributed function beforePrizePoolAwarded(uint256 randomNumber, uint256 prizePeriodStartedAt) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IRareboardSweeper { function sweep( address _collection, uint256 _tokenId, uint256 _price, bytes calldata _data, uint256 _timestamp, bytes calldata _signature, address _to ) external; function createSweepingFunds(address _collection, address _to) external returns (address); function sweepingFunds(address _collection, address _to) external view returns (address); function signatureMaxAge() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/utils/Address.sol"; contract EmergencyWithdrawable is Ownable { using SafeERC20 for IERC20; using Address for address; event EmergencyWithdrawERC721(address indexed owner, address indexed token, uint256[] tokenIds); event EmergencyWithdrawERC20(address indexed owner, address indexed token, uint256 balance); event EmergencyWithdraw(address indexed owner, uint256 amount); /** * @notice Allows the owner to withdraw non-fungible tokens for emergencies * @param _token: NFT address * @param _tokenIds: tokenIds * @dev Callable by owner */ function emergencyWithdraw(address _token, uint256[] memory _tokenIds) external onlyOwner { require(_tokenIds.length != 0, "Cannot recover zero balance"); emit EmergencyWithdrawERC721(msg.sender, _token, _tokenIds); for (uint256 i = 0; i < _tokenIds.length; ++i) { IERC721(_token).transferFrom(address(this), address(msg.sender), _tokenIds[i]); } } /** * @notice Allows the owner to withdraw tokens for emergencies * @param _token: token address * @dev Callable by owner */ function emergencyWithdraw(address _token) external onlyOwner { uint256 balance = IERC20(_token).balanceOf(address(this)); require(balance != 0, "Cannot recover zero balance"); emit EmergencyWithdrawERC20(msg.sender, _token, balance); IERC20(_token).safeTransfer(address(msg.sender), balance); } /** * @notice Allows the owner to withdraw Ether for emergencies * @dev Callable by owner */ function emergencyWithdraw() external onlyOwner { uint256 balance = address(this).balance; require(balance != 0, "Cannot recover zero balance"); emit EmergencyWithdraw(msg.sender, balance); Address.sendValue(payable(msg.sender), balance); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; contract Discounts { using EnumerableSet for EnumerableSet.UintSet; struct DiscountConfig { uint16 id; uint16 discountFactor; uint16 discountedTickets; uint8 collections; address collection1; address collection2; } uint256 internal constant MAX_DISCOUNT_FACTOR = 9000; uint256 internal constant DISCOUNT_FACTOR_BASE = 10000; mapping(address user => mapping(uint256 roundId => mapping(uint256 discountId => uint256 used))) public discountsUsed; mapping(uint256 => DiscountConfig) private _discounts; EnumerableSet.UintSet private _discountIds; event DiscountSet(DiscountConfig); function discounts() external view returns (DiscountConfig[] memory) { uint256 length = _discountIds.length(); DiscountConfig[] memory data = new DiscountConfig[](length); for (uint256 i = 0; i < length; ++i) { data[i] = _discounts[_discountIds.at(i)]; } return data; } function _discountedCost( uint256 roundId, address user, uint256 price, uint256 tickets, uint256[] calldata discountIds ) internal view returns (uint256 cost, uint256[] memory discountedTicketss, uint256[] memory discountFactors) { uint256 length = discountIds.length; discountedTicketss = new uint256[](length); discountFactors = new uint256[](length); for (uint256 i = 0; i < length; ++i) { (uint256 discountedTickets, uint256 discountFactor) = _checkDiscount( roundId, user, discountIds[i] ); discountedTickets = _min(discountedTickets, tickets); discountedTicketss[i] = discountedTickets; discountFactors[i] = discountFactor; tickets -= discountedTickets; cost += (price * discountFactor / DISCOUNT_FACTOR_BASE * discountedTickets); } cost += (price * tickets); } function _useDiscounted( uint256 roundId, address user, uint256 price, uint256 tickets, uint256[] calldata discountIds ) internal returns (uint256 cost) { uint256 length = discountIds.length; for (uint256 i = 0; i < length; ++i) { uint256 discountId = discountIds[i]; (uint256 discountedTickets, uint256 discountFactor) = _checkDiscount( roundId, user, discountId ); discountedTickets = _min(discountedTickets, tickets); discountsUsed[user][roundId][discountId] += discountedTickets; tickets -= discountedTickets; cost += (price * discountFactor / DISCOUNT_FACTOR_BASE * discountedTickets); } cost += (price * tickets); } function _checkDiscount( uint256 roundId, address user, uint256 discountId ) internal view returns (uint256 tickets, uint256 discountFactor) { DiscountConfig memory discount = _discounts[discountId]; ( // uint16 id_, uint16 discountFactor_, uint16 discountedTickets_, uint8 collections_, address collection1_ ) = ( // discount.id, discount.discountFactor, discount.discountedTickets, discount.collections, discount.collection1 ); uint256 balance = IERC721(collection1_).balanceOf(user); if (collections_ == 2) { balance = _min( balance, IERC721(discount.collection2).balanceOf(user) ); } uint256 used = discountsUsed[user][roundId][discountId]; tickets = balance * uint256(discountedTickets_); tickets = used > tickets ? 0 : tickets - used; discountFactor = uint256(discountFactor_); } function _setDiscount(DiscountConfig memory discount) internal { ( uint16 id, uint16 discountFactor, uint16 discountedTickets, uint8 collections, address collection1 ) = ( discount.id, discount.discountFactor, discount.discountedTickets, discount.collections, discount.collection1 ); require( discountFactor >= MAX_DISCOUNT_FACTOR, "Invalid discount factor" ); require(discountedTickets > 0, "Invalid discount tickets"); require(collection1 != address(0), "Invalid collection1"); require( collections == 1 || (collections == 2 && discount.collection2 != address(0)), "Invalid collections" ); uint256 _id = uint256(id); _discountIds.add(_id); _discounts[_id] = discount; emit DiscountSet(discount); } function _removeDiscount(uint256 id) internal { _discountIds.remove(id); delete _discounts[id]; } function _min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; contract PriceConversion { error ZeroAddressPriceOracle(); struct PriceFeed { address feed; uint8 decimals; } event PriceFeedUpdated(address feed, uint8 decimals); uint256 public constant usdPriceDecimals = 8; PriceFeed public ethUsdFeed; function usdFromNative(uint256 value) external view returns (uint256) { return _usdFromNative(value); } function nativeFromUsd(uint256 value) external view returns (uint256) { return _nativeFromUsd(value); } function _setEthUsdFeed(address feed) internal { if (feed == address(0)) revert ZeroAddressPriceOracle(); uint8 decimals = AggregatorV3Interface(feed).decimals(); ethUsdFeed = PriceFeed({feed: feed, decimals: decimals}); emit PriceFeedUpdated(feed, decimals); } function _usdFromNative(uint256 value) internal view returns (uint256) { PriceFeed memory _ethUsdFeed = ethUsdFeed; (address feed, uint8 decimals) = ( _ethUsdFeed.feed, _ethUsdFeed.decimals ); (, int256 price, , , ) = AggregatorV3Interface(feed).latestRoundData(); return _scaled( value * uint256(price), uint256(decimals), usdPriceDecimals ); } function _nativeFromUsd(uint256 value) internal view returns (uint256) { PriceFeed memory _ethUsdFeed = ethUsdFeed; (address feed, uint8 decimals) = ( _ethUsdFeed.feed, _ethUsdFeed.decimals ); (, int256 price, , , ) = AggregatorV3Interface(feed).latestRoundData(); return _scaled( value / uint256(price), usdPriceDecimals, uint256(decimals) ); } function _scaled( uint256 value, uint256 fromDecimals, uint256 toDecimals ) private pure returns (uint256) { return fromDecimals == toDecimals ? value : ( fromDecimals > toDecimals ? value / (10 ** uint256(fromDecimals - toDecimals)) : value * (10 ** uint256(toDecimals - fromDecimals)) ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import "../token/ITokenController.sol"; /// @title Controlled ERC20 Token /// @notice ERC20 Tokens with a controller for minting & burning interface IControlledToken is IERC20Upgradeable { /// @notice Interface to the contract responsible for controlling mint/burn function controller() external view returns (ITokenController); /// @notice Allows the controller to mint tokens for a user account /// @dev May be overridden to provide more granular control over minting /// @param _user Address of the receiver of the minted tokens /// @param _amount Amount of tokens to mint function controllerMint(address _user, uint256 _amount) external; /// @notice Allows the controller to burn tokens from a user account /// @dev May be overridden to provide more granular control over burning /// @param _user Address of the holder account to burn tokens from /// @param _amount Amount of tokens to burn function controllerBurn(address _user, uint256 _amount) external; /// @notice Allows an operator via the controller to burn tokens on behalf of a user account /// @dev May be overridden to provide more granular control over operator-burning /// @param _operator Address of the operator performing the burn action via the controller contract /// @param _user Address of the holder account to burn tokens from /// @param _amount Amount of tokens to burn function controllerBurnFrom(address _operator, address _user, uint256 _amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./Ticket.sol"; contract NonTransferableTicketUpgradeable is Ticket { function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual override { super._beforeTokenTransfer(from, to, amount); require(from == address(0) || to == address(0), "Ticke not transferable"); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../external/SortitionSumTreeFactory.sol"; import "../external/libs/UniformRandomNumber.sol"; import "./ControlledToken.sol"; import "../token/ITicket.sol"; contract Ticket is ControlledToken, ITicket { using SortitionSumTreeFactory for SortitionSumTreeFactory.SortitionSumTrees; bytes32 private constant TREE_KEY = keccak256("PixelSweeper/Ticket"); uint256 private constant MAX_TREE_LEAVES = 5; // Ticket-weighted odds SortitionSumTreeFactory.SortitionSumTrees internal sortitionSumTrees; constructor() { _disableInitializers(); } /// @notice Initializes the Controlled Token with Token Details and the Controller /// @param _name The name of the Token /// @param _symbol The symbol for the Token /// @param _controller Address of the Controller contract for minting & burning function initialize( string memory _name, string memory _symbol, ITokenController _controller ) public virtual override initializer { __ControlledToken__init(_name, _symbol, _controller); sortitionSumTrees.createTree(TREE_KEY, MAX_TREE_LEAVES); } /// @notice Returns the user's chance of winning. function chanceOf(address user) external view returns (uint256) { return sortitionSumTrees.stakeOf( TREE_KEY, bytes32(uint256(uint160(user))) ); } /// @notice Selects a user using a random number. The random number will be uniformly bounded to the ticket totalSupply. /// @param randomNumber The random number to use to select a user. /// @return The winner function draw( uint256 randomNumber ) external view override returns (address) { uint256 bound = totalSupply(); address selected; if (bound == 0) { selected = address(0); } else { uint256 token = UniformRandomNumber.uniform(randomNumber, bound); selected = address( uint160(uint256(sortitionSumTrees.draw(TREE_KEY, token))) ); } return selected; } /// @dev Controller hook to provide notifications & rule validations on token transfers to the controller. /// This includes minting and burning. /// May be overridden to provide more granular control over operator-burning /// @param from Address of the account sending the tokens (address(0x0) on minting) /// @param to Address of the account receiving the tokens (address(0x0) on burning) /// @param amount Amount of tokens being transferred function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual override { super._beforeTokenTransfer(from, to, amount); // optimize: ignore transfers to self if (from == to) { return; } if (from != address(0)) { uint256 fromBalance = balanceOf(from) - amount; sortitionSumTrees.set( TREE_KEY, fromBalance, bytes32(uint256(uint160(from))) ); } if (to != address(0)) { uint256 toBalance = balanceOf(to) + amount; sortitionSumTrees.set( TREE_KEY, toBalance, bytes32(uint256(uint160(to))) ); } } }
// SPDX-License-Identifier: MIT /** * @reviewers: [@clesaege, @unknownunknown1, @ferittuncer] * @auditors: [] * @bounties: [<14 days 10 ETH max payout>] * @deployments: [] */ pragma solidity ^0.8.0; /** * @title SortitionSumTreeFactory * @author Enrique Piqueras - <[email protected]> * @dev A factory of trees that keep track of staked values for sortition. */ library SortitionSumTreeFactory { /* Structs */ struct SortitionSumTree { uint K; // The maximum number of childs per node. // We use this to keep track of vacant positions in the tree after removing a leaf. This is for keeping the tree as balanced as possible without spending gas on moving nodes around. uint[] stack; uint[] nodes; // Two-way mapping of IDs to node indexes. Note that node index 0 is reserved for the root node, and means the ID does not have a node. mapping(bytes32 => uint) IDsToNodeIndexes; mapping(uint => bytes32) nodeIndexesToIDs; } /* Storage */ struct SortitionSumTrees { mapping(bytes32 => SortitionSumTree) sortitionSumTrees; } /* internal */ /** * @dev Create a sortition sum tree at the specified key. * @param _key The key of the new tree. * @param _K The number of children each node in the tree should have. */ function createTree(SortitionSumTrees storage self, bytes32 _key, uint _K) internal { SortitionSumTree storage tree = self.sortitionSumTrees[_key]; require(tree.K == 0, "Tree already exists."); require(_K > 1, "K must be greater than one."); tree.K = _K; tree.stack = new uint[](0); tree.nodes = new uint[](0); tree.nodes.push(0); } /** * @dev Set a value of a tree. * @param _key The key of the tree. * @param _value The new value. * @param _ID The ID of the value. * `O(log_k(n))` where * `k` is the maximum number of childs per node in the tree, * and `n` is the maximum number of nodes ever appended. */ function set(SortitionSumTrees storage self, bytes32 _key, uint _value, bytes32 _ID) internal { SortitionSumTree storage tree = self.sortitionSumTrees[_key]; uint treeIndex = tree.IDsToNodeIndexes[_ID]; if (treeIndex == 0) { // No existing node. if (_value != 0) { // Non zero value. // Append. // Add node. if (tree.stack.length == 0) { // No vacant spots. // Get the index and append the value. treeIndex = tree.nodes.length; tree.nodes.push(_value); // Potentially append a new node and make the parent a sum node. if (treeIndex != 1 && (treeIndex - 1) % tree.K == 0) { // Is first child. uint parentIndex = treeIndex / tree.K; bytes32 parentID = tree.nodeIndexesToIDs[parentIndex]; uint newIndex = treeIndex + 1; tree.nodes.push(tree.nodes[parentIndex]); delete tree.nodeIndexesToIDs[parentIndex]; tree.IDsToNodeIndexes[parentID] = newIndex; tree.nodeIndexesToIDs[newIndex] = parentID; } } else { // Some vacant spot. // Pop the stack and append the value. treeIndex = tree.stack[tree.stack.length - 1]; tree.stack.pop(); tree.nodes[treeIndex] = _value; } // Add label. tree.IDsToNodeIndexes[_ID] = treeIndex; tree.nodeIndexesToIDs[treeIndex] = _ID; updateParents(self, _key, treeIndex, true, _value); } } else { // Existing node. if (_value == 0) { // Zero value. // Remove. // Remember value and set to 0. uint value = tree.nodes[treeIndex]; tree.nodes[treeIndex] = 0; // Push to stack. tree.stack.push(treeIndex); // Clear label. delete tree.IDsToNodeIndexes[_ID]; delete tree.nodeIndexesToIDs[treeIndex]; updateParents(self, _key, treeIndex, false, value); } else if (_value != tree.nodes[treeIndex]) { // New, non zero value. // Set. bool plusOrMinus = tree.nodes[treeIndex] <= _value; uint plusOrMinusValue = plusOrMinus ? _value - tree.nodes[treeIndex] : tree.nodes[treeIndex] - _value; tree.nodes[treeIndex] = _value; updateParents(self, _key, treeIndex, plusOrMinus, plusOrMinusValue); } } } /* internal Views */ /** * @dev Query the leaves of a tree. Note that if `startIndex == 0`, the tree is empty and the root node will be returned. * @param _key The key of the tree to get the leaves from. * @param _cursor The pagination cursor. * @param _count The number of items to return. * @return startIndex The index at which leaves start * @return values The values of the returned leaves * @return hasMore Whether there are more for pagination. * `O(n)` where * `n` is the maximum number of nodes ever appended. */ function queryLeafs( SortitionSumTrees storage self, bytes32 _key, uint _cursor, uint _count ) internal view returns(uint startIndex, uint[] memory values, bool hasMore) { SortitionSumTree storage tree = self.sortitionSumTrees[_key]; // Find the start index. for (uint i = 0; i < tree.nodes.length; i++) { if ((tree.K * i) + 1 >= tree.nodes.length) { startIndex = i; break; } } // Get the values. uint loopStartIndex = startIndex + _cursor; values = new uint[](loopStartIndex + _count > tree.nodes.length ? tree.nodes.length - loopStartIndex : _count); uint valuesIndex = 0; for (uint j = loopStartIndex; j < tree.nodes.length; j++) { if (valuesIndex < _count) { values[valuesIndex] = tree.nodes[j]; valuesIndex++; } else { hasMore = true; break; } } } /** * @dev Draw an ID from a tree using a number. Note that this function reverts if the sum of all values in the tree is 0. * @param _key The key of the tree. * @param _drawnNumber The drawn number. * @return ID The drawn ID. * `O(k * log_k(n))` where * `k` is the maximum number of childs per node in the tree, * and `n` is the maximum number of nodes ever appended. */ function draw(SortitionSumTrees storage self, bytes32 _key, uint _drawnNumber) internal view returns(bytes32 ID) { SortitionSumTree storage tree = self.sortitionSumTrees[_key]; uint treeIndex = 0; uint currentDrawnNumber = _drawnNumber % tree.nodes[0]; while ((tree.K * treeIndex) + 1 < tree.nodes.length) // While it still has children. for (uint i = 1; i <= tree.K; i++) { // Loop over children. uint nodeIndex = (tree.K * treeIndex) + i; uint nodeValue = tree.nodes[nodeIndex]; if (currentDrawnNumber >= nodeValue) currentDrawnNumber -= nodeValue; // Go to the next child. else { // Pick this child. treeIndex = nodeIndex; break; } } ID = tree.nodeIndexesToIDs[treeIndex]; } /** @dev Gets a specified ID's associated value. * @param _key The key of the tree. * @param _ID The ID of the value. * @return value The associated value. */ function stakeOf(SortitionSumTrees storage self, bytes32 _key, bytes32 _ID) internal view returns(uint value) { SortitionSumTree storage tree = self.sortitionSumTrees[_key]; uint treeIndex = tree.IDsToNodeIndexes[_ID]; if (treeIndex == 0) value = 0; else value = tree.nodes[treeIndex]; } function total(SortitionSumTrees storage self, bytes32 _key) internal view returns (uint) { SortitionSumTree storage tree = self.sortitionSumTrees[_key]; if (tree.nodes.length == 0) { return 0; } else { return tree.nodes[0]; } } /* Private */ /** * @dev Update all the parents of a node. * @param _key The key of the tree to update. * @param _treeIndex The index of the node to start from. * @param _plusOrMinus Wether to add (true) or substract (false). * @param _value The value to add or substract. * `O(log_k(n))` where * `k` is the maximum number of childs per node in the tree, * and `n` is the maximum number of nodes ever appended. */ function updateParents(SortitionSumTrees storage self, bytes32 _key, uint _treeIndex, bool _plusOrMinus, uint _value) private { SortitionSumTree storage tree = self.sortitionSumTrees[_key]; uint parentIndex = _treeIndex; while (parentIndex != 0) { parentIndex = (parentIndex - 1) / tree.K; tree.nodes[parentIndex] = _plusOrMinus ? tree.nodes[parentIndex] + _value : tree.nodes[parentIndex] - _value; } } }
// SPDX-License-Identifier: UNLICENSED /** Copyright 2019 PoolTogether LLC This file is part of PoolTogether. PoolTogether is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation under version 3 of the License. PoolTogether is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with PoolTogether. If not, see <https://www.gnu.org/licenses/>. */ pragma solidity ^0.8.0; /** * @author Brendan Asselstine * @notice A library that uses entropy to select a random number within a bound. Compensates for modulo bias. * @dev Thanks to https://medium.com/hownetworks/dont-waste-cycles-with-modulo-bias-35b6fdafcf94 */ library UniformRandomNumber { /// @notice Select a random number without modulo bias using a random seed and upper bound /// @param _entropy The seed for randomness /// @param _upperBound The upper bound of the desired number /// @return A random number less than the _upperBound function uniform(uint256 _entropy, uint256 _upperBound) internal pure returns (uint256) { require(_upperBound > 0, "UniformRand/min-bound"); uint256 min = (type(uint256).max - _upperBound + 1) % _upperBound; uint256 random = _entropy; while (true) { if (random >= min) { break; } random = uint256(keccak256(abi.encodePacked(random))); } return random % _upperBound; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; import "../token/ITokenController.sol"; import "./IControlledToken.sol"; /// @title Controlled ERC20 Token /// @notice ERC20 Tokens with a controller for minting & burning contract ControlledToken is ERC20Upgradeable, IControlledToken { /// @notice Interface to the contract responsible for controlling mint/burn ITokenController public override controller; constructor() { _disableInitializers(); } /// @notice Initializes the Controlled Token with Token Details and the Controller /// @param _name The name of the Token /// @param _symbol The symbol for the Token /// @param _controller Address of the Controller contract for minting & burning function initialize( string memory _name, string memory _symbol, ITokenController _controller ) public virtual initializer { __ControlledToken__init(_name, _symbol, _controller); } function __ControlledToken__init( string memory _name, string memory _symbol, ITokenController _controller ) internal onlyInitializing { __ERC20_init(_name, _symbol); controller = _controller; } /// @notice Allows the controller to mint tokens for a user account /// @dev May be overridden to provide more granular control over minting /// @param _user Address of the receiver of the minted tokens /// @param _amount Amount of tokens to mint function controllerMint( address _user, uint256 _amount ) external virtual override onlyController { _mint(_user, _amount); } /// @notice Allows the controller to burn tokens from a user account /// @dev May be overridden to provide more granular control over burning /// @param _user Address of the holder account to burn tokens from /// @param _amount Amount of tokens to burn function controllerBurn( address _user, uint256 _amount ) external virtual override onlyController { _burn(_user, _amount); } /// @notice Allows an operator via the controller to burn tokens on behalf of a user account /// @dev May be overridden to provide more granular control over operator-burning /// @param _user Address of the holder account to burn tokens from /// @param _amount Amount of tokens to burn function controllerBurnFrom( address, address _user, uint256 _amount ) external virtual override onlyController { _burn(_user, _amount); } /// @dev Function modifier to ensure that the caller is the controller contract modifier onlyController() { require( _msgSender() == address(controller), "ControlledToken/only-controller" ); _; } /// @dev Controller hook to provide notifications & rule validations on token transfers to the controller. /// This includes minting and burning. /// May be overridden to provide more granular control over operator-burning /// @param from Address of the account sending the tokens (address(0x0) on minting) /// @param to Address of the account receiving the tokens (address(0x0) on burning) /// @param amount Amount of tokens being transferred function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual override { controller.beforeTokenTransfer(from, to, amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import {IPeriodicPrizeStrategyListener} from "./IPeriodicPrizeStrategyListener.sol"; import {IBeforeAwardListener} from "./IBeforeAwardListener.sol"; /// @title An interface that allows a contract to listen to token mint, transfer and burn events. interface IPeriodicPrizeStrategy is IERC165 { function awardNotInProgress() external view returns (bool); function prizePeriodRemainingSeconds() external view returns (uint256); function prizePeriodSeconds() external view returns (uint256); function prizePeriodStartedAt() external view returns (uint256); function prizePeriodEndAt() external view returns (uint256); function periodicPrizeStrategyListener() external view returns (IPeriodicPrizeStrategyListener); function beforeAwardListener() external view returns (IBeforeAwardListener); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library 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 * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts 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.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.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. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling 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: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/ERC165Checker.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Library used to query support of an interface declared via {IERC165}. * * Note that these functions return the actual result of the query: they do not * `revert` if an interface is not supported. It is up to the caller to decide * what to do in these cases. */ library ERC165Checker { // As per the EIP-165 spec, no interface should ever match 0xffffffff bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff; /** * @dev Returns true if `account` supports the {IERC165} interface. */ function supportsERC165(address account) internal view returns (bool) { // Any contract that implements ERC165 must explicitly indicate support of // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid return supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) && !supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID); } /** * @dev Returns true if `account` supports the interface defined by * `interfaceId`. Support for {IERC165} itself is queried automatically. * * See {IERC165-supportsInterface}. */ function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) { // query support of both ERC165 as per the spec and support of _interfaceId return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId); } /** * @dev Returns a boolean array where each value corresponds to the * interfaces passed in and whether they're supported or not. This allows * you to batch check interfaces for a contract where your expectation * is that some interfaces may not be supported. * * See {IERC165-supportsInterface}. * * _Available since v3.4._ */ function getSupportedInterfaces( address account, bytes4[] memory interfaceIds ) internal view returns (bool[] memory) { // an array of booleans corresponding to interfaceIds and whether they're supported or not bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length); // query support of ERC165 itself if (supportsERC165(account)) { // query support of each interface in interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]); } } return interfaceIdsSupported; } /** * @dev Returns true if `account` supports all the interfaces defined in * `interfaceIds`. Support for {IERC165} itself is queried automatically. * * Batch-querying can lead to gas savings by skipping repeated checks for * {IERC165} support. * * See {IERC165-supportsInterface}. */ function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { // query support of ERC165 itself if (!supportsERC165(account)) { return false; } // query support of each interface in interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) { return false; } } // all interfaces supported return true; } /** * @notice Query if a contract implements an interface, does not check ERC165 support * @param account The address of the contract to query for support of an interface * @param interfaceId The interface identifier, as specified in ERC-165 * @return true if the contract at account indicates support of the interface with * identifier interfaceId, false otherwise * @dev Assumes that account contains a contract that supports ERC165, otherwise * the behavior of this method is undefined. This precondition can be checked * with {supportsERC165}. * * Some precompiled contracts will falsely indicate support for a given interface, so caution * should be exercised when using this function. * * Interface identification is specified in ERC-165. */ function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) { // prepare call bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId); // perform static call bool success; uint256 returnSize; uint256 returnValue; assembly { success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20) returnSize := returndatasize() returnValue := mload(0x00) } return success && returnSize >= 0x20 && returnValue > 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.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 ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// 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: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/Clones.sol) pragma solidity ^0.8.0; /** * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for * deploying minimal proxy contracts, also known as "clones". * * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies * > a minimal bytecode implementation that delegates all calls to a known, fixed address. * * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2` * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the * deterministic method. * * _Available since v3.4._ */ library Clones { /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create opcode, which should never revert. */ function clone(address implementation) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes // of the `implementation` address with the bytecode before the address. mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) // Packs the remaining 17 bytes of `implementation` with the bytecode after the address. mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3)) instance := create(0, 0x09, 0x37) } require(instance != address(0), "ERC1167: create failed"); } /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create2 opcode and a `salt` to deterministically deploy * the clone. Using the same `implementation` and `salt` multiple time will revert, since * the clones cannot be deployed twice at the same address. */ function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes // of the `implementation` address with the bytecode before the address. mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) // Packs the remaining 17 bytes of `implementation` with the bytecode after the address. mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3)) instance := create2(0, 0x09, 0x37, salt) } require(instance != address(0), "ERC1167: create2 failed"); } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress( address implementation, bytes32 salt, address deployer ) internal pure returns (address predicted) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(add(ptr, 0x38), deployer) mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff) mstore(add(ptr, 0x14), implementation) mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73) mstore(add(ptr, 0x58), salt) mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37)) predicted := keccak256(add(ptr, 0x43), 0x55) } } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress( address implementation, bytes32 salt ) internal view returns (address predicted) { return predictDeterministicAddress(implementation, salt, address(this)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20Upgradeable.sol"; import "./extensions/IERC20MetadataUpgradeable.sol"; import "../../utils/ContextUpgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing { __ERC20_init_unchained(name_, symbol_); } function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the default value returned by this function, unless * it's overridden. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer(address from, address to, uint256 amount) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. _balances[to] += amount; } emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _balances[account] += amount; } emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[45] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20Upgradeable.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20MetadataUpgradeable is IERC20Upgradeable { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts 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 (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol) pragma solidity ^0.8.0; import "../ERC721.sol"; import "./IERC721Enumerable.sol"; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @dev See {ERC721-_beforeTokenTransfer}. */ function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual override { super._beforeTokenTransfer(from, to, firstTokenId, batchSize); if (batchSize > 1) { // Will only trigger during construction. Batch transferring (minting) is not available afterwards. revert("ERC721Enumerable: consecutive transfers not supported"); } uint256 tokenId = firstTokenId; if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; import "./IERC721.sol"; import "./IERC721Receiver.sol"; import "./extensions/IERC721Metadata.sol"; import "../../utils/Address.sol"; import "../../utils/Context.sol"; import "../../utils/Strings.sol"; import "../../utils/introspection/ERC165.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _ownerOf(tokenId) != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such * that `ownerOf(tokenId)` is `a`. */ // solhint-disable-next-line func-name-mixedcase function __unsafe_increaseBalance(address account, uint256 amount) internal { _balances[account] += amount; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.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 // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ```solidity * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); function getRoundData(uint80 _roundId) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); }
{ "optimizer": { "enabled": true, "runs": 2000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"contract IRareboardSweeper","name":"_sweeper","type":"address"},{"internalType":"address","name":"_collection","type":"address"},{"internalType":"uint256","name":"_ticketPrice","type":"uint256"},{"components":[{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"partner","type":"address"},{"internalType":"uint32","name":"treasurySplit","type":"uint32"},{"internalType":"uint32","name":"partnerSplit","type":"uint32"},{"internalType":"uint32","name":"sweepSplit","type":"uint32"}],"internalType":"struct PixelSweeperPlayerPotV3Base.FundConfig","name":"_fundConfig","type":"tuple"},{"internalType":"bool","name":"_ticketsRollOver","type":"bool"},{"internalType":"string","name":"_ticketNamePrefix","type":"string"},{"internalType":"string","name":"_ticketSymbolPrefix","type":"string"},{"internalType":"address","name":"_vault","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ZeroAddressPriceOracle","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint16","name":"id","type":"uint16"},{"internalType":"uint16","name":"discountFactor","type":"uint16"},{"internalType":"uint16","name":"discountedTickets","type":"uint16"},{"internalType":"uint8","name":"collections","type":"uint8"},{"internalType":"address","name":"collection1","type":"address"},{"internalType":"address","name":"collection2","type":"address"}],"indexed":false,"internalType":"struct Discounts.DiscountConfig","name":"","type":"tuple"}],"name":"DiscountSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"}],"name":"EmergencyWithdrawERC20","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"EmergencyWithdrawERC721","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bool","name":"isExecutor","type":"bool"}],"name":"ExecutorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"executorsOnly","type":"bool"}],"name":"ExecutorsOnlySet","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"partner","type":"address"},{"internalType":"uint32","name":"treasurySplit","type":"uint32"},{"internalType":"uint32","name":"partnerSplit","type":"uint32"},{"internalType":"uint32","name":"sweepSplit","type":"uint32"}],"indexed":false,"internalType":"struct PixelSweeperPlayerPotV3Base.FundConfig","name":"fundConfig","type":"tuple"}],"name":"FundConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"feed","type":"address"},{"indexed":false,"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"PriceFeedUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nftsSwept","type":"uint256"}],"name":"PrizeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"prizeStrategy","type":"address"}],"name":"PrizeStrategySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"TicketPriceSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"rountId","type":"uint256"},{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TicketsBought","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"uint256","name":"prizes","type":"uint256"}],"name":"addPrizeFromVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"afterPrizePoolAwarded","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"randomNumber","type":"uint256"},{"internalType":"uint256","name":"prizePeriodStartAt","type":"uint256"}],"name":"beforePrizePoolAwarded","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"beforeTokenTransfer","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256[]","name":"discountIds","type":"uint256[]"}],"name":"buyTickets","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"tickets","type":"uint256"},{"internalType":"uint256[]","name":"discountIds","type":"uint256[]"}],"name":"calculateCost","outputs":[{"internalType":"uint256","name":"cost","type":"uint256"},{"internalType":"uint256[]","name":"discountedTicketss","type":"uint256[]"},{"internalType":"uint256[]","name":"discountFactors","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collection","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentRound","outputs":[{"components":[{"internalType":"uint256","name":"roundId","type":"uint256"},{"internalType":"uint256","name":"ticketPrice","type":"uint256"},{"internalType":"contract BurnableTicket","name":"ticket","type":"address"},{"internalType":"uint256","name":"ticketsSold","type":"uint256"},{"internalType":"uint256","name":"nftsSweept","type":"uint256"}],"internalType":"struct PixelSweeperPlayerPotV3Base.Round","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"currentTicketBalance","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"totalSupply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"discounts","outputs":[{"components":[{"internalType":"uint16","name":"id","type":"uint16"},{"internalType":"uint16","name":"discountFactor","type":"uint16"},{"internalType":"uint16","name":"discountedTickets","type":"uint16"},{"internalType":"uint8","name":"collections","type":"uint8"},{"internalType":"address","name":"collection1","type":"address"},{"internalType":"address","name":"collection2","type":"address"}],"internalType":"struct Discounts.DiscountConfig[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"roundId","type":"uint256"},{"internalType":"uint256","name":"discountId","type":"uint256"}],"name":"discountsUsed","outputs":[{"internalType":"uint256","name":"used","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"donatePrizes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ethUsdFeed","outputs":[{"internalType":"address","name":"feed","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"executorsOnly","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fundConfig","outputs":[{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"partner","type":"address"},{"internalType":"uint32","name":"treasurySplit","type":"uint32"},{"internalType":"uint32","name":"partnerSplit","type":"uint32"},{"internalType":"uint32","name":"sweepSplit","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isExectutor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"nativeFromUsd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"prizeStrategy","outputs":[{"internalType":"contract IDynamicPeriodicPrizeStrategy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"removeDiscount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"roundId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rounds","outputs":[{"internalType":"uint256","name":"roundId","type":"uint256"},{"internalType":"uint256","name":"ticketPrice","type":"uint256"},{"internalType":"contract BurnableTicket","name":"ticket","type":"address"},{"internalType":"uint256","name":"ticketsSold","type":"uint256"},{"internalType":"uint256","name":"nftsSweept","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint16","name":"id","type":"uint16"},{"internalType":"uint16","name":"discountFactor","type":"uint16"},{"internalType":"uint16","name":"discountedTickets","type":"uint16"},{"internalType":"uint8","name":"collections","type":"uint8"},{"internalType":"address","name":"collection1","type":"address"},{"internalType":"address","name":"collection2","type":"address"}],"internalType":"struct Discounts.DiscountConfig","name":"discount","type":"tuple"}],"name":"setDiscount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"feed","type":"address"}],"name":"setEthUsdPriceFeed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"executor","type":"address"},{"internalType":"bool","name":"_isExecutor","type":"bool"}],"name":"setExecutor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_executorsOnly","type":"bool"}],"name":"setExecutorsOnly","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"partner","type":"address"},{"internalType":"uint32","name":"treasurySplit","type":"uint32"},{"internalType":"uint32","name":"partnerSplit","type":"uint32"},{"internalType":"uint32","name":"sweepSplit","type":"uint32"}],"internalType":"struct PixelSweeperPlayerPotV3Base.FundConfig","name":"_fundConfig","type":"tuple"}],"name":"setFundConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IDynamicPeriodicPrizeStrategy","name":"_prizeStrategy","type":"address"}],"name":"setPrizeStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_ticketPrice","type":"uint256"}],"name":"setTicketPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_collection","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"uint256","name":"_timestamp","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sweeper","outputs":[{"internalType":"contract IRareboardSweeper","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sweepingFunds","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ticket","outputs":[{"internalType":"contract ITicket","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ticketPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ticketsRollOver","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"usdFromNative","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdPriceDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101406040523480156200001257600080fd5b50604051620081bc380380620081bc833981016040819052620000359162000bae565b88888888888888886200004833620001e5565b600180556040516200005a90620009e3565b604051809103906000f08015801562000077573d6000803e3d6000fd5b506001600160a01b03166080526002805460ff191690556200009988620001e5565b6001600160a01b0380881660e052861660a052600a85905582151560c0526010620000c5838262000d2b565b506011620000d4828262000d2b565b5060e05160a05160405163ce72772960e01b81526001600160a01b03918216600482015230602482015291169063ce727729906044016020604051808303816000875af11580156200012a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000150919062000df7565b6001600160a01b0316610100819052620001a05760405162461bcd60e51b815260206004820152600c60248201526b14d95d1d5c0819985a5b195960a21b60448201526064015b60405180910390fd5b620001ab8462000235565b620001b562000459565b620001bf620004b6565b5050506001600160a01b03909516610120525062000f929b505050505050505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61271081606001518260400151836080015162000253919062000e34565b6200025f919062000e34565b63ffffffff1614620002a45760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a590814dc1b1a5d609a1b604482015260640162000197565b80516001600160a01b0316620002fd5760405162461bcd60e51b815260206004820152601460248201527f496e76616c69642066756e642061646472657373000000000000000000000000604482015260640162000197565b60208101516001600160a01b0316620003595760405162461bcd60e51b815260206004820152601460248201527f496e76616c69642066756e642061646472657373000000000000000000000000604482015260640162000197565b6040805182516001600160a01b039081168252602080850151909116908201528282015163ffffffff908116828401526060808501518216908301526080808501519091169082015290517f6430fee6dee986056638c4e4129ff4b5374d0d4d58d43ce042c0c4e84bcb6cec9181900360a00190a18051600c80546001600160a01b0319166001600160a01b039283161790556020820151600d805460408501516060860151608090960151939094166001600160c01b031990911617600160a01b63ffffffff94851602176001600160c01b0316600160c01b948416949094026001600160e01b031693909317600160e01b9290911691909102179055565b62000463620006ec565b6002805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258620004993390565b6040516001600160a01b03909116815260200160405180910390a1565b6009546000908152600b602052604081206002015460c0516001600160a01b0390911691908015620004f057506001600160a01b03821615155b80156200050f57506009546000908152600b6020526040902060040154155b9050801580156200052857506001600160a01b03821615155b156200060857816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200056d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000593919062000e5b565b6009546000908152600b60205260409081902060030191909155516380929e5b60e01b8152600160048201526001600160a01b038316906380929e5b90602401600060405180830381600087803b158015620005ee57600080fd5b505af115801562000603573d6000803e3d6000fd5b505050505b80620006e8576000600b6000600960008154620006259062000e75565b919050819055815260200190815260200160002090506000620006506009546200073660201b60201c565b905060006010826040516020016200066a92919062000e91565b604051602081830303815290604052905060006011836040516020016200069392919062000e91565b60408051601f1981840301815291905290506000620006b38383620007cf565b6002860180546001600160a01b0319166001600160a01b0392909216919091179055505060095483555050600a546001909101555b5050565b60025460ff1615620007345760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640162000197565b565b60606000620007458362000856565b60010190506000816001600160401b0381111562000767576200076762000a17565b6040519080825280601f01601f19166020018201604052801562000792576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846200079c57509392505050565b600080620007e56080516200094060201b60201c565b6040516303bf912560e11b81529091506001600160a01b0382169063077f224a906200081a9087908790309060040162000f50565b600060405180830381600087803b1580156200083557600080fd5b505af11580156200084a573d6000803e3d6000fd5b50929695505050505050565b6000807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310620008a0577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef81000000008310620008cd576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310620008ec57662386f26fc10000830492506010015b6305f5e100831062000905576305f5e100830492506008015b61271083106200091a57612710830492506004015b606483106200092d576064830492506002015b600a83106200093a576001015b92915050565b6000763d602d80600a3d3981f3363d3d373d3d3d363d730000008260601b60e81c176000526e5af43d82803e903d91602b57fd5bf38260781b17602052603760096000f090506001600160a01b038116620009de5760405162461bcd60e51b815260206004820152601660248201527f455243313136373a20637265617465206661696c656400000000000000000000604482015260640162000197565b919050565b6120b7806200610583390190565b6001600160a01b038116811462000a0757600080fd5b50565b8051620009de81620009f1565b634e487b7160e01b600052604160045260246000fd5b805163ffffffff81168114620009de57600080fd5b600060a0828403121562000a5557600080fd5b60405160a081016001600160401b038111828210171562000a7a5762000a7a62000a17565b8060405250809150825162000a8f81620009f1565b8152602083015162000aa181620009f1565b602082015262000ab46040840162000a2d565b604082015262000ac76060840162000a2d565b606082015262000ada6080840162000a2d565b60808201525092915050565b80518015158114620009de57600080fd5b60005b8381101562000b1457818101518382015260200162000afa565b50506000910152565b600082601f83011262000b2f57600080fd5b81516001600160401b038082111562000b4c5762000b4c62000a17565b604051601f8301601f19908116603f0116810190828211818310171562000b775762000b7762000a17565b8160405283815286602085880101111562000b9157600080fd5b62000ba484602083016020890162000af7565b9695505050505050565b60008060008060008060008060006101a08a8c03121562000bce57600080fd5b895162000bdb81620009f1565b60208b015190995062000bee81620009f1565b975062000bfe60408b0162000a0a565b965060608a0151955062000c168b60808c0162000a42565b945062000c276101208b0162000ae6565b6101408b01519094506001600160401b038082111562000c4657600080fd5b62000c548d838e0162000b1d565b94506101608c015191508082111562000c6c57600080fd5b5062000c7b8c828d0162000b1d565b92505062000c8d6101808b0162000a0a565b90509295985092959850929598565b600181811c9082168062000cb157607f821691505b60208210810362000cd257634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000d2657600081815260208120601f850160051c8101602086101562000d015750805b601f850160051c820191505b8181101562000d225782815560010162000d0d565b5050505b505050565b81516001600160401b0381111562000d475762000d4762000a17565b62000d5f8162000d58845462000c9c565b8462000cd8565b602080601f83116001811462000d97576000841562000d7e5750858301515b600019600386901b1c1916600185901b17855562000d22565b600085815260208120601f198616915b8281101562000dc85788860151825594840194600190910190840162000da7565b508582101562000de75787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006020828403121562000e0a57600080fd5b815162000e1781620009f1565b9392505050565b634e487b7160e01b600052601160045260246000fd5b63ffffffff81811683821601908082111562000e545762000e5462000e1e565b5092915050565b60006020828403121562000e6e57600080fd5b5051919050565b60006001820162000e8a5762000e8a62000e1e565b5060010190565b600080845462000ea18162000c9c565b6001828116801562000ebc576001811462000ed25762000f03565b60ff198416875282151583028701945062000f03565b8860005260208060002060005b8581101562000efa5781548a82015290840190820162000edf565b50505082870194505b50505050835162000f1981836020880162000af7565b01949350505050565b6000815180845262000f3c81602086016020860162000af7565b601f01601f19169290920160200192915050565b60608152600062000f65606083018662000f22565b828103602084015262000f79818662000f22565b91505060018060a01b0383166040830152949350505050565b60805160a05160c05160e05161010051610120516150906200107560003960008181610ae801528181610de401528181610e4601528181611670015281816116ac015281816120e70152818161214a01526126b401526000818161092001526139650152600081816108230152611bf10152600081816108ec015261286f01526000818161063f01528181610c3101528181610e76015281816113830152818161174a01528181611ae401528181612179015281816121f0015281816126fc0152818161278601528181612fe5015261308301526000613c8b01526150906000f3fe6080604052600436106103125760003560e01c80638456cb591161019a578063b2940d02116100e1578063e5a690f71161008a578063ed0d294e11610064578063ed0d294e14610aa1578063f2fde38b14610ab6578063fbfa77cf14610ad657600080fd5b8063e5a690f714610a41578063ea03a53e14610a61578063ec24720614610a8157600080fd5b8063dfeaa74c116100bb578063dfeaa74c14610977578063e28d1d2e14610997578063e293dcbf14610a2157600080fd5b8063b2940d021461090e578063db2e21bc14610942578063ded983b01461095757600080fd5b80639189a59e116101435780639a08bd1c1161011d5780639a08bd1c146108855780639a19aed1146108a5578063aa58a28c146108da57600080fd5b80639189a59e1461081157806391ca480e1461084557806398bf3eb61461086557600080fd5b80638c65c81f116101745780638c65c81f146107535780638cd221c9146107dd5780638da5cb5b146107f357600080fd5b80638456cb59146106ae5780638a19c8bc146106c35780638baa71811461072357600080fd5b80634cdf9c3e1161025e57806372389a5e116102075780637cbab1c7116101e15780637cbab1c71461060d5780637de1e5361461062d5780638009b7bd1461066157600080fd5b806372389a5e146105ab57806375af65d1146105cb5780637728805e146105ed57600080fd5b80636cc25db7116102385780636cc25db7146105325780636ff1c9bc14610576578063715018a61461059657600080fd5b80634cdf9c3e146104da578063575072c6146104fa5780635c975abb1461051a57600080fd5b8063178c6618116102c05780631fe449311161029a5780631fe449311461047657806323ee2234146104965780633f4ba83a146104c557600080fd5b8063178c6618146103fe57806317a94b57146104185780631e1bff3f1461045657600080fd5b80631209b1f6116102f15780631209b1f61461038f578063150b7a02146103a557806315981650146103de57600080fd5b80629c367c1461031757806301ffc9a71461034a578063104ba8c81461037a575b600080fd5b34801561032357600080fd5b50610337610332366004614394565b610b0a565b6040519081526020015b60405180910390f35b34801561035657600080fd5b5061036a6103653660046143ad565b610b1b565b6040519015158152602001610341565b61038d610388366004614438565b610b9d565b005b34801561039b57600080fd5b50610337600a5481565b3480156103b157600080fd5b506103c56103c036600461454b565b610c24565b6040516001600160e01b03199091168152602001610341565b3480156103ea57600080fd5b5061038d6103f9366004614394565b610cde565b34801561040a57600080fd5b50600f5461036a9060ff1681565b34801561042457600080fd5b506103376104333660046145b7565b600360209081526000938452604080852082529284528284209052825290205481565b34801561046257600080fd5b5061038d6104713660046145fa565b610d22565b34801561048257600080fd5b5061038d610491366004614394565b610d89565b3480156104a257600080fd5b506104b66104b1366004614633565b610d9d565b604051610341939291906146b2565b3480156104d157600080fd5b5061038d610dda565b3480156104e657600080fd5b5061038d6104f53660046146dd565b610f39565b34801561050657600080fd5b5061038d6105153660046146dd565b610faa565b34801561052657600080fd5b5060025460ff1661036a565b34801561053e57600080fd5b506009546000908152600b60205260409020600201546001600160a01b03165b6040516001600160a01b039091168152602001610341565b34801561058257600080fd5b5061038d6105913660046146ff565b611015565b3480156105a257600080fd5b5061038d61112e565b3480156105b757600080fd5b5061038d6105c6366004614730565b611140565b3480156105d757600080fd5b506105e0611151565b60405161034191906147c2565b3480156105f957600080fd5b5061038d610608366004614861565b6112af565b34801561061957600080fd5b5061038d6106283660046148a3565b61140a565b34801561063957600080fd5b5061055e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561066d57600080fd5b5060075461068d906001600160a01b03811690600160a01b900460ff1682565b604080516001600160a01b03909316835260ff909116602083015201610341565b3480156106ba57600080fd5b5061038d6115af565b3480156106cf57600080fd5b506106d86115bf565b6040516103419190600060a08201905082518252602083015160208301526001600160a01b036040840151166040830152606083015160608301526080830151608083015292915050565b34801561072f57600080fd5b5061036a61073e3660046146ff565b600e6020526000908152604090205460ff1681565b34801561075f57600080fd5b506107a761076e366004614394565b600b6020526000908152604090208054600182015460028301546003840154600490940154929391926001600160a01b03909116919085565b6040805195865260208601949094526001600160a01b03909216928401929092526060830191909152608082015260a001610341565b3480156107e957600080fd5b5061033760095481565b3480156107ff57600080fd5b506000546001600160a01b031661055e565b34801561081d57600080fd5b5061055e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561085157600080fd5b5061038d6108603660046146ff565b611655565b34801561087157600080fd5b5060085461055e906001600160a01b031681565b34801561089157600080fd5b5061038d6108a0366004614394565b61166e565b3480156108b157600080fd5b506108c56108c03660046146ff565b6117c0565b60408051928352602083019190915201610341565b3480156108e657600080fd5b5061036a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561091a57600080fd5b5061055e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561094e57600080fd5b5061038d6118ae565b34801561096357600080fd5b50610337610972366004614394565b611947565b34801561098357600080fd5b5061038d6109923660046148e4565b611952565b3480156109a357600080fd5b50600c54600d546109e3916001600160a01b03908116919081169063ffffffff600160a01b8204811691600160c01b8104821691600160e01b9091041685565b604080516001600160a01b03968716815295909416602086015263ffffffff928316938501939093528116606084015216608082015260a001610341565b348015610a2d57600080fd5b5061038d610a3c3660046146ff565b611aa8565b348015610a4d57600080fd5b5061038d610a5c3660046149c0565b611ab9565b348015610a6d57600080fd5b5061038d610a7c366004614a65565b611aca565b348015610a8d57600080fd5b5061038d610a9c366004614b2c565b611c83565b348015610aad57600080fd5b50610337600881565b348015610ac257600080fd5b5061038d610ad13660046146ff565b611ccc565b348015610ae257600080fd5b5061055e7f000000000000000000000000000000000000000000000000000000000000000081565b6000610b1582611d59565b92915050565b60006001600160e01b031982167f575072c6000000000000000000000000000000000000000000000000000000001480610b7e57506001600160e01b031982167f4cdf9c3e00000000000000000000000000000000000000000000000000000000145b80610b1557506301ffc9a760e01b6001600160e01b0319831614610b15565b6000610bab85858585611e2a565b905080341015610c025760405162461bcd60e51b815260206004820152601760248201527f496e73756666696369656e742066756e64732073656e6400000000000000000060448201526064015b60405180910390fd5b80341115610c1d57610c1d33610c188334614b5f565b611f6a565b5050505050565b6000336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610c9e5760405162461bcd60e51b815260206004820152600f60248201527f4f6e6c7920636f6c6c656374696f6e00000000000000000000000000000000006044820152606401610bf9565b60125460ff16610cb357610cb3836000612083565b507f150b7a02000000000000000000000000000000000000000000000000000000005b949350505050565b610ce6612259565b600a8190556040518181527f34388f2433e2a2e6d6f978efe10bb2784b04bec67ff0eaa768c332c248da5d1d906020015b60405180910390a150565b610d2a612259565b6001600160a01b0382166000818152600e6020908152604091829020805460ff191685151590811790915591519182527f278b09622564dd3991fe7744514513d64ea2c8ed2b2b9ec1150ad964fde80a99910160405180910390a25050565b610d91612259565b610d9a816122b3565b50565b6000606080610dca60095488600b6000600954815260200190815260200160002060010154898989612313565b9250925092509450945094915050565b610de2612259565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161580610ee357506008546040517fe985e9c50000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015291821660248201527f00000000000000000000000000000000000000000000000000000000000000009091169063e985e9c590604401602060405180830381865afa158015610ebf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee39190614b72565b610f2f5760405162461bcd60e51b815260206004820152601e60248201527f73747261746567792d6e6f742d617070726f7665642d62792d7661756c7400006044820152606401610bf9565b610f37612492565b565b6008546001600160a01b0316336001600160a01b031614610f9c5760405162461bcd60e51b815260206004820152601360248201527f6f6e6c79207072697a65207374726174656779000000000000000000000000006044820152606401610bf9565b610fa682826126b2565b5050565b6008546001600160a01b0316336001600160a01b03161461100d5760405162461bcd60e51b815260206004820152601360248201527f6f6e6c79207072697a65207374726174656779000000000000000000000000006044820152606401610bf9565b610fa661284e565b61101d612259565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015611064573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110889190614b8f565b9050806000036110da5760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f74207265636f766572207a65726f2062616c616e636500000000006044820152606401610bf9565b6040518181526001600160a01b0383169033907fda568f14cc33c45f2866f24477f9007a04f029daa19ea7192cf685a53b9b92c89060200160405180910390a3610fa66001600160a01b0383163383612aa9565b611136612259565b610f376000612b29565b611148612259565b610d9a81612b86565b6060600061115f6005612e0d565b905060008167ffffffffffffffff81111561117c5761117c614494565b6040519080825280602002602001820160405280156111dc57816020015b6040805160c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820152825260001990920191018161119a5790505b50905060005b828110156112a857600460006111f9600584612e17565b81526020808201929092526040908101600020815160c081018352815461ffff808216835262010000820481169583019590955264010000000081049094169281019290925260ff660100000000000084041660608301526001600160a01b03670100000000000000909304831660808301526001015490911660a0820152825183908390811061128c5761128c614ba8565b6020026020010181905250806112a190614bbe565b90506111e2565b5092915050565b6012805460ff191660011790556008546001600160a01b03166113145760405162461bcd60e51b815260206004820152600f60248201527f4e6f2073747261746567792073657400000000000000000000000000000000006044820152606401610bf9565b60005b818110156113fb57600083838381811061133357611333614ba8565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015230602482015260209091029290920135604483018190529250506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906323b872dd90606401600060405180830381600087803b1580156113c757600080fd5b505af11580156113db573d6000803e3d6000fd5b505050506113ea816000612083565b506113f481614bbe565b9050611317565b50506012805460ff1916905550565b816001600160a01b0316836001600160a01b03160361146b5760405162461bcd60e51b815260206004820152600d60248201527f53656c66207472616e73666572000000000000000000000000000000000000006044820152606401610bf9565b6001600160a01b038316158061148857506001600160a01b038216155b6114d45760405162461bcd60e51b815260206004820152601860248201527f5469636b657473206e6f6e207472616e7366657261626c6500000000000000006044820152606401610bf9565b6008546001600160a01b0316158061155e5750600860009054906101000a90046001600160a01b03166001600160a01b03166330f747ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561153a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155e9190614b72565b6115aa5760405162461bcd60e51b815260206004820152601160248201527f417761726420696e2070726f67726573730000000000000000000000000000006044820152606401610bf9565b505050565b6115b7612259565b610f37612e2a565b6115fa6040518060a00160405280600081526020016000815260200160006001600160a01b0316815260200160008152602001600081525090565b506009546000908152600b6020908152604091829020825160a0810184528154815260018201549281019290925260028101546001600160a01b03169282019290925260038201546060820152600490910154608082015290565b61165d612259565b611665612e84565b610d9a81612ed6565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316158015906116ce5750336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016145b61171a5760405162461bcd60e51b815260206004820152600a60248201527f6f6e6c792d7661756c74000000000000000000000000000000000000000000006044820152606401610bf9565b60005b81811015610fa657611730600080613138565b60085460405163deeaf11b60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301529091169063deeaf11b90602401600060405180830381600087803b15801561179757600080fd5b505af11580156117ab573d6000803e3d6000fd5b50505050806117b990614bbe565b905061171d565b6009546000908152600b60205260408082206002015490516370a0823160e01b81526001600160a01b0384811660048301528392169081906370a0823190602401602060405180830381865afa15801561181e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118429190614b8f565b9250806001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611882573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118a69190614b8f565b915050915091565b6118b6612259565b4760008190036119085760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f74207265636f766572207a65726f2062616c616e636500000000006044820152606401610bf9565b60405181815233907f5fafa99d0643513820be26656b45130b01e1c03062e1266bf36f88cbd3bd96959060200160405180910390a2610d9a3382611f6a565b6000610b15826131bf565b61195a612259565b80516000036119ab5760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f74207265636f766572207a65726f2062616c616e636500000000006044820152606401610bf9565b816001600160a01b0316336001600160a01b03167f1a42b329ffb74e68eccd569af5123474d5ed15bfab15c94cca5271ed2aa03614836040516119ee9190614bd8565b60405180910390a360005b81518110156115aa57826001600160a01b03166323b872dd3033858581518110611a2557611a25614ba8565b60209081029190910101516040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b158015611a7f57600080fd5b505af1158015611a93573d6000803e3d6000fd5b5050505080611aa190614bbe565b90506119f9565b611ab0612259565b610d9a81613286565b611ac1612259565b610d9a816133b5565b6012805460ff191660011790556001600160a01b038781167f00000000000000000000000000000000000000000000000000000000000000009190911614611b545760405162461bcd60e51b815260206004820152601460248201527f4f6e6c79206d61696e20636f6c6c656374696f6e0000000000000000000000006044820152606401610bf9565b600f5460ff161580611b755750336000908152600e602052604090205460ff165b611bc15760405162461bcd60e51b815260206004820152600e60248201527f4f6e6c79206578656375746f72730000000000000000000000000000000000006044820152606401610bf9565b6040517f75d5da510000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906375d5da5190611c34908a908a908a908a908a908a908a903090600401614c3b565b600060405180830381600087803b158015611c4e57600080fd5b505af1158015611c62573d6000803e3d6000fd5b50505050611c708686612083565b50506012805460ff191690555050505050565b611c8b612259565b600f805460ff19168215159081179091556040519081527f951a4ddc4870161de6fcd55dea2c9773af92888fc44b7d870d8fca94ec188a6790602001610d17565b611cd4612259565b6001600160a01b038116611d505760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610bf9565b610d9a81612b29565b6040805180820182526007546001600160a01b038116808352600160a01b90910460ff166020830181905283517ffeaf968c00000000000000000000000000000000000000000000000000000000815293516000948591849163feaf968c9160048083019260a09291908290030181865afa158015611ddc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e009190614cce565b505050915050611e208187611e159190614d1e565b60088460ff166136c4565b9695505050505050565b6000611e3461371f565b611e3c613778565b6009546000818152600b60205260409020600101543391611e619183908988886137cb565b6009546000908152600b60205260409020600201549092506001600160a01b031680635d7b075887611e9b8a670de0b6b3a7640000614d40565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015611ee157600080fd5b505af1158015611ef5573d6000803e3d6000fd5b50505050856001600160a01b0316826001600160a01b03166009547f71d54cf57511eea8d601229e41e7d0ed6e13eeac75d51b8f83fa8c7f02aff9808a670de0b6b3a7640000611f459190614d40565b60405190815260200160405180910390a4611f5f836138df565b5050610cd660018055565b80471015611fba5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610bf9565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612007576040519150601f19603f3d011682016040523d82523d6000602084013e61200c565b606091505b50509050806115aa5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610bf9565b61208d8282613138565b6008546001600160a01b03166120e55760405162461bcd60e51b815260206004820152601160248201527f6e6f2d7072697a652d73747261746567790000000000000000000000000000006044820152606401610bf9565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316156121d6576040517f42842e0e0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166024830152604482018490527f000000000000000000000000000000000000000000000000000000000000000016906342842e0e90606401600060405180830381600087803b1580156121bd57600080fd5b505af11580156121d1573d6000803e3d6000fd5b505050505b60085460405163deeaf11b60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301529091169063deeaf11b90602401600060405180830381600087803b15801561223d57600080fd5b505af1158015612251573d6000803e3d6000fd5b505050505050565b6000546001600160a01b03163314610f375760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610bf9565b6122be6005826139a8565b50600090815260046020526040902080547fffffffffff000000000000000000000000000000000000000000000000000000168155600101805473ffffffffffffffffffffffffffffffffffffffff19169055565b6000606080838067ffffffffffffffff81111561233257612332614494565b60405190808252806020026020018201604052801561235b578160200160208202803683370190505b5092508067ffffffffffffffff81111561237757612377614494565b6040519080825280602002602001820160405280156123a0578160200160208202803683370190505b50915060005b8181101561246e576000806123d48d8d8b8b878181106123c8576123c8614ba8565b905060200201356139b4565b915091506123e2828b613b94565b9150818684815181106123f7576123f7614ba8565b6020026020010181815250508085848151811061241657612416614ba8565b602090810291909101015261242b828b614b5f565b99508161271061243b838e614d40565b6124459190614d1e565b61244f9190614d40565b6124599088614d57565b965050508061246790614bbe565b90506123a6565b506124798789614d40565b6124839085614d57565b93505096509650969350505050565b61249a612259565b6008546001600160a01b03166124f25760405162461bcd60e51b815260206004820152601160248201527f6e6f2d7072697a652d73746172746567790000000000000000000000000000006044820152606401610bf9565b600854604080517fc2f19ee8000000000000000000000000000000000000000000000000000000008152905130926001600160a01b03169163c2f19ee89160048083019260209291908290030181865afa158015612554573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125789190614d6a565b6001600160a01b0316146125ce5760405162461bcd60e51b815260206004820152601960248201527f6e6f742d7365742d61732d61667465722d6c697374656e6572000000000000006044820152606401610bf9565b600854604080517f0d847fc4000000000000000000000000000000000000000000000000000000008152905130926001600160a01b031691630d847fc49160048083019260209291908290030181865afa158015612630573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126549190614d6a565b6001600160a01b0316146126aa5760405162461bcd60e51b815260206004820152601a60248201527f6e6f742d7365742d61732d6265666f72652d6c697374656e65720000000000006044820152606401610bf9565b610f37613baa565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166126e4575050565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561274b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061276f9190614b8f565b905060005b81811015612848576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016632f745c5930836127b8600187614b5f565b6127c29190614b5f565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa925050508015612827575060408051601f3d908101601f1916820190925261282491810190614b8f565b60015b1561284857612837816000612083565b5061284181614bbe565b9050612774565b50505050565b6009546000908152600b60205260408120600201546001600160a01b0316907f000000000000000000000000000000000000000000000000000000000000000080156128a257506001600160a01b03821615155b80156128c057506009546000908152600b6020526040902060040154155b9050801580156128d857506001600160a01b03821615155b156129cb57816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561291b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061293f9190614b8f565b6009546000908152600b60205260409081902060030191909155517f80929e5b000000000000000000000000000000000000000000000000000000008152600160048201526001600160a01b038316906380929e5b90602401600060405180830381600087803b1580156129b257600080fd5b505af11580156129c6573d6000803e3d6000fd5b505050505b80610fa6576000600b60006009600081546129e590614bbe565b919050819055815260200190815260200160002090506000612a08600954613be3565b90506000601082604051602001612a20929190614da3565b60405160208183030381529060405290506000601183604051602001612a47929190614da3565b60405160208183030381529060405290506000612a648383613c83565b60028601805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055505060095483555050600a546001909101555050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526115aa908490613d35565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612710816060015182604001518360800151612ba29190614e4d565b612bac9190614e4d565b63ffffffff1614612bff5760405162461bcd60e51b815260206004820152600d60248201527f496e76616c69642053706c6974000000000000000000000000000000000000006044820152606401610bf9565b80516001600160a01b0316612c565760405162461bcd60e51b815260206004820152601460248201527f496e76616c69642066756e6420616464726573730000000000000000000000006044820152606401610bf9565b60208101516001600160a01b0316612cb05760405162461bcd60e51b815260206004820152601460248201527f496e76616c69642066756e6420616464726573730000000000000000000000006044820152606401610bf9565b7f6430fee6dee986056638c4e4129ff4b5374d0d4d58d43ce042c0c4e84bcb6cec81604051612d2f9190600060a0820190506001600160a01b0380845116835280602085015116602084015250604083015163ffffffff8082166040850152806060860151166060850152806080860151166080850152505092915050565b60405180910390a18051600c805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b039283161790556020820151600d805460408501516060860151608090960151939094167fffffffffffffffff00000000000000000000000000000000000000000000000090911617600160a01b63ffffffff948516021777ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b948416949094027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1693909317600160e01b9290911691909102179055565b6000610b15825490565b6000612e238383613e1d565b9392505050565b612e32613778565b6002805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612e673390565b6040516001600160a01b03909116815260200160405180910390a1565b60025460ff16610f375760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610bf9565b6001600160a01b038116612f2c5760405162461bcd60e51b815260206004820152601660248201527f7072697a6553747261746567792d6e6f742d7a65726f000000000000000000006044820152606401610bf9565b612f466001600160a01b03821663deeaf11b60e01b613e47565b612f925760405162461bcd60e51b815260206004820152601560248201527f7072697a6553747261746567792d696e76616c696400000000000000000000006044820152606401610bf9565b6008546001600160a01b031615613044576008546040517fa22cb4650000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152600060248201527f00000000000000000000000000000000000000000000000000000000000000009091169063a22cb46590604401600060405180830381600087803b15801561302b57600080fd5b505af115801561303f573d6000803e3d6000fd5b505050505b6040517fa22cb4650000000000000000000000000000000000000000000000000000000081526001600160a01b038281166004830152600160248301527f0000000000000000000000000000000000000000000000000000000000000000169063a22cb46590604401600060405180830381600087803b1580156130c757600080fd5b505af11580156130db573d6000803e3d6000fd5b50506008805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385169081179091556040519092507f7f58dc86bc2e435cb77ca0edb1df55e25f90caf2d6bd866971715437d456a2129150600090a250565b6009546000908152600b6020526040812060040180546001929061315d908490614d57565b90915550506009546000908152600b6020908152604091829020600401548251858152918201849052918101919091527fcd9a7360c57fb4628e98193b7a9e651d55b1fe0dbe62ad9547a0390cd1dab713906060015b60405180910390a15050565b6040805180820182526007546001600160a01b038116808352600160a01b90910460ff166020830181905283517ffeaf968c00000000000000000000000000000000000000000000000000000000815293516000948591849163feaf968c9160048083019260a09291908290030181865afa158015613242573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132669190614cce565b505050915050611e20818761327b9190614d40565b8360ff1660086136c4565b6001600160a01b0381166132c6576040517ffaf6a7a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613306573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061332a9190614e6a565b6040805180820182526001600160a01b03851680825260ff84166020928301819052600780547fffffffffffffffffffffff000000000000000000000000000000000000000000168317600160a01b83021790558351918252918101919091529192507f8deb401a943ebaf5b5b213be8b61e720c24de99752ca0e593386d5b330e7973d91016131b3565b8051602082015160408301516060840151608085015161232861ffff851610156134215760405162461bcd60e51b815260206004820152601760248201527f496e76616c696420646973636f756e7420666163746f720000000000000000006044820152606401610bf9565b60008361ffff16116134755760405162461bcd60e51b815260206004820152601860248201527f496e76616c696420646973636f756e74207469636b65747300000000000000006044820152606401610bf9565b6001600160a01b0381166134cb5760405162461bcd60e51b815260206004820152601360248201527f496e76616c696420636f6c6c656374696f6e31000000000000000000000000006044820152606401610bf9565b8160ff16600114806134f757508160ff1660021480156134f7575060a08601516001600160a01b031615155b6135435760405162461bcd60e51b815260206004820152601360248201527f496e76616c696420636f6c6c656374696f6e73000000000000000000000000006044820152606401610bf9565b61ffff8516613553600582613e63565b5060008181526004602090815260409182902089518154928b01518b85015160608d015160808e015161ffff9485167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000909716969096176201000093851693909302929092177fffffffffffffffffffffffffffffffffffffffffffffffffff000000ffffffff1664010000000093909116929092027fffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffff1691909117660100000000000060ff90921691909102177fffffffffff0000000000000000000000000000000000000000ffffffffffffff166701000000000000006001600160a01b039384160217815560a08a01516001909101805473ffffffffffffffffffffffffffffffffffffffff191691909216179055517fbd578e2dcec99bbaa454fe5206b66b738d0b3b33a0c9c2e1a28ac8024926631f906136b3908990614e87565b60405180910390a150505050505050565b6000818314613717578183116136f8576136de8383614b5f565b6136e990600a614fca565b6136f39085614d40565b610cd6565b6137028284614b5f565b61370d90600a614fca565b6136f39085614d1e565b509192915050565b6002600154036137715760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610bf9565b6002600155565b60025460ff1615610f375760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610bf9565b600081815b818110156138be5760008585838181106137ec576137ec614ba8565b9050602002013590506000806138038c8c856139b4565b91509150613811828a613b94565b915081600360008d6001600160a01b03166001600160a01b0316815260200190815260200160002060008e81526020019081526020016000206000858152602001908152602001600020600082825461386a9190614d57565b9091555061387a9050828a614b5f565b98508161271061388a838d614d40565b6138949190614d1e565b61389e9190614d40565b6138a89087614d57565b9550505050806138b790614bbe565b90506137d0565b506138c98587614d40565b6138d39083614d57565b98975050505050505050565b600c54600d546001600160a01b039182169181169063ffffffff600160c01b8204811691600160e01b900416600061271061391a8388614d40565b6139249190614d1e565b9050600061271061393b63ffffffff861689614d40565b6139459190614d1e565b9050600081613954848a614b5f565b61395e9190614b5f565b905061398a7f000000000000000000000000000000000000000000000000000000000000000084611f6a565b6139948782611f6a565b61399e8683611f6a565b5050505050505050565b6000612e238383613e6f565b6000818152600460208181526040808420815160c081018352815461ffff8082168352620100008204811695830186905264010000000082041682850181905260ff6601000000000000830416606084018190526001600160a01b03670100000000000000909304831660808501819052600190950154831660a085015294516370a0823160e01b8152918a16968201969096528695919493919290869082906370a0823190602401602060405180830381865afa158015613a7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a9e9190614b8f565b90508260ff16600203613b285760a08601516040516370a0823160e01b81526001600160a01b038c81166004830152613b259284929116906370a0823190602401602060405180830381865afa158015613afc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b209190614b8f565b613b94565b90505b6001600160a01b038a1660009081526003602090815260408083208e845282528083208c8452909152902054613b6261ffff861683614d40565b9850888111613b7a57613b75818a614b5f565b613b7d565b60005b9c61ffff9096169b50949950505050505050505050565b6000818310613ba35781612e23565b5090919050565b613bb2612e84565b6002805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33612e67565b60606000613bf083613f62565b600101905060008167ffffffffffffffff811115613c1057613c10614494565b6040519080825280601f01601f191660200182016040528015613c3a576020820181803683370190505b5090508181016020015b600019017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8504945084613c4457509392505050565b600080613caf7f0000000000000000000000000000000000000000000000000000000000000000614044565b6040517f077f224a0000000000000000000000000000000000000000000000000000000081529091506001600160a01b0382169063077f224a90613cfb90879087903090600401614fd6565b600060405180830381600087803b158015613d1557600080fd5b505af1158015613d29573d6000803e3d6000fd5b50929695505050505050565b6000613d8a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166140e59092919063ffffffff16565b9050805160001480613dab575080806020019051810190613dab9190614b72565b6115aa5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610bf9565b6000826000018281548110613e3457613e34614ba8565b9060005260206000200154905092915050565b6000613e52836140f4565b8015612e235750612e238383614127565b6000612e2383836141c5565b60008181526001830160205260408120548015613f58576000613e93600183614b5f565b8554909150600090613ea790600190614b5f565b9050818114613f0c576000866000018281548110613ec757613ec7614ba8565b9060005260206000200154905080876000018481548110613eea57613eea614ba8565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613f1d57613f1d615015565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610b15565b6000915050610b15565b6000807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613fab577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef81000000008310613fd7576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310613ff557662386f26fc10000830492506010015b6305f5e100831061400d576305f5e100830492506008015b612710831061402157612710830492506004015b60648310614033576064830492506002015b600a8310610b155760010192915050565b6000763d602d80600a3d3981f3363d3d373d3d3d363d730000008260601b60e81c176000526e5af43d82803e903d91602b57fd5bf38260781b17602052603760096000f090506001600160a01b0381166140e05760405162461bcd60e51b815260206004820152601660248201527f455243313136373a20637265617465206661696c6564000000000000000000006044820152606401610bf9565b919050565b6060610cd68484600085614214565b6000614107826301ffc9a760e01b614127565b8015610b155750614120826001600160e01b0319614127565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d915060005190508280156141ae575060208210155b80156141ba5750600081115b979650505050505050565b600081815260018301602052604081205461420c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610b15565b506000610b15565b60608247101561428c5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610bf9565b600080866001600160a01b031685876040516142a8919061502b565b60006040518083038185875af1925050503d80600081146142e5576040519150601f19603f3d011682016040523d82523d6000602084013e6142ea565b606091505b50915091506141ba878383876060831561436557825160000361435e576001600160a01b0385163b61435e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610bf9565b5081610cd6565b610cd6838381511561437a5781518083602001fd5b8060405162461bcd60e51b8152600401610bf99190615047565b6000602082840312156143a657600080fd5b5035919050565b6000602082840312156143bf57600080fd5b81356001600160e01b031981168114612e2357600080fd5b6001600160a01b0381168114610d9a57600080fd5b60008083601f8401126143fe57600080fd5b50813567ffffffffffffffff81111561441657600080fd5b6020830191508360208260051b850101111561443157600080fd5b9250929050565b6000806000806060858703121561444e57600080fd5b843593506020850135614460816143d7565b9250604085013567ffffffffffffffff81111561447c57600080fd5b614488878288016143ec565b95989497509550505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156144d3576144d3614494565b604052919050565b600082601f8301126144ec57600080fd5b813567ffffffffffffffff81111561450657614506614494565b6145196020601f19601f840116016144aa565b81815284602083860101111561452e57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000806080858703121561456157600080fd5b843561456c816143d7565b9350602085013561457c816143d7565b925060408501359150606085013567ffffffffffffffff81111561459f57600080fd5b6145ab878288016144db565b91505092959194509250565b6000806000606084860312156145cc57600080fd5b83356145d7816143d7565b95602085013595506040909401359392505050565b8015158114610d9a57600080fd5b6000806040838503121561460d57600080fd5b8235614618816143d7565b91506020830135614628816145ec565b809150509250929050565b6000806000806060858703121561464957600080fd5b8435614654816143d7565b935060208501359250604085013567ffffffffffffffff81111561447c57600080fd5b600081518084526020808501945080840160005b838110156146a75781518752958201959082019060010161468b565b509495945050505050565b8381526060602082015260006146cb6060830185614677565b8281036040840152611e208185614677565b600080604083850312156146f057600080fd5b50508035926020909101359150565b60006020828403121561471157600080fd5b8135612e23816143d7565b803563ffffffff811681146140e057600080fd5b600060a0828403121561474257600080fd5b60405160a0810181811067ffffffffffffffff8211171561476557614765614494565b6040528235614773816143d7565b81526020830135614783816143d7565b60208201526147946040840161471c565b60408201526147a56060840161471c565b60608201526147b66080840161471c565b60808201529392505050565b6020808252825182820181905260009190848201906040850190845b818110156148555761484283855161ffff8082511683528060208301511660208401528060408301511660408401525060ff606082015116606083015260808101516001600160a01b0380821660808501528060a08401511660a085015250505050565b9284019260c092909201916001016147de565b50909695505050505050565b6000806020838503121561487457600080fd5b823567ffffffffffffffff81111561488b57600080fd5b614897858286016143ec565b90969095509350505050565b6000806000606084860312156148b857600080fd5b83356148c3816143d7565b925060208401356148d3816143d7565b929592945050506040919091013590565b600080604083850312156148f757600080fd5b8235614902816143d7565b915060208381013567ffffffffffffffff8082111561492057600080fd5b818601915086601f83011261493457600080fd5b81358181111561494657614946614494565b8060051b91506149578483016144aa565b818152918301840191848101908984111561497157600080fd5b938501935b8385101561498f57843582529385019390850190614976565b8096505050505050509250929050565b803561ffff811681146140e057600080fd5b60ff81168114610d9a57600080fd5b600060c082840312156149d257600080fd5b60405160c0810181811067ffffffffffffffff821117156149f5576149f5614494565b604052614a018361499f565b8152614a0f6020840161499f565b6020820152614a206040840161499f565b60408201526060830135614a33816149b1565b60608201526080830135614a46816143d7565b608082015260a0830135614a59816143d7565b60a08201529392505050565b600080600080600080600060c0888a031215614a8057600080fd5b8735614a8b816143d7565b96506020880135955060408801359450606088013567ffffffffffffffff80821115614ab657600080fd5b818a0191508a601f830112614aca57600080fd5b813581811115614ad957600080fd5b8b6020828501011115614aeb57600080fd5b6020830196508095505060808a0135935060a08a0135915080821115614b1057600080fd5b50614b1d8a828b016144db565b91505092959891949750929550565b600060208284031215614b3e57600080fd5b8135612e23816145ec565b634e487b7160e01b600052601160045260246000fd5b81810381811115610b1557610b15614b49565b600060208284031215614b8457600080fd5b8151612e23816145ec565b600060208284031215614ba157600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b60006000198203614bd157614bd1614b49565b5060010190565b602081526000612e236020830184614677565b60005b83811015614c06578181015183820152602001614bee565b50506000910152565b60008151808452614c27816020860160208601614beb565b601f01601f19169290920160200192915050565b60006001600160a01b03808b16835289602084015288604084015260e060608401528660e08401526101008789828601376000818986010152601f19601f8901168401876080860152818582030160a0860152614c9a82820188614c0f565b9350505080841660c0840152509998505050505050505050565b805169ffffffffffffffffffff811681146140e057600080fd5b600080600080600060a08688031215614ce657600080fd5b614cef86614cb4565b9450602086015193506040860151925060608601519150614d1260808701614cb4565b90509295509295909350565b600082614d3b57634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417610b1557610b15614b49565b80820180821115610b1557610b15614b49565b600060208284031215614d7c57600080fd5b8151612e23816143d7565b60008151614d99818560208601614beb565b9290920192915050565b600080845481600182811c915080831680614dbf57607f831692505b60208084108203614dde57634e487b7160e01b86526022600452602486fd5b818015614df25760018114614e0757614e34565b60ff1986168952841515850289019650614e34565b60008b81526020902060005b86811015614e2c5781548b820152908501908301614e13565b505084890196505b505050505050614e448185614d87565b95945050505050565b63ffffffff8181168382160190808211156112a8576112a8614b49565b600060208284031215614e7c57600080fd5b8151612e23816149b1565b60c08101610b15828461ffff8082511683528060208301511660208401528060408301511660408401525060ff606082015116606083015260808101516001600160a01b0380821660808501528060a08401511660a085015250505050565b600181815b80851115614f21578160001904821115614f0757614f07614b49565b80851615614f1457918102915b93841c9390800290614eeb565b509250929050565b600082614f3857506001610b15565b81614f4557506000610b15565b8160018114614f5b5760028114614f6557614f81565b6001915050610b15565b60ff841115614f7657614f76614b49565b50506001821b610b15565b5060208310610133831016604e8410600b8410161715614fa4575081810a610b15565b614fae8383614ee6565b8060001904821115614fc257614fc2614b49565b029392505050565b6000612e238383614f29565b606081526000614fe96060830186614c0f565b8281036020840152614ffb8186614c0f565b9150506001600160a01b0383166040830152949350505050565b634e487b7160e01b600052603160045260246000fd5b6000825161503d818460208701614beb565b9190910192915050565b602081526000612e236020830184614c0f56fea26469706673582212201320eaaf730fb43e02f361159e726d6e6bef389dbff7cfa9f76141588b6dbe7164736f6c6343000813003360806040523480156200001157600080fd5b506200001c6200002c565b620000266200002c565b620000ed565b600054610100900460ff1615620000995760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000eb576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b611fba80620000fd6000396000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c8063631b5dfb116100d857806395d89b411161008c578063a9059cbb11610066578063a9059cbb146102fc578063dd62ed3e1461030f578063f77c47911461034857600080fd5b806395d89b41146102d4578063a07c7ce4146102dc578063a457c2d7146102e957600080fd5b806380929e5b116100bd57806380929e5b1461029b578063885d194d146102ae57806390596dd1146102c157600080fd5b8063631b5dfb1461025f57806370a082311461027257600080fd5b80632791834d1161012f5780633950935111610114578063395093511461020e5780633b304147146102215780635d7b07581461024c57600080fd5b80632791834d146101f7578063313ce567146101ff57600080fd5b8063095ea7b311610160578063095ea7b3146101af57806318160ddd146101d257806323b872dd146101e457600080fd5b806306fdde031461017c578063077f224a1461019a575b600080fd5b61018461035b565b6040516101919190611aee565b60405180910390f35b6101ad6101a8366004611bf7565b6103ed565b005b6101c26101bd366004611c6f565b610545565b6040519015158152602001610191565b6035545b604051908152602001610191565b6101c26101f2366004611c9b565b61055f565b6101ad610583565b60405160128152602001610191565b6101c261021c366004611c6f565b6105f3565b61023461022f366004611cdc565b610632565b6040516001600160a01b039091168152602001610191565b6101ad61025a366004611c6f565b610697565b6101ad61026d366004611c9b565b610704565b6101d6610280366004611cf5565b6001600160a01b031660009081526033602052604090205490565b6101ad6102a9366004611d12565b610776565b6101d66102bc366004611cf5565b6107ec565b6101ad6102cf366004611c6f565b610823565b610184610890565b6067546101c29060ff1681565b6101c26102f7366004611c6f565b61089f565b6101c261030a366004611c6f565b610949565b6101d661031d366004611d34565b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b606554610234906001600160a01b031681565b60606036805461036a90611d6d565b80601f016020809104026020016040519081016040528092919081815260200182805461039690611d6d565b80156103e35780601f106103b8576101008083540402835291602001916103e3565b820191906000526020600020905b8154815290600101906020018083116103c657829003601f168201915b5050505050905090565b600054610100900460ff161580801561040d5750600054600160ff909116105b806104275750303b158015610427575060005460ff166001145b61049e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b6000805460ff1916600117905580156104c1576000805461ff0019166101001790555b6104cc848484610957565b6104f960667f785cd364d007a51692c42fd972cf679bcdfc6107829c214da24f12cd06e2d0e16005610a1a565b801561053f576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b600033610553818585610b25565b60019150505b92915050565b60003361056d858285610c7d565b610578858585610d09565b506001949350505050565b60675460ff166105d55760405162461bcd60e51b815260206004820152601060248201527f4e6f74206275726e61626c6520796574000000000000000000000000000000006044820152606401610495565b336000818152603360205260409020546105ef8282610f08565b5050565b3360008181526034602090815260408083206001600160a01b0387168452909152812054909190610553908290869061062d908790611dbd565b610b25565b60008061063e60355490565b905060008160000361065257506000610690565b600061065e858461107f565b905061068c60667f785cd364d007a51692c42fd972cf679bcdfc6107829c214da24f12cd06e2d0e183611139565b9150505b9392505050565b6065546001600160a01b0316336001600160a01b0316146106fa5760405162461bcd60e51b815260206004820152601f60248201527f436f6e74726f6c6c6564546f6b656e2f6f6e6c792d636f6e74726f6c6c6572006044820152606401610495565b6105ef828261123f565b6065546001600160a01b0316336001600160a01b0316146107675760405162461bcd60e51b815260206004820152601f60248201527f436f6e74726f6c6c6564546f6b656e2f6f6e6c792d636f6e74726f6c6c6572006044820152606401610495565b6107718282610f08565b505050565b6065546001600160a01b0316336001600160a01b0316146107d95760405162461bcd60e51b815260206004820152601f60248201527f436f6e74726f6c6c6564546f6b656e2f6f6e6c792d636f6e74726f6c6c6572006044820152606401610495565b6067805460ff1916911515919091179055565b600061055960667f785cd364d007a51692c42fd972cf679bcdfc6107829c214da24f12cd06e2d0e16001600160a01b03851661130c565b6065546001600160a01b0316336001600160a01b0316146108865760405162461bcd60e51b815260206004820152601f60248201527f436f6e74726f6c6c6564546f6b656e2f6f6e6c792d636f6e74726f6c6c6572006044820152606401610495565b6105ef8282610f08565b60606037805461036a90611d6d565b3360008181526034602090815260408083206001600160a01b03871684529091528120549091908381101561093c5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610495565b6105788286868403610b25565b600033610553818585610d09565b600054610100900460ff166109d45760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610495565b6109de8383611364565b606580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03929092169190911790555050565b6000828152602084905260409020805415610a775760405162461bcd60e51b815260206004820152601460248201527f5472656520616c7265616479206578697374732e0000000000000000000000006044820152606401610495565b60018211610ac75760405162461bcd60e51b815260206004820152601b60248201527f4b206d7573742062652067726561746572207468616e206f6e652e00000000006044820152606401610495565b8181556040805160008152602081019182905251610ae9916001840191611a8e565b506040805160008152602081019182905251610b09916002840191611a8e565b5060020180546001810182556000918252602082200155505050565b6001600160a01b038316610ba05760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610495565b6001600160a01b038216610c1c5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610495565b6001600160a01b0383811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b03838116600090815260346020908152604080832093861683529290522054600019811461053f5781811015610cfc5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610495565b61053f8484848403610b25565b6001600160a01b038316610d855760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610495565b6001600160a01b038216610e015760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610495565b610e0c8383836113eb565b6001600160a01b03831660009081526033602052604090205481811015610e9b5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610495565b6001600160a01b0380851660008181526033602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610efb9086815260200190565b60405180910390a361053f565b6001600160a01b038216610f845760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610495565b610f90826000836113eb565b6001600160a01b0382166000908152603360205260409020548181101561101f5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610495565b6001600160a01b03831660008181526033602090815260408083208686039055603580548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b60008082116110d05760405162461bcd60e51b815260206004820152601560248201527f556e69666f726d52616e642f6d696e2d626f756e6400000000000000000000006044820152606401610495565b6000826110df81600019611dd0565b6110ea906001611dbd565b6110f49190611df9565b9050835b81811015611126576040805160208082019390935281518082038401815290820190915280519101206110f8565b6111308482611df9565b95945050505050565b600082815260208490526040812060028101805483918291829061115f5761115f611e0d565b9060005260206000200154856111759190611df9565b90505b6002830154835461118a908490611e23565b611195906001611dbd565b10156112245760015b8354811161121e576000818486600001546111b99190611e23565b6111c39190611dbd565b905060008560020182815481106111dc576111dc611e0d565b90600052602060002001549050808410611201576111fa8185611dd0565b9350611209565b50925061121e565b5050808061121690611e3a565b91505061119e565b50611178565b50600090815260049091016020526040902054949350505050565b6001600160a01b0382166112955760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610495565b6112a1600083836113eb565b80603560008282546112b39190611dbd565b90915550506001600160a01b0382166000818152603360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b60008281526020848152604080832084845260038101909252822054808303611338576000925061135b565b81600201818154811061134d5761134d611e0d565b906000526020600020015492505b50509392505050565b600054610100900460ff166113e15760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610495565b6105ef828261145f565b6113f68383836114f5565b6001600160a01b038316158061141357506001600160a01b038216155b6107715760405162461bcd60e51b815260206004820152601660248201527f5469636b65206e6f74207472616e7366657261626c65000000000000000000006044820152606401610495565b600054610100900460ff166114dc5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610495565b60366114e88382611e9a565b5060376107718282611e9a565b6115008383836115f6565b816001600160a01b0316836001600160a01b03160361151e57505050565b6001600160a01b0383161561158b576001600160a01b038316600090815260336020526040812054611551908390611dd0565b905061158960667f785cd364d007a51692c42fd972cf679bcdfc6107829c214da24f12cd06e2d0e1836001600160a01b038816611682565b505b6001600160a01b03821615610771576001600160a01b0382166000908152603360205260408120546115be908390611dbd565b905061053f60667f785cd364d007a51692c42fd972cf679bcdfc6107829c214da24f12cd06e2d0e1836001600160a01b038716611682565b6065546040517f7cbab1c70000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015284811660248301526044820184905290911690637cbab1c790606401600060405180830381600087803b15801561166557600080fd5b505af1158015611679573d6000803e3d6000fd5b50505050505050565b60008381526020858152604080832084845260038101909252822054909181900361184e57831561184957600182015460000361179b5750600281018054600180820183556000928352602090922081018590559081148015906116fa575081546116ee600183611dd0565b6116f89190611df9565b155b1561179657815460009061170e9083611f5a565b600081815260048501602052604081205491925061172d846001611dbd565b90508460020185600201848154811061174857611748611e0d565b60009182526020808320909101548354600181018555938352818320909301929092559384526004860180825260408086208690558486526003880183528086208490559285529052909120555b611816565b6001808301805490916117ad91611dd0565b815481106117bd576117bd611e0d565b90600052602060002001549050816001018054806117dd576117dd611f6e565b600190038181906000526020600020016000905590558382600201828154811061180957611809611e0d565b6000918252602090912001555b600083815260038301602090815260408083208490558383526004850190915290208390556118498686836001886119d9565b6119d1565b836000036118ee57600082600201828154811061186d5761186d611e0d565b90600052602060002001549050600083600201838154811061189157611891611e0d565b60009182526020808320909101929092556001808601805491820181558252828220018490558581526003850182526040808220829055848252600486019092529081208190556118e890889088908590856119d9565b506119d1565b81600201818154811061190357611903611e0d565b906000526020600020015484146119d15760008483600201838154811061192c5761192c611e0d565b906000526020600020015411159050600081611972578584600201848154811061195857611958611e0d565b906000526020600020015461196d9190611dd0565b61199d565b83600201838154811061198757611987611e0d565b90600052602060002001548661199d9190611dd0565b9050858460020184815481106119b5576119b5611e0d565b6000918252602090912001556119ce88888585856119d9565b50505b505050505050565b6000848152602086905260409020835b80156116795781546119fc600183611dd0565b611a069190611f5a565b905083611a3d5782826002018281548110611a2357611a23611e0d565b9060005260206000200154611a389190611dd0565b611a68565b82826002018281548110611a5357611a53611e0d565b9060005260206000200154611a689190611dbd565b826002018281548110611a7d57611a7d611e0d565b6000918252602090912001556119e9565b828054828255906000526020600020908101928215611ac9579160200282015b82811115611ac9578251825591602001919060010190611aae565b50611ad5929150611ad9565b5090565b5b80821115611ad55760008155600101611ada565b600060208083528351808285015260005b81811015611b1b57858101830151858201604001528201611aff565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112611b6357600080fd5b813567ffffffffffffffff80821115611b7e57611b7e611b3c565b604051601f8301601f19908116603f01168101908282118183101715611ba657611ba6611b3c565b81604052838152866020858801011115611bbf57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6001600160a01b0381168114611bf457600080fd5b50565b600080600060608486031215611c0c57600080fd5b833567ffffffffffffffff80821115611c2457600080fd5b611c3087838801611b52565b94506020860135915080821115611c4657600080fd5b50611c5386828701611b52565b9250506040840135611c6481611bdf565b809150509250925092565b60008060408385031215611c8257600080fd5b8235611c8d81611bdf565b946020939093013593505050565b600080600060608486031215611cb057600080fd5b8335611cbb81611bdf565b92506020840135611ccb81611bdf565b929592945050506040919091013590565b600060208284031215611cee57600080fd5b5035919050565b600060208284031215611d0757600080fd5b813561069081611bdf565b600060208284031215611d2457600080fd5b8135801515811461069057600080fd5b60008060408385031215611d4757600080fd5b8235611d5281611bdf565b91506020830135611d6281611bdf565b809150509250929050565b600181811c90821680611d8157607f821691505b602082108103611da157634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561055957610559611da7565b8181038181111561055957610559611da7565b634e487b7160e01b600052601260045260246000fd5b600082611e0857611e08611de3565b500690565b634e487b7160e01b600052603260045260246000fd5b808202811582820484141761055957610559611da7565b60006000198203611e4d57611e4d611da7565b5060010190565b601f82111561077157600081815260208120601f850160051c81016020861015611e7b5750805b601f850160051c820191505b818110156119d157828155600101611e87565b815167ffffffffffffffff811115611eb457611eb4611b3c565b611ec881611ec28454611d6d565b84611e54565b602080601f831160018114611efd5760008415611ee55750858301515b600019600386901b1c1916600185901b1785556119d1565b600085815260208120601f198616915b82811015611f2c57888601518255948401946001909101908401611f0d565b5085821015611f4a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600082611f6957611f69611de3565b500490565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220decd3853b6f9dc7408f97569a16fbf24d058d5955cc03659b32c600e26e9415a64736f6c63430008130033000000000000000000000000fab0003acc6afefb60e21b77ad788c617c8da7b4000000000000000000000000b3d747fd0d099f09b165fca7c94c0e442b47a5740000000000000000000000001c7e17aabfc4dc27b489629ea0711d2e550edbbb0000000000000000000000000000000000000000000000001bc16d674ec80000000000000000000000000000a827c3cf03ddfbdfde7323323477ae06f13d12cc000000000000000000000000a379597c5aace4da623db6328854be988bec29ac00000000000000000000000000000000000000000000000000000000000002ee00000000000000000000000000000000000000000000000000000000000000fa0000000000000000000000000000000000000000000000000000000000002328000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000e135b22baec73461caea51274c6a705edb5af6fc0000000000000000000000000000000000000000000000000000000000000033506978656c5377656570657220506c61796572506f747633202d204b72656570794d6f6e73746173202d205469636b6574202300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c535750522d5033204b4d20230000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106103125760003560e01c80638456cb591161019a578063b2940d02116100e1578063e5a690f71161008a578063ed0d294e11610064578063ed0d294e14610aa1578063f2fde38b14610ab6578063fbfa77cf14610ad657600080fd5b8063e5a690f714610a41578063ea03a53e14610a61578063ec24720614610a8157600080fd5b8063dfeaa74c116100bb578063dfeaa74c14610977578063e28d1d2e14610997578063e293dcbf14610a2157600080fd5b8063b2940d021461090e578063db2e21bc14610942578063ded983b01461095757600080fd5b80639189a59e116101435780639a08bd1c1161011d5780639a08bd1c146108855780639a19aed1146108a5578063aa58a28c146108da57600080fd5b80639189a59e1461081157806391ca480e1461084557806398bf3eb61461086557600080fd5b80638c65c81f116101745780638c65c81f146107535780638cd221c9146107dd5780638da5cb5b146107f357600080fd5b80638456cb59146106ae5780638a19c8bc146106c35780638baa71811461072357600080fd5b80634cdf9c3e1161025e57806372389a5e116102075780637cbab1c7116101e15780637cbab1c71461060d5780637de1e5361461062d5780638009b7bd1461066157600080fd5b806372389a5e146105ab57806375af65d1146105cb5780637728805e146105ed57600080fd5b80636cc25db7116102385780636cc25db7146105325780636ff1c9bc14610576578063715018a61461059657600080fd5b80634cdf9c3e146104da578063575072c6146104fa5780635c975abb1461051a57600080fd5b8063178c6618116102c05780631fe449311161029a5780631fe449311461047657806323ee2234146104965780633f4ba83a146104c557600080fd5b8063178c6618146103fe57806317a94b57146104185780631e1bff3f1461045657600080fd5b80631209b1f6116102f15780631209b1f61461038f578063150b7a02146103a557806315981650146103de57600080fd5b80629c367c1461031757806301ffc9a71461034a578063104ba8c81461037a575b600080fd5b34801561032357600080fd5b50610337610332366004614394565b610b0a565b6040519081526020015b60405180910390f35b34801561035657600080fd5b5061036a6103653660046143ad565b610b1b565b6040519015158152602001610341565b61038d610388366004614438565b610b9d565b005b34801561039b57600080fd5b50610337600a5481565b3480156103b157600080fd5b506103c56103c036600461454b565b610c24565b6040516001600160e01b03199091168152602001610341565b3480156103ea57600080fd5b5061038d6103f9366004614394565b610cde565b34801561040a57600080fd5b50600f5461036a9060ff1681565b34801561042457600080fd5b506103376104333660046145b7565b600360209081526000938452604080852082529284528284209052825290205481565b34801561046257600080fd5b5061038d6104713660046145fa565b610d22565b34801561048257600080fd5b5061038d610491366004614394565b610d89565b3480156104a257600080fd5b506104b66104b1366004614633565b610d9d565b604051610341939291906146b2565b3480156104d157600080fd5b5061038d610dda565b3480156104e657600080fd5b5061038d6104f53660046146dd565b610f39565b34801561050657600080fd5b5061038d6105153660046146dd565b610faa565b34801561052657600080fd5b5060025460ff1661036a565b34801561053e57600080fd5b506009546000908152600b60205260409020600201546001600160a01b03165b6040516001600160a01b039091168152602001610341565b34801561058257600080fd5b5061038d6105913660046146ff565b611015565b3480156105a257600080fd5b5061038d61112e565b3480156105b757600080fd5b5061038d6105c6366004614730565b611140565b3480156105d757600080fd5b506105e0611151565b60405161034191906147c2565b3480156105f957600080fd5b5061038d610608366004614861565b6112af565b34801561061957600080fd5b5061038d6106283660046148a3565b61140a565b34801561063957600080fd5b5061055e7f0000000000000000000000001c7e17aabfc4dc27b489629ea0711d2e550edbbb81565b34801561066d57600080fd5b5060075461068d906001600160a01b03811690600160a01b900460ff1682565b604080516001600160a01b03909316835260ff909116602083015201610341565b3480156106ba57600080fd5b5061038d6115af565b3480156106cf57600080fd5b506106d86115bf565b6040516103419190600060a08201905082518252602083015160208301526001600160a01b036040840151166040830152606083015160608301526080830151608083015292915050565b34801561072f57600080fd5b5061036a61073e3660046146ff565b600e6020526000908152604090205460ff1681565b34801561075f57600080fd5b506107a761076e366004614394565b600b6020526000908152604090208054600182015460028301546003840154600490940154929391926001600160a01b03909116919085565b6040805195865260208601949094526001600160a01b03909216928401929092526060830191909152608082015260a001610341565b3480156107e957600080fd5b5061033760095481565b3480156107ff57600080fd5b506000546001600160a01b031661055e565b34801561081d57600080fd5b5061055e7f000000000000000000000000b3d747fd0d099f09b165fca7c94c0e442b47a57481565b34801561085157600080fd5b5061038d6108603660046146ff565b611655565b34801561087157600080fd5b5060085461055e906001600160a01b031681565b34801561089157600080fd5b5061038d6108a0366004614394565b61166e565b3480156108b157600080fd5b506108c56108c03660046146ff565b6117c0565b60408051928352602083019190915201610341565b3480156108e657600080fd5b5061036a7f000000000000000000000000000000000000000000000000000000000000000181565b34801561091a57600080fd5b5061055e7f00000000000000000000000069a5784ae89ebbaeac3ede170b6fa921e89e8da381565b34801561094e57600080fd5b5061038d6118ae565b34801561096357600080fd5b50610337610972366004614394565b611947565b34801561098357600080fd5b5061038d6109923660046148e4565b611952565b3480156109a357600080fd5b50600c54600d546109e3916001600160a01b03908116919081169063ffffffff600160a01b8204811691600160c01b8104821691600160e01b9091041685565b604080516001600160a01b03968716815295909416602086015263ffffffff928316938501939093528116606084015216608082015260a001610341565b348015610a2d57600080fd5b5061038d610a3c3660046146ff565b611aa8565b348015610a4d57600080fd5b5061038d610a5c3660046149c0565b611ab9565b348015610a6d57600080fd5b5061038d610a7c366004614a65565b611aca565b348015610a8d57600080fd5b5061038d610a9c366004614b2c565b611c83565b348015610aad57600080fd5b50610337600881565b348015610ac257600080fd5b5061038d610ad13660046146ff565b611ccc565b348015610ae257600080fd5b5061055e7f000000000000000000000000e135b22baec73461caea51274c6a705edb5af6fc81565b6000610b1582611d59565b92915050565b60006001600160e01b031982167f575072c6000000000000000000000000000000000000000000000000000000001480610b7e57506001600160e01b031982167f4cdf9c3e00000000000000000000000000000000000000000000000000000000145b80610b1557506301ffc9a760e01b6001600160e01b0319831614610b15565b6000610bab85858585611e2a565b905080341015610c025760405162461bcd60e51b815260206004820152601760248201527f496e73756666696369656e742066756e64732073656e6400000000000000000060448201526064015b60405180910390fd5b80341115610c1d57610c1d33610c188334614b5f565b611f6a565b5050505050565b6000336001600160a01b037f0000000000000000000000001c7e17aabfc4dc27b489629ea0711d2e550edbbb1614610c9e5760405162461bcd60e51b815260206004820152600f60248201527f4f6e6c7920636f6c6c656374696f6e00000000000000000000000000000000006044820152606401610bf9565b60125460ff16610cb357610cb3836000612083565b507f150b7a02000000000000000000000000000000000000000000000000000000005b949350505050565b610ce6612259565b600a8190556040518181527f34388f2433e2a2e6d6f978efe10bb2784b04bec67ff0eaa768c332c248da5d1d906020015b60405180910390a150565b610d2a612259565b6001600160a01b0382166000818152600e6020908152604091829020805460ff191685151590811790915591519182527f278b09622564dd3991fe7744514513d64ea2c8ed2b2b9ec1150ad964fde80a99910160405180910390a25050565b610d91612259565b610d9a816122b3565b50565b6000606080610dca60095488600b6000600954815260200190815260200160002060010154898989612313565b9250925092509450945094915050565b610de2612259565b7f000000000000000000000000e135b22baec73461caea51274c6a705edb5af6fc6001600160a01b03161580610ee357506008546040517fe985e9c50000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000e135b22baec73461caea51274c6a705edb5af6fc8116600483015291821660248201527f0000000000000000000000001c7e17aabfc4dc27b489629ea0711d2e550edbbb9091169063e985e9c590604401602060405180830381865afa158015610ebf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee39190614b72565b610f2f5760405162461bcd60e51b815260206004820152601e60248201527f73747261746567792d6e6f742d617070726f7665642d62792d7661756c7400006044820152606401610bf9565b610f37612492565b565b6008546001600160a01b0316336001600160a01b031614610f9c5760405162461bcd60e51b815260206004820152601360248201527f6f6e6c79207072697a65207374726174656779000000000000000000000000006044820152606401610bf9565b610fa682826126b2565b5050565b6008546001600160a01b0316336001600160a01b03161461100d5760405162461bcd60e51b815260206004820152601360248201527f6f6e6c79207072697a65207374726174656779000000000000000000000000006044820152606401610bf9565b610fa661284e565b61101d612259565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015611064573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110889190614b8f565b9050806000036110da5760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f74207265636f766572207a65726f2062616c616e636500000000006044820152606401610bf9565b6040518181526001600160a01b0383169033907fda568f14cc33c45f2866f24477f9007a04f029daa19ea7192cf685a53b9b92c89060200160405180910390a3610fa66001600160a01b0383163383612aa9565b611136612259565b610f376000612b29565b611148612259565b610d9a81612b86565b6060600061115f6005612e0d565b905060008167ffffffffffffffff81111561117c5761117c614494565b6040519080825280602002602001820160405280156111dc57816020015b6040805160c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820152825260001990920191018161119a5790505b50905060005b828110156112a857600460006111f9600584612e17565b81526020808201929092526040908101600020815160c081018352815461ffff808216835262010000820481169583019590955264010000000081049094169281019290925260ff660100000000000084041660608301526001600160a01b03670100000000000000909304831660808301526001015490911660a0820152825183908390811061128c5761128c614ba8565b6020026020010181905250806112a190614bbe565b90506111e2565b5092915050565b6012805460ff191660011790556008546001600160a01b03166113145760405162461bcd60e51b815260206004820152600f60248201527f4e6f2073747261746567792073657400000000000000000000000000000000006044820152606401610bf9565b60005b818110156113fb57600083838381811061133357611333614ba8565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015230602482015260209091029290920135604483018190529250506001600160a01b037f0000000000000000000000001c7e17aabfc4dc27b489629ea0711d2e550edbbb16906323b872dd90606401600060405180830381600087803b1580156113c757600080fd5b505af11580156113db573d6000803e3d6000fd5b505050506113ea816000612083565b506113f481614bbe565b9050611317565b50506012805460ff1916905550565b816001600160a01b0316836001600160a01b03160361146b5760405162461bcd60e51b815260206004820152600d60248201527f53656c66207472616e73666572000000000000000000000000000000000000006044820152606401610bf9565b6001600160a01b038316158061148857506001600160a01b038216155b6114d45760405162461bcd60e51b815260206004820152601860248201527f5469636b657473206e6f6e207472616e7366657261626c6500000000000000006044820152606401610bf9565b6008546001600160a01b0316158061155e5750600860009054906101000a90046001600160a01b03166001600160a01b03166330f747ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561153a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155e9190614b72565b6115aa5760405162461bcd60e51b815260206004820152601160248201527f417761726420696e2070726f67726573730000000000000000000000000000006044820152606401610bf9565b505050565b6115b7612259565b610f37612e2a565b6115fa6040518060a00160405280600081526020016000815260200160006001600160a01b0316815260200160008152602001600081525090565b506009546000908152600b6020908152604091829020825160a0810184528154815260018201549281019290925260028101546001600160a01b03169282019290925260038201546060820152600490910154608082015290565b61165d612259565b611665612e84565b610d9a81612ed6565b7f000000000000000000000000e135b22baec73461caea51274c6a705edb5af6fc6001600160a01b0316158015906116ce5750336001600160a01b037f000000000000000000000000e135b22baec73461caea51274c6a705edb5af6fc16145b61171a5760405162461bcd60e51b815260206004820152600a60248201527f6f6e6c792d7661756c74000000000000000000000000000000000000000000006044820152606401610bf9565b60005b81811015610fa657611730600080613138565b60085460405163deeaf11b60e01b81526001600160a01b037f0000000000000000000000001c7e17aabfc4dc27b489629ea0711d2e550edbbb811660048301529091169063deeaf11b90602401600060405180830381600087803b15801561179757600080fd5b505af11580156117ab573d6000803e3d6000fd5b50505050806117b990614bbe565b905061171d565b6009546000908152600b60205260408082206002015490516370a0823160e01b81526001600160a01b0384811660048301528392169081906370a0823190602401602060405180830381865afa15801561181e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118429190614b8f565b9250806001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611882573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118a69190614b8f565b915050915091565b6118b6612259565b4760008190036119085760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f74207265636f766572207a65726f2062616c616e636500000000006044820152606401610bf9565b60405181815233907f5fafa99d0643513820be26656b45130b01e1c03062e1266bf36f88cbd3bd96959060200160405180910390a2610d9a3382611f6a565b6000610b15826131bf565b61195a612259565b80516000036119ab5760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f74207265636f766572207a65726f2062616c616e636500000000006044820152606401610bf9565b816001600160a01b0316336001600160a01b03167f1a42b329ffb74e68eccd569af5123474d5ed15bfab15c94cca5271ed2aa03614836040516119ee9190614bd8565b60405180910390a360005b81518110156115aa57826001600160a01b03166323b872dd3033858581518110611a2557611a25614ba8565b60209081029190910101516040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b158015611a7f57600080fd5b505af1158015611a93573d6000803e3d6000fd5b5050505080611aa190614bbe565b90506119f9565b611ab0612259565b610d9a81613286565b611ac1612259565b610d9a816133b5565b6012805460ff191660011790556001600160a01b038781167f0000000000000000000000001c7e17aabfc4dc27b489629ea0711d2e550edbbb9190911614611b545760405162461bcd60e51b815260206004820152601460248201527f4f6e6c79206d61696e20636f6c6c656374696f6e0000000000000000000000006044820152606401610bf9565b600f5460ff161580611b755750336000908152600e602052604090205460ff165b611bc15760405162461bcd60e51b815260206004820152600e60248201527f4f6e6c79206578656375746f72730000000000000000000000000000000000006044820152606401610bf9565b6040517f75d5da510000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000b3d747fd0d099f09b165fca7c94c0e442b47a57416906375d5da5190611c34908a908a908a908a908a908a908a903090600401614c3b565b600060405180830381600087803b158015611c4e57600080fd5b505af1158015611c62573d6000803e3d6000fd5b50505050611c708686612083565b50506012805460ff191690555050505050565b611c8b612259565b600f805460ff19168215159081179091556040519081527f951a4ddc4870161de6fcd55dea2c9773af92888fc44b7d870d8fca94ec188a6790602001610d17565b611cd4612259565b6001600160a01b038116611d505760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610bf9565b610d9a81612b29565b6040805180820182526007546001600160a01b038116808352600160a01b90910460ff166020830181905283517ffeaf968c00000000000000000000000000000000000000000000000000000000815293516000948591849163feaf968c9160048083019260a09291908290030181865afa158015611ddc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e009190614cce565b505050915050611e208187611e159190614d1e565b60088460ff166136c4565b9695505050505050565b6000611e3461371f565b611e3c613778565b6009546000818152600b60205260409020600101543391611e619183908988886137cb565b6009546000908152600b60205260409020600201549092506001600160a01b031680635d7b075887611e9b8a670de0b6b3a7640000614d40565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015611ee157600080fd5b505af1158015611ef5573d6000803e3d6000fd5b50505050856001600160a01b0316826001600160a01b03166009547f71d54cf57511eea8d601229e41e7d0ed6e13eeac75d51b8f83fa8c7f02aff9808a670de0b6b3a7640000611f459190614d40565b60405190815260200160405180910390a4611f5f836138df565b5050610cd660018055565b80471015611fba5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610bf9565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612007576040519150601f19603f3d011682016040523d82523d6000602084013e61200c565b606091505b50509050806115aa5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610bf9565b61208d8282613138565b6008546001600160a01b03166120e55760405162461bcd60e51b815260206004820152601160248201527f6e6f2d7072697a652d73747261746567790000000000000000000000000000006044820152606401610bf9565b7f000000000000000000000000e135b22baec73461caea51274c6a705edb5af6fc6001600160a01b0316156121d6576040517f42842e0e0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b037f000000000000000000000000e135b22baec73461caea51274c6a705edb5af6fc81166024830152604482018490527f0000000000000000000000001c7e17aabfc4dc27b489629ea0711d2e550edbbb16906342842e0e90606401600060405180830381600087803b1580156121bd57600080fd5b505af11580156121d1573d6000803e3d6000fd5b505050505b60085460405163deeaf11b60e01b81526001600160a01b037f0000000000000000000000001c7e17aabfc4dc27b489629ea0711d2e550edbbb811660048301529091169063deeaf11b90602401600060405180830381600087803b15801561223d57600080fd5b505af1158015612251573d6000803e3d6000fd5b505050505050565b6000546001600160a01b03163314610f375760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610bf9565b6122be6005826139a8565b50600090815260046020526040902080547fffffffffff000000000000000000000000000000000000000000000000000000168155600101805473ffffffffffffffffffffffffffffffffffffffff19169055565b6000606080838067ffffffffffffffff81111561233257612332614494565b60405190808252806020026020018201604052801561235b578160200160208202803683370190505b5092508067ffffffffffffffff81111561237757612377614494565b6040519080825280602002602001820160405280156123a0578160200160208202803683370190505b50915060005b8181101561246e576000806123d48d8d8b8b878181106123c8576123c8614ba8565b905060200201356139b4565b915091506123e2828b613b94565b9150818684815181106123f7576123f7614ba8565b6020026020010181815250508085848151811061241657612416614ba8565b602090810291909101015261242b828b614b5f565b99508161271061243b838e614d40565b6124459190614d1e565b61244f9190614d40565b6124599088614d57565b965050508061246790614bbe565b90506123a6565b506124798789614d40565b6124839085614d57565b93505096509650969350505050565b61249a612259565b6008546001600160a01b03166124f25760405162461bcd60e51b815260206004820152601160248201527f6e6f2d7072697a652d73746172746567790000000000000000000000000000006044820152606401610bf9565b600854604080517fc2f19ee8000000000000000000000000000000000000000000000000000000008152905130926001600160a01b03169163c2f19ee89160048083019260209291908290030181865afa158015612554573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125789190614d6a565b6001600160a01b0316146125ce5760405162461bcd60e51b815260206004820152601960248201527f6e6f742d7365742d61732d61667465722d6c697374656e6572000000000000006044820152606401610bf9565b600854604080517f0d847fc4000000000000000000000000000000000000000000000000000000008152905130926001600160a01b031691630d847fc49160048083019260209291908290030181865afa158015612630573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126549190614d6a565b6001600160a01b0316146126aa5760405162461bcd60e51b815260206004820152601a60248201527f6e6f742d7365742d61732d6265666f72652d6c697374656e65720000000000006044820152606401610bf9565b610f37613baa565b7f000000000000000000000000e135b22baec73461caea51274c6a705edb5af6fc6001600160a01b03166126e4575050565b6040516370a0823160e01b81523060048201526000907f0000000000000000000000001c7e17aabfc4dc27b489629ea0711d2e550edbbb6001600160a01b0316906370a0823190602401602060405180830381865afa15801561274b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061276f9190614b8f565b905060005b81811015612848576001600160a01b037f0000000000000000000000001c7e17aabfc4dc27b489629ea0711d2e550edbbb16632f745c5930836127b8600187614b5f565b6127c29190614b5f565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa925050508015612827575060408051601f3d908101601f1916820190925261282491810190614b8f565b60015b1561284857612837816000612083565b5061284181614bbe565b9050612774565b50505050565b6009546000908152600b60205260408120600201546001600160a01b0316907f000000000000000000000000000000000000000000000000000000000000000180156128a257506001600160a01b03821615155b80156128c057506009546000908152600b6020526040902060040154155b9050801580156128d857506001600160a01b03821615155b156129cb57816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561291b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061293f9190614b8f565b6009546000908152600b60205260409081902060030191909155517f80929e5b000000000000000000000000000000000000000000000000000000008152600160048201526001600160a01b038316906380929e5b90602401600060405180830381600087803b1580156129b257600080fd5b505af11580156129c6573d6000803e3d6000fd5b505050505b80610fa6576000600b60006009600081546129e590614bbe565b919050819055815260200190815260200160002090506000612a08600954613be3565b90506000601082604051602001612a20929190614da3565b60405160208183030381529060405290506000601183604051602001612a47929190614da3565b60405160208183030381529060405290506000612a648383613c83565b60028601805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055505060095483555050600a546001909101555050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526115aa908490613d35565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612710816060015182604001518360800151612ba29190614e4d565b612bac9190614e4d565b63ffffffff1614612bff5760405162461bcd60e51b815260206004820152600d60248201527f496e76616c69642053706c6974000000000000000000000000000000000000006044820152606401610bf9565b80516001600160a01b0316612c565760405162461bcd60e51b815260206004820152601460248201527f496e76616c69642066756e6420616464726573730000000000000000000000006044820152606401610bf9565b60208101516001600160a01b0316612cb05760405162461bcd60e51b815260206004820152601460248201527f496e76616c69642066756e6420616464726573730000000000000000000000006044820152606401610bf9565b7f6430fee6dee986056638c4e4129ff4b5374d0d4d58d43ce042c0c4e84bcb6cec81604051612d2f9190600060a0820190506001600160a01b0380845116835280602085015116602084015250604083015163ffffffff8082166040850152806060860151166060850152806080860151166080850152505092915050565b60405180910390a18051600c805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b039283161790556020820151600d805460408501516060860151608090960151939094167fffffffffffffffff00000000000000000000000000000000000000000000000090911617600160a01b63ffffffff948516021777ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b948416949094027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1693909317600160e01b9290911691909102179055565b6000610b15825490565b6000612e238383613e1d565b9392505050565b612e32613778565b6002805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612e673390565b6040516001600160a01b03909116815260200160405180910390a1565b60025460ff16610f375760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610bf9565b6001600160a01b038116612f2c5760405162461bcd60e51b815260206004820152601660248201527f7072697a6553747261746567792d6e6f742d7a65726f000000000000000000006044820152606401610bf9565b612f466001600160a01b03821663deeaf11b60e01b613e47565b612f925760405162461bcd60e51b815260206004820152601560248201527f7072697a6553747261746567792d696e76616c696400000000000000000000006044820152606401610bf9565b6008546001600160a01b031615613044576008546040517fa22cb4650000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152600060248201527f0000000000000000000000001c7e17aabfc4dc27b489629ea0711d2e550edbbb9091169063a22cb46590604401600060405180830381600087803b15801561302b57600080fd5b505af115801561303f573d6000803e3d6000fd5b505050505b6040517fa22cb4650000000000000000000000000000000000000000000000000000000081526001600160a01b038281166004830152600160248301527f0000000000000000000000001c7e17aabfc4dc27b489629ea0711d2e550edbbb169063a22cb46590604401600060405180830381600087803b1580156130c757600080fd5b505af11580156130db573d6000803e3d6000fd5b50506008805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385169081179091556040519092507f7f58dc86bc2e435cb77ca0edb1df55e25f90caf2d6bd866971715437d456a2129150600090a250565b6009546000908152600b6020526040812060040180546001929061315d908490614d57565b90915550506009546000908152600b6020908152604091829020600401548251858152918201849052918101919091527fcd9a7360c57fb4628e98193b7a9e651d55b1fe0dbe62ad9547a0390cd1dab713906060015b60405180910390a15050565b6040805180820182526007546001600160a01b038116808352600160a01b90910460ff166020830181905283517ffeaf968c00000000000000000000000000000000000000000000000000000000815293516000948591849163feaf968c9160048083019260a09291908290030181865afa158015613242573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132669190614cce565b505050915050611e20818761327b9190614d40565b8360ff1660086136c4565b6001600160a01b0381166132c6576040517ffaf6a7a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613306573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061332a9190614e6a565b6040805180820182526001600160a01b03851680825260ff84166020928301819052600780547fffffffffffffffffffffff000000000000000000000000000000000000000000168317600160a01b83021790558351918252918101919091529192507f8deb401a943ebaf5b5b213be8b61e720c24de99752ca0e593386d5b330e7973d91016131b3565b8051602082015160408301516060840151608085015161232861ffff851610156134215760405162461bcd60e51b815260206004820152601760248201527f496e76616c696420646973636f756e7420666163746f720000000000000000006044820152606401610bf9565b60008361ffff16116134755760405162461bcd60e51b815260206004820152601860248201527f496e76616c696420646973636f756e74207469636b65747300000000000000006044820152606401610bf9565b6001600160a01b0381166134cb5760405162461bcd60e51b815260206004820152601360248201527f496e76616c696420636f6c6c656374696f6e31000000000000000000000000006044820152606401610bf9565b8160ff16600114806134f757508160ff1660021480156134f7575060a08601516001600160a01b031615155b6135435760405162461bcd60e51b815260206004820152601360248201527f496e76616c696420636f6c6c656374696f6e73000000000000000000000000006044820152606401610bf9565b61ffff8516613553600582613e63565b5060008181526004602090815260409182902089518154928b01518b85015160608d015160808e015161ffff9485167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000909716969096176201000093851693909302929092177fffffffffffffffffffffffffffffffffffffffffffffffffff000000ffffffff1664010000000093909116929092027fffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffff1691909117660100000000000060ff90921691909102177fffffffffff0000000000000000000000000000000000000000ffffffffffffff166701000000000000006001600160a01b039384160217815560a08a01516001909101805473ffffffffffffffffffffffffffffffffffffffff191691909216179055517fbd578e2dcec99bbaa454fe5206b66b738d0b3b33a0c9c2e1a28ac8024926631f906136b3908990614e87565b60405180910390a150505050505050565b6000818314613717578183116136f8576136de8383614b5f565b6136e990600a614fca565b6136f39085614d40565b610cd6565b6137028284614b5f565b61370d90600a614fca565b6136f39085614d1e565b509192915050565b6002600154036137715760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610bf9565b6002600155565b60025460ff1615610f375760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610bf9565b600081815b818110156138be5760008585838181106137ec576137ec614ba8565b9050602002013590506000806138038c8c856139b4565b91509150613811828a613b94565b915081600360008d6001600160a01b03166001600160a01b0316815260200190815260200160002060008e81526020019081526020016000206000858152602001908152602001600020600082825461386a9190614d57565b9091555061387a9050828a614b5f565b98508161271061388a838d614d40565b6138949190614d1e565b61389e9190614d40565b6138a89087614d57565b9550505050806138b790614bbe565b90506137d0565b506138c98587614d40565b6138d39083614d57565b98975050505050505050565b600c54600d546001600160a01b039182169181169063ffffffff600160c01b8204811691600160e01b900416600061271061391a8388614d40565b6139249190614d1e565b9050600061271061393b63ffffffff861689614d40565b6139459190614d1e565b9050600081613954848a614b5f565b61395e9190614b5f565b905061398a7f00000000000000000000000069a5784ae89ebbaeac3ede170b6fa921e89e8da384611f6a565b6139948782611f6a565b61399e8683611f6a565b5050505050505050565b6000612e238383613e6f565b6000818152600460208181526040808420815160c081018352815461ffff8082168352620100008204811695830186905264010000000082041682850181905260ff6601000000000000830416606084018190526001600160a01b03670100000000000000909304831660808501819052600190950154831660a085015294516370a0823160e01b8152918a16968201969096528695919493919290869082906370a0823190602401602060405180830381865afa158015613a7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a9e9190614b8f565b90508260ff16600203613b285760a08601516040516370a0823160e01b81526001600160a01b038c81166004830152613b259284929116906370a0823190602401602060405180830381865afa158015613afc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b209190614b8f565b613b94565b90505b6001600160a01b038a1660009081526003602090815260408083208e845282528083208c8452909152902054613b6261ffff861683614d40565b9850888111613b7a57613b75818a614b5f565b613b7d565b60005b9c61ffff9096169b50949950505050505050505050565b6000818310613ba35781612e23565b5090919050565b613bb2612e84565b6002805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33612e67565b60606000613bf083613f62565b600101905060008167ffffffffffffffff811115613c1057613c10614494565b6040519080825280601f01601f191660200182016040528015613c3a576020820181803683370190505b5090508181016020015b600019017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8504945084613c4457509392505050565b600080613caf7f00000000000000000000000049218911822c894e0b2c324d7c56245fee24193b614044565b6040517f077f224a0000000000000000000000000000000000000000000000000000000081529091506001600160a01b0382169063077f224a90613cfb90879087903090600401614fd6565b600060405180830381600087803b158015613d1557600080fd5b505af1158015613d29573d6000803e3d6000fd5b50929695505050505050565b6000613d8a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166140e59092919063ffffffff16565b9050805160001480613dab575080806020019051810190613dab9190614b72565b6115aa5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610bf9565b6000826000018281548110613e3457613e34614ba8565b9060005260206000200154905092915050565b6000613e52836140f4565b8015612e235750612e238383614127565b6000612e2383836141c5565b60008181526001830160205260408120548015613f58576000613e93600183614b5f565b8554909150600090613ea790600190614b5f565b9050818114613f0c576000866000018281548110613ec757613ec7614ba8565b9060005260206000200154905080876000018481548110613eea57613eea614ba8565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613f1d57613f1d615015565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610b15565b6000915050610b15565b6000807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613fab577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef81000000008310613fd7576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310613ff557662386f26fc10000830492506010015b6305f5e100831061400d576305f5e100830492506008015b612710831061402157612710830492506004015b60648310614033576064830492506002015b600a8310610b155760010192915050565b6000763d602d80600a3d3981f3363d3d373d3d3d363d730000008260601b60e81c176000526e5af43d82803e903d91602b57fd5bf38260781b17602052603760096000f090506001600160a01b0381166140e05760405162461bcd60e51b815260206004820152601660248201527f455243313136373a20637265617465206661696c6564000000000000000000006044820152606401610bf9565b919050565b6060610cd68484600085614214565b6000614107826301ffc9a760e01b614127565b8015610b155750614120826001600160e01b0319614127565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d915060005190508280156141ae575060208210155b80156141ba5750600081115b979650505050505050565b600081815260018301602052604081205461420c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610b15565b506000610b15565b60608247101561428c5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610bf9565b600080866001600160a01b031685876040516142a8919061502b565b60006040518083038185875af1925050503d80600081146142e5576040519150601f19603f3d011682016040523d82523d6000602084013e6142ea565b606091505b50915091506141ba878383876060831561436557825160000361435e576001600160a01b0385163b61435e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610bf9565b5081610cd6565b610cd6838381511561437a5781518083602001fd5b8060405162461bcd60e51b8152600401610bf99190615047565b6000602082840312156143a657600080fd5b5035919050565b6000602082840312156143bf57600080fd5b81356001600160e01b031981168114612e2357600080fd5b6001600160a01b0381168114610d9a57600080fd5b60008083601f8401126143fe57600080fd5b50813567ffffffffffffffff81111561441657600080fd5b6020830191508360208260051b850101111561443157600080fd5b9250929050565b6000806000806060858703121561444e57600080fd5b843593506020850135614460816143d7565b9250604085013567ffffffffffffffff81111561447c57600080fd5b614488878288016143ec565b95989497509550505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156144d3576144d3614494565b604052919050565b600082601f8301126144ec57600080fd5b813567ffffffffffffffff81111561450657614506614494565b6145196020601f19601f840116016144aa565b81815284602083860101111561452e57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000806080858703121561456157600080fd5b843561456c816143d7565b9350602085013561457c816143d7565b925060408501359150606085013567ffffffffffffffff81111561459f57600080fd5b6145ab878288016144db565b91505092959194509250565b6000806000606084860312156145cc57600080fd5b83356145d7816143d7565b95602085013595506040909401359392505050565b8015158114610d9a57600080fd5b6000806040838503121561460d57600080fd5b8235614618816143d7565b91506020830135614628816145ec565b809150509250929050565b6000806000806060858703121561464957600080fd5b8435614654816143d7565b935060208501359250604085013567ffffffffffffffff81111561447c57600080fd5b600081518084526020808501945080840160005b838110156146a75781518752958201959082019060010161468b565b509495945050505050565b8381526060602082015260006146cb6060830185614677565b8281036040840152611e208185614677565b600080604083850312156146f057600080fd5b50508035926020909101359150565b60006020828403121561471157600080fd5b8135612e23816143d7565b803563ffffffff811681146140e057600080fd5b600060a0828403121561474257600080fd5b60405160a0810181811067ffffffffffffffff8211171561476557614765614494565b6040528235614773816143d7565b81526020830135614783816143d7565b60208201526147946040840161471c565b60408201526147a56060840161471c565b60608201526147b66080840161471c565b60808201529392505050565b6020808252825182820181905260009190848201906040850190845b818110156148555761484283855161ffff8082511683528060208301511660208401528060408301511660408401525060ff606082015116606083015260808101516001600160a01b0380821660808501528060a08401511660a085015250505050565b9284019260c092909201916001016147de565b50909695505050505050565b6000806020838503121561487457600080fd5b823567ffffffffffffffff81111561488b57600080fd5b614897858286016143ec565b90969095509350505050565b6000806000606084860312156148b857600080fd5b83356148c3816143d7565b925060208401356148d3816143d7565b929592945050506040919091013590565b600080604083850312156148f757600080fd5b8235614902816143d7565b915060208381013567ffffffffffffffff8082111561492057600080fd5b818601915086601f83011261493457600080fd5b81358181111561494657614946614494565b8060051b91506149578483016144aa565b818152918301840191848101908984111561497157600080fd5b938501935b8385101561498f57843582529385019390850190614976565b8096505050505050509250929050565b803561ffff811681146140e057600080fd5b60ff81168114610d9a57600080fd5b600060c082840312156149d257600080fd5b60405160c0810181811067ffffffffffffffff821117156149f5576149f5614494565b604052614a018361499f565b8152614a0f6020840161499f565b6020820152614a206040840161499f565b60408201526060830135614a33816149b1565b60608201526080830135614a46816143d7565b608082015260a0830135614a59816143d7565b60a08201529392505050565b600080600080600080600060c0888a031215614a8057600080fd5b8735614a8b816143d7565b96506020880135955060408801359450606088013567ffffffffffffffff80821115614ab657600080fd5b818a0191508a601f830112614aca57600080fd5b813581811115614ad957600080fd5b8b6020828501011115614aeb57600080fd5b6020830196508095505060808a0135935060a08a0135915080821115614b1057600080fd5b50614b1d8a828b016144db565b91505092959891949750929550565b600060208284031215614b3e57600080fd5b8135612e23816145ec565b634e487b7160e01b600052601160045260246000fd5b81810381811115610b1557610b15614b49565b600060208284031215614b8457600080fd5b8151612e23816145ec565b600060208284031215614ba157600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b60006000198203614bd157614bd1614b49565b5060010190565b602081526000612e236020830184614677565b60005b83811015614c06578181015183820152602001614bee565b50506000910152565b60008151808452614c27816020860160208601614beb565b601f01601f19169290920160200192915050565b60006001600160a01b03808b16835289602084015288604084015260e060608401528660e08401526101008789828601376000818986010152601f19601f8901168401876080860152818582030160a0860152614c9a82820188614c0f565b9350505080841660c0840152509998505050505050505050565b805169ffffffffffffffffffff811681146140e057600080fd5b600080600080600060a08688031215614ce657600080fd5b614cef86614cb4565b9450602086015193506040860151925060608601519150614d1260808701614cb4565b90509295509295909350565b600082614d3b57634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417610b1557610b15614b49565b80820180821115610b1557610b15614b49565b600060208284031215614d7c57600080fd5b8151612e23816143d7565b60008151614d99818560208601614beb565b9290920192915050565b600080845481600182811c915080831680614dbf57607f831692505b60208084108203614dde57634e487b7160e01b86526022600452602486fd5b818015614df25760018114614e0757614e34565b60ff1986168952841515850289019650614e34565b60008b81526020902060005b86811015614e2c5781548b820152908501908301614e13565b505084890196505b505050505050614e448185614d87565b95945050505050565b63ffffffff8181168382160190808211156112a8576112a8614b49565b600060208284031215614e7c57600080fd5b8151612e23816149b1565b60c08101610b15828461ffff8082511683528060208301511660208401528060408301511660408401525060ff606082015116606083015260808101516001600160a01b0380821660808501528060a08401511660a085015250505050565b600181815b80851115614f21578160001904821115614f0757614f07614b49565b80851615614f1457918102915b93841c9390800290614eeb565b509250929050565b600082614f3857506001610b15565b81614f4557506000610b15565b8160018114614f5b5760028114614f6557614f81565b6001915050610b15565b60ff841115614f7657614f76614b49565b50506001821b610b15565b5060208310610133831016604e8410600b8410161715614fa4575081810a610b15565b614fae8383614ee6565b8060001904821115614fc257614fc2614b49565b029392505050565b6000612e238383614f29565b606081526000614fe96060830186614c0f565b8281036020840152614ffb8186614c0f565b9150506001600160a01b0383166040830152949350505050565b634e487b7160e01b600052603160045260246000fd5b6000825161503d818460208701614beb565b9190910192915050565b602081526000612e236020830184614c0f56fea26469706673582212201320eaaf730fb43e02f361159e726d6e6bef389dbff7cfa9f76141588b6dbe7164736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000fab0003acc6afefb60e21b77ad788c617c8da7b4000000000000000000000000b3d747fd0d099f09b165fca7c94c0e442b47a5740000000000000000000000001c7e17aabfc4dc27b489629ea0711d2e550edbbb0000000000000000000000000000000000000000000000001bc16d674ec80000000000000000000000000000a827c3cf03ddfbdfde7323323477ae06f13d12cc000000000000000000000000a379597c5aace4da623db6328854be988bec29ac00000000000000000000000000000000000000000000000000000000000002ee00000000000000000000000000000000000000000000000000000000000000fa0000000000000000000000000000000000000000000000000000000000002328000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000e135b22baec73461caea51274c6a705edb5af6fc0000000000000000000000000000000000000000000000000000000000000033506978656c5377656570657220506c61796572506f747633202d204b72656570794d6f6e73746173202d205469636b6574202300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c535750522d5033204b4d20230000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _owner (address): 0xFab0003aCc6AFeFB60E21b77AD788c617c8dA7b4
Arg [1] : _sweeper (address): 0xB3d747FD0D099f09B165Fca7c94c0E442b47a574
Arg [2] : _collection (address): 0x1c7E17aABFC4Dc27b489629eA0711D2e550EDBBB
Arg [3] : _ticketPrice (uint256): 2000000000000000000
Arg [4] : _fundConfig (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
Arg [5] : _ticketsRollOver (bool): True
Arg [6] : _ticketNamePrefix (string): PixelSweeper PlayerPotv3 - KreepyMonstas - Ticket #
Arg [7] : _ticketSymbolPrefix (string): SWPR-P3 KM #
Arg [8] : _vault (address): 0xe135b22baec73461caEa51274c6A705eDb5AF6FC
-----Encoded View---------------
18 Constructor Arguments found :
Arg [0] : 000000000000000000000000fab0003acc6afefb60e21b77ad788c617c8da7b4
Arg [1] : 000000000000000000000000b3d747fd0d099f09b165fca7c94c0e442b47a574
Arg [2] : 0000000000000000000000001c7e17aabfc4dc27b489629ea0711d2e550edbbb
Arg [3] : 0000000000000000000000000000000000000000000000001bc16d674ec80000
Arg [4] : 000000000000000000000000a827c3cf03ddfbdfde7323323477ae06f13d12cc
Arg [5] : 000000000000000000000000a379597c5aace4da623db6328854be988bec29ac
Arg [6] : 00000000000000000000000000000000000000000000000000000000000002ee
Arg [7] : 00000000000000000000000000000000000000000000000000000000000000fa
Arg [8] : 0000000000000000000000000000000000000000000000000000000000002328
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [10] : 00000000000000000000000000000000000000000000000000000000000001a0
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000200
Arg [12] : 000000000000000000000000e135b22baec73461caea51274c6a705edb5af6fc
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000033
Arg [14] : 506978656c5377656570657220506c61796572506f747633202d204b72656570
Arg [15] : 794d6f6e73746173202d205469636b6574202300000000000000000000000000
Arg [16] : 000000000000000000000000000000000000000000000000000000000000000c
Arg [17] : 535750522d5033204b4d20230000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
355:3441:32:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;574:115:34;;;;;;;;;;-1:-1:-1;574:115:34;;;;;:::i;:::-;;:::i;:::-;;;345:25:51;;;333:2;318:18;574:115:34;;;;;;;;12109:342:33;;;;;;;;;;-1:-1:-1;12109:342:33;;;;;:::i;:::-;;:::i;:::-;;;883:14:51;;876:22;858:41;;846:2;831:18;12109:342:33;718:187:51;1407:386:32;;;;;;:::i;:::-;;:::i;:::-;;4020:26:33;;;;;;;;;;;;;;;;12457:351;;;;;;;;;;-1:-1:-1;12457:351:33;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;;4040:79:51;;;4022:98;;4010:2;3995:18;12457:351:33;3878:248:51;9436:151:33;;;;;;;;;;-1:-1:-1;9436:151:33;;;;;:::i;:::-;;:::i;4289:25::-;;;;;;;;;;-1:-1:-1;4289:25:33;;;;;;;;621:125:31;;;;;;;;;;-1:-1:-1;621:125:31;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8766:199:33;;;;;;;;;;-1:-1:-1;8766:199:33;;;;;:::i;:::-;;:::i;10840:91::-;;;;;;;;;;-1:-1:-1;10840:91:33;;;;;:::i;:::-;;:::i;11594:509::-;;;;;;;;;;-1:-1:-1;11594:509:33;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;1902:228:32:-;;;;;;;;;;;;;:::i;7701:252:33:-;;;;;;;;;;-1:-1:-1;7701:252:33;;;;;:::i;:::-;;:::i;8019:183::-;;;;;;;;;;-1:-1:-1;8019:183:33;;;;;:::i;:::-;;:::i;1615:84:9:-;;;;;;;;;;-1:-1:-1;1685:7:9;;;;1615:84;;11483:105:33;;;;;;;;;;-1:-1:-1;11566:7:33;;11533;11559:15;;;:6;:15;;;;;:22;;;-1:-1:-1;;;;;11559:22:33;11483:105;;;-1:-1:-1;;;;;7088:55:51;;;7070:74;;7058:2;7043:18;11483:105:33;6908:242:51;1433:332:49;;;;;;;;;;-1:-1:-1;1433:332:49;;;;;:::i;:::-;;:::i;1824:101:7:-;;;;;;;;;;;;;:::i;8363:117:33:-;;;;;;;;;;-1:-1:-1;8363:117:33;;;;;:::i;:::-;;:::i;901:325:31:-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;5695:460:33:-;;;;;;;;;;-1:-1:-1;5695:460:33;;;;;:::i;:::-;;:::i;7062:453::-;;;;;;;;;;-1:-1:-1;7062:453:33;;;;;:::i;:::-;;:::i;3460:35::-;;;;;;;;;;;;;;;419:27:34;;;;;;;;;;-1:-1:-1;419:27:34;;;;-1:-1:-1;;;;;419:27:34;;;-1:-1:-1;;;419:27:34;;;;;;;;;;-1:-1:-1;;;;;11062:55:51;;;11044:74;;11166:4;11154:17;;;11149:2;11134:18;;11127:45;11017:18;419:27:34;10874:304:51;9965:61:33;;;;;;;;;;;;;:::i;11377:100::-;;;;;;;;;;;;;:::i;:::-;;;;;;11321:4:51;11363:3;11352:9;11348:19;11340:27;;11400:6;11394:13;11383:9;11376:32;11464:4;11456:6;11452:17;11446:24;11439:4;11428:9;11424:20;11417:54;-1:-1:-1;;;;;11531:4:51;11523:6;11519:17;11513:24;11509:73;11502:4;11491:9;11487:20;11480:103;11639:4;11631:6;11627:17;11621:24;11614:4;11603:9;11599:20;11592:54;11702:4;11694:6;11690:17;11684:24;11677:4;11666:9;11662:20;11655:54;11183:532;;;;;4240:43:33;;;;;;;;;;-1:-1:-1;4240:43:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;4105:39;;;;;;;;;;-1:-1:-1;4105:39:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;4105:39:33;;;;;;;;;;;12002:25:51;;;12058:2;12043:18;;12036:34;;;;-1:-1:-1;;;;;12106:55:51;;;12086:18;;;12079:83;;;;12193:2;12178:18;;12171:34;;;;12236:3;12221:19;;12214:35;11989:3;11974:19;4105:39:33;11720:535:51;3950:22:33;;;;;;;;;;;;;;;;1201:85:7;;;;;;;;;;-1:-1:-1;1247:7:7;1273:6;-1:-1:-1;;;;;1273:6:7;1201:85;;3764:42:33;;;;;;;;;;;;;;;9112:166;;;;;;;;;;-1:-1:-1;9112:166:33;;;;;:::i;:::-;;:::i;3667:50::-;;;;;;;;;;-1:-1:-1;3667:50:33;;;;-1:-1:-1;;;;;3667:50:33;;;2295:281:32;;;;;;;;;;-1:-1:-1;2295:281:32;;;;;:::i;:::-;;:::i;11098:273:33:-;;;;;;;;;;-1:-1:-1;11098:273:33;;;;;:::i;:::-;;:::i;:::-;;;;13251:25:51;;;13307:2;13292:18;;13285:34;;;;13224:18;11098:273:33;13077:248:51;3502:37:33;;;;;;;;;;;;;;;3875:38;;;;;;;;;;;;;;;1883:277:49;;;;;;;;;;;;;:::i;453:115:34:-;;;;;;;;;;-1:-1:-1;453:115:34;;;;;:::i;:::-;;:::i;881:397:49:-;;;;;;;;;;-1:-1:-1;881:397:49;;;;;:::i;:::-;;:::i;4205:28:33:-;;;;;;;;;;-1:-1:-1;4205:28:33;;;;;;-1:-1:-1;;;;;4205:28:33;;;;;;;;;-1:-1:-1;;;4205:28:33;;;;;-1:-1:-1;;;4205:28:33;;;;;-1:-1:-1;;;4205:28:33;;;;;;;;;;-1:-1:-1;;;;;14748:15:51;;;14730:34;;14800:15;;;;14795:2;14780:18;;14773:43;14835:10;14881:15;;;14861:18;;;14854:43;;;;14933:15;;14928:2;14913:18;;14906:43;14986:15;14980:3;14965:19;;14958:44;14656:3;14641:19;4205:28:33;14416:592:51;9715:98:33;;;;;;;;;;-1:-1:-1;9715:98:33;;;;;:::i;:::-;;:::i;10650:111::-;;;;;;;;;;-1:-1:-1;10650:111:33;;;;;:::i;:::-;;:::i;6313:605::-;;;;;;;;;;-1:-1:-1;6313:605:33;;;;;:::i;:::-;;:::i;8551:160::-;;;;;;;;;;-1:-1:-1;8551:160:33;;;;;:::i;:::-;;:::i;369:44:34:-;;;;;;;;;;;;412:1;369:44;;2074:198:7;;;;;;;;;;-1:-1:-1;2074:198:7;;;;;:::i;:::-;;:::i;426:30:32:-;;;;;;;;;;;;;;;574:115:34;635:7;661:21;676:5;661:14;:21::i;:::-;654:28;574:115;-1:-1:-1;;574:115:34:o;12109:342:33:-;12225:4;-1:-1:-1;;;;;;12260:63:33;;12275:48;12260:63;;:132;;-1:-1:-1;;;;;;;12339:53:33;;12354:38;12339:53;12260:132;:184;;;-1:-1:-1;;;;;;;;;;937:40:23;;;12408:36:33;829:155:23;1407:386:32;1551:12;1566:43;1578:6;1586:9;1597:11;;1566;:43::i;:::-;1551:58;;1641:4;1628:9;:17;;1620:53;;;;-1:-1:-1;;;1620:53:32;;17892:2:51;1620:53:32;;;17874:21:51;17931:2;17911:18;;;17904:30;17970:25;17950:18;;;17943:53;18013:18;;1620:53:32;;;;;;;;;1700:4;1688:9;:16;1684:103;;;1720:56;1746:10;1759:16;1771:4;1759:9;:16;:::i;:::-;1720:17;:56::i;:::-;1541:252;1407:386;;;;:::o;12457:351:33:-;12603:6;12629:10;-1:-1:-1;;;;;12643:10:33;12629:24;;12621:52;;;;-1:-1:-1;;;12621:52:33;;18566:2:51;12621:52:33;;;18548:21:51;18605:2;18585:18;;;18578:30;18644:17;18624:18;;;18617:45;18679:18;;12621:52:33;18364:339:51;12621:52:33;12689:17;;;;12684:70;;12722:21;12732:7;12741:1;12722:9;:21::i;:::-;-1:-1:-1;12771:30:33;12457:351;;;;;;;:::o;9436:151::-;1094:13:7;:11;:13::i;:::-;9511:11:33::1;:26:::0;;;9552:28:::1;::::0;345:25:51;;;9552:28:33::1;::::0;333:2:51;318:18;9552:28:33::1;;;;;;;;9436:151:::0;:::o;8766:199::-;1094:13:7;:11;:13::i;:::-;-1:-1:-1;;;;;8874:21:33;::::1;;::::0;;;:11:::1;:21;::::0;;;;;;;;:35;;-1:-1:-1;;8874:35:33::1;::::0;::::1;;::::0;;::::1;::::0;;;8924:34;;858:41:51;;;8924:34:33::1;::::0;831:18:51;8924:34:33::1;;;;;;;8766:199:::0;;:::o;10840:91::-;1094:13:7;:11;:13::i;:::-;10905:19:33::1;10921:2;10905:15;:19::i;:::-;10840:91:::0;:::o;11594:509::-;11770:12;11796:35;11845:32;11921:175;11954:7;;11979:4;12001:6;:15;12008:7;;12001:15;;;;;;;;;;;:27;;;12046:7;12071:11;;11921:15;:175::i;:::-;11902:194;;;;;;11594:509;;;;;;;;:::o;1902:228:32:-;1094:13:7;:11;:13::i;:::-;1973:5:32::1;-1:-1:-1::0;;;;;1973:19:32::1;::::0;;:90:::1;;-1:-1:-1::0;2048:13:32::1;::::0;1996:67:::1;::::0;;;;-1:-1:-1;;;;;2033:5:32::1;18961:15:51::0;;1996:67:32::1;::::0;::::1;18943:34:51::0;2048:13:32;;::::1;18993:18:51::0;;;18986:43;2004:10:32::1;1996:36:::0;;::::1;::::0;::::1;::::0;18855:18:51;;1996:67:32::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1965:133;;;::::0;-1:-1:-1;;;1965:133:32;;19492:2:51;1965:133:32::1;::::0;::::1;19474:21:51::0;19531:2;19511:18;;;19504:30;19570:32;19550:18;;;19543:60;19620:18;;1965:133:32::1;19290:354:51::0;1965:133:32::1;2108:15;:13;:15::i;:::-;1902:228::o:0;7701:252:33:-;7843:13;;-1:-1:-1;;;;;7843:13:33;719:10:21;-1:-1:-1;;;;;7819:38:33;;7811:70;;;;-1:-1:-1;;;7811:70:33;;19851:2:51;7811:70:33;;;19833:21:51;19890:2;19870:18;;;19863:30;19929:21;19909:18;;;19902:49;19968:18;;7811:70:33;19649:343:51;7811:70:33;7891:55;7913:12;7927:18;7891:21;:55::i;:::-;7701:252;;:::o;8019:183::-;8128:13;;-1:-1:-1;;;;;8128:13:33;719:10:21;-1:-1:-1;;;;;8104:38:33;;8096:70;;;;-1:-1:-1;;;8096:70:33;;19851:2:51;8096:70:33;;;19833:21:51;19890:2;19870:18;;;19863:30;19929:21;19909:18;;;19902:49;19968:18;;8096:70:33;19649:343:51;8096:70:33;8176:19;:17;:19::i;1433:332:49:-;1094:13:7;:11;:13::i;:::-;1523:39:49::1;::::0;-1:-1:-1;;;1523:39:49;;1556:4:::1;1523:39;::::0;::::1;7070:74:51::0;1505:15:49::1;::::0;-1:-1:-1;;;;;1523:24:49;::::1;::::0;::::1;::::0;7043:18:51;;1523:39:49::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1505:57;;1580:7;1591:1;1580:12:::0;1572:52:::1;;;::::0;-1:-1:-1;;;1572:52:49;;20388:2:51;1572:52:49::1;::::0;::::1;20370:21:51::0;20427:2;20407:18;;;20400:30;20466:29;20446:18;;;20439:57;20513:18;;1572:52:49::1;20186:351:51::0;1572:52:49::1;1640:51;::::0;345:25:51;;;-1:-1:-1;;;;;1640:51:49;::::1;::::0;1663:10:::1;::::0;1640:51:::1;::::0;333:2:51;318:18;1640:51:49::1;;;;;;;1701:57;-1:-1:-1::0;;;;;1701:27:49;::::1;1737:10;1750:7:::0;1701:27:::1;:57::i;1824:101:7:-:0;1094:13;:11;:13::i;:::-;1888:30:::1;1915:1;1888:18;:30::i;8363:117:33:-:0;1094:13:7;:11;:13::i;:::-;8446:27:33::1;8461:11;8446:14;:27::i;901:325:31:-:0;945:23;980:14;997:21;:12;:19;:21::i;:::-;980:38;;1028:28;1080:6;1059:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1059:28:31;;-1:-1:-1;;1059:28:31;;;;;;;;;;;;1028:59;;1102:9;1097:102;1121:6;1117:1;:10;1097:102;;;1158:10;:30;1169:18;:12;1185:1;1169:15;:18::i;:::-;1158:30;;;;;;;;;;;;;;-1:-1:-1;1158:30:31;1148:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1148:40:31;;;;;;;;;;;;;;;;;;;;:7;;:4;;1153:1;;1148:7;;;;;;:::i;:::-;;;;;;:40;;;;1129:3;;;;:::i;:::-;;;1097:102;;;-1:-1:-1;1215:4:31;901:325;-1:-1:-1;;901:325:31:o;5695:460:33:-;4646:17;:24;;-1:-1:-1;;4646:24:33;4666:4;4646:24;;;5812:13:::1;::::0;-1:-1:-1;;;;;5812:13:33::1;5796:64;;;::::0;-1:-1:-1;;;5796:64:33;;21133:2:51;5796:64:33::1;::::0;::::1;21115:21:51::0;21172:2;21152:18;;;21145:30;21211:17;21191:18;;;21184:45;21246:18;;5796:64:33::1;20931:339:51::0;5796:64:33::1;5875:9;5870:279;5890:19:::0;;::::1;5870:279;;;5930:15;5948:8;;5957:1;5948:11;;;;;;;:::i;:::-;5973:130;::::0;;;;6023:10:::1;5973:130;::::0;::::1;21538:34:51::0;6059:4:33::1;21588:18:51::0;;;21581:43;5948:11:33::1;::::0;;::::1;::::0;;;::::1;;21640:18:51::0;;;21633:34;;;5948:11:33;-1:-1:-1;;;;;;;5981:10:33::1;5973:32;::::0;::::1;::::0;21450:18:51;;5973:130:33::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;6117:21;6127:7;6136:1;6117:9;:21::i;:::-;-1:-1:-1::0;5911:3:33::1;::::0;::::1;:::i;:::-;;;5870:279;;;-1:-1:-1::0;;4691:17:33;:25;;-1:-1:-1;;4691:25:33;;;-1:-1:-1;5695:460:33:o;7062:453::-;7205:2;-1:-1:-1;;;;;7197:10:33;:4;-1:-1:-1;;;;;7197:10:33;;7189:36;;;;-1:-1:-1;;;7189:36:33;;21880:2:51;7189:36:33;;;21862:21:51;21919:2;21899:18;;;21892:30;21958:15;21938:18;;;21931:43;21991:18;;7189:36:33;21678:337:51;7189:36:33;-1:-1:-1;;;;;7256:18:33;;;;:38;;-1:-1:-1;;;;;;7278:16:33;;;7256:38;7235:109;;;;-1:-1:-1;;;7235:109:33;;22222:2:51;7235:109:33;;;22204:21:51;22261:2;22241:18;;;22234:30;22300:26;22280:18;;;22273:54;22344:18;;7235:109:33;22020:348:51;7235:109:33;7383:13;;-1:-1:-1;;;;;7383:13:33;7375:36;;:90;;;7431:13;;;;;;;;;-1:-1:-1;;;;;7431:13:33;-1:-1:-1;;;;;7431:32:33;;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7354:154;;;;-1:-1:-1;;;7354:154:33;;22575:2:51;7354:154:33;;;22557:21:51;22614:2;22594:18;;;22587:30;22653:19;22633:18;;;22626:47;22690:18;;7354:154:33;22373:341:51;7354:154:33;7062:453;;;:::o;9965:61::-;1094:13:7;:11;:13::i;:::-;10011:8:33::1;:6;:8::i;11377:100::-:0;11424:12;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11424:12:33;-1:-1:-1;11462:7:33;;11455:15;;;;:6;:15;;;;;;;;;11448:22;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;11448:22:33;;;;;;;;;;;;;;;;;;;;;;;;;;11377:100::o;9112:166::-;1094:13:7;:11;:13::i;:::-;1486:16:9::1;:14;:16::i;:::-;9238:33:33::2;9256:14;9238:17;:33::i;2295:281:32:-:0;2365:5;-1:-1:-1;;;;;2365:19:32;;;;;:42;;-1:-1:-1;2388:10:32;-1:-1:-1;;;;;2402:5:32;2388:19;;2365:42;2357:65;;;;-1:-1:-1;;;2357:65:32;;22921:2:51;2357:65:32;;;22903:21:51;22960:2;22940:18;;;22933:30;22999:12;22979:18;;;22972:40;23029:18;;2357:65:32;22719:334:51;2357:65:32;2437:9;2432:138;2456:6;2452:1;:10;2432:138;;;2483:21;2499:1;2502;2483:15;:21::i;:::-;2518:13;;:41;;-1:-1:-1;;;2518:41:32;;-1:-1:-1;;;;;2548:10:32;7088:55:51;;2518:41:32;;;7070:74:51;2518:13:32;;;;:29;;7043:18:51;;2518:41:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2464:3;;;;:::i;:::-;;;2432:138;;11098:273:33;11260:7;;11180:15;11253;;;:6;:15;;;;;;:22;;;11295:24;;-1:-1:-1;;;11295:24:33;;-1:-1:-1;;;;;7088:55:51;;;11295:24:33;;;7070:74:51;11180:15:33;;11253:22;;;;11295:17;;7043:18:51;;11295:24:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11285:34;;11343:7;-1:-1:-1;;;;;11343:19:33;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11329:35;;11218:153;11098:273;;;:::o;1883:277:49:-;1094:13:7;:11;:13::i;:::-;1959:21:49::1;1941:15;1998:12:::0;;;1990:52:::1;;;::::0;-1:-1:-1;;;1990:52:49;;20388:2:51;1990:52:49::1;::::0;::::1;20370:21:51::0;20427:2;20407:18;;;20400:30;20466:29;20446:18;;;20439:57;20513:18;;1990:52:49::1;20186:351:51::0;1990:52:49::1;2058:38;::::0;345:25:51;;;2076:10:49::1;::::0;2058:38:::1;::::0;333:2:51;318:18;2058:38:49::1;;;;;;;2106:47;2132:10;2145:7;2106:17;:47::i;453:115:34:-:0;514:7;540:21;555:5;540:14;:21::i;881:397:49:-;1094:13:7;:11;:13::i;:::-;989:9:49::1;:16;1009:1;989:21:::0;981:61:::1;;;::::0;-1:-1:-1;;;981:61:49;;20388:2:51;981:61:49::1;::::0;::::1;20370:21:51::0;20427:2;20407:18;;;20400:30;20466:29;20446:18;;;20439:57;20513:18;;981:61:49::1;20186:351:51::0;981:61:49::1;1094:6;-1:-1:-1::0;;;;;1058:54:49::1;1082:10;-1:-1:-1::0;;;;;1058:54:49::1;;1102:9;1058:54;;;;;;:::i;:::-;;;;;;;;1127:9;1122:150;1146:9;:16;1142:1;:20;1122:150;;;1191:6;-1:-1:-1::0;;;;;1183:28:49::1;;1220:4;1235:10;1248:9;1258:1;1248:12;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;1183:78:::1;::::0;-1:-1:-1;;;;;;1183:78:49::1;::::0;;;;;;-1:-1:-1;;;;;21556:15:51;;;1183:78:49::1;::::0;::::1;21538:34:51::0;21608:15;;;;21588:18;;;21581:43;21640:18;;;21633:34;21450:18;;1183:78:49::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;1164:3;;;;:::i;:::-;;;1122:150;;9715:98:33::0;1094:13:7;:11;:13::i;:::-;9786:20:33::1;9801:4;9786:14;:20::i;10650:111::-:0;1094:13:7;:11;:13::i;:::-;10732:22:33::1;10745:8;10732:12;:22::i;6313:605::-:0;4646:17;:24;;-1:-1:-1;;4646:24:33;4666:4;4646:24;;;-1:-1:-1;;;;;6548:25:33;;::::1;6563:10;6548:25:::0;;;::::1;;6540:58;;;::::0;-1:-1:-1;;;6540:58:33;;23526:2:51;6540:58:33::1;::::0;::::1;23508:21:51::0;23565:2;23545:18;;;23538:30;23604:22;23584:18;;;23577:50;23644:18;;6540:58:33::1;23324:344:51::0;6540:58:33::1;6617:13;::::0;::::1;;6616:14;::::0;:43:::1;;-1:-1:-1::0;719:10:21;6634:25:33::1;::::0;;;:11:::1;:25;::::0;;;;;::::1;;6616:43;6608:70;;;::::0;-1:-1:-1;;;6608:70:33;;23875:2:51;6608:70:33::1;::::0;::::1;23857:21:51::0;23914:2;23894:18;;;23887:30;23953:16;23933:18;;;23926:44;23987:18;;6608:70:33::1;23673:338:51::0;6608:70:33::1;6689:184;::::0;;;;-1:-1:-1;;;;;6689:7:33::1;:13;::::0;::::1;::::0;:184:::1;::::0;6716:11;;6741:8;;6763:6;;6783:5;;;;6802:10;;6826;;6858:4:::1;::::0;6689:184:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;6884:27;6894:8;6904:6;6884:9;:27::i;:::-;-1:-1:-1::0;;4691:17:33;:25;;-1:-1:-1;;4691:25:33;;;-1:-1:-1;;;;;6313:605:33:o;8551:160::-;1094:13:7;:11;:13::i;:::-;8627::33::1;:30:::0;;-1:-1:-1;;8627:30:33::1;::::0;::::1;;::::0;;::::1;::::0;;;8672:32:::1;::::0;858:41:51;;;8672:32:33::1;::::0;846:2:51;831:18;8672:32:33::1;718:187:51::0;2074:198:7;1094:13;:11;:13::i;:::-;-1:-1:-1;;;;;2162:22:7;::::1;2154:73;;;::::0;-1:-1:-1;;;2154:73:7;;25877:2:51;2154:73:7::1;::::0;::::1;25859:21:51::0;25916:2;25896:18;;;25889:30;25955:34;25935:18;;;25928:62;26026:8;26006:18;;;25999:36;26052:19;;2154:73:7::1;25675:402:51::0;2154:73:7::1;2237:28;2256:8;2237:18;:28::i;1489:485:34:-:0;1570:41;;;;;;;;1601:10;1570:41;-1:-1:-1;;;;;1570:41:34;;;;;-1:-1:-1;;;1570:41:34;;;;;;;;;;;1763:45;;;;;;;-1:-1:-1;;;;1570:41:34;;1763:43;;:45;;;;;;;;;;;;;;1570:41;1763:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1738:70;;;;;;1837:130;1878:5;1862;:22;;;;:::i;:::-;412:1;1944:8;1936:17;;1837:7;:130::i;:::-;1818:149;1489:485;-1:-1:-1;;;;;;1489:485:34:o;13267:614:33:-;13430:12;2261:21:10;:19;:21::i;:::-;1239:19:9::1;:17;:19::i;:::-;13527:7:33::2;::::0;13454:13:::2;13567:15:::0;;;:6:::2;:15;::::0;;;;:27:::2;;::::0;719:10:21;;13499:150:33::2;::::0;719:10:21;;13608:6:33;13628:11;;13499:14:::2;:150::i;:::-;13691:7;::::0;13659:22:::2;13684:15:::0;;;:6:::2;:15;::::0;;;;:22:::2;;::::0;13492:157;;-1:-1:-1;;;;;;13684:22:33::2;::::0;13717::::2;13740:9:::0;13751:16:::2;:6:::0;13760:7:::2;13751:16;:::i;:::-;13717:51;::::0;-1:-1:-1;;;;;;13717:51:33::2;::::0;;;;;;-1:-1:-1;;;;;27577:55:51;;;13717:51:33::2;::::0;::::2;27559:74:51::0;27649:18;;;27642:34;27532:18;;13717:51:33::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;13813:9;-1:-1:-1::0;;;;;13783:58:33::2;13806:5;-1:-1:-1::0;;;;;13783:58:33::2;13797:7;;13783:58;13824:6;13833:7;13824:16;;;;:::i;:::-;13783:58;::::0;345:25:51;;;333:2;318:18;13783:58:33::2;;;;;;;13852:22;13869:4;13852:16;:22::i;:::-;13444:437;;2303:20:10::0;1716:1;2809:22;;2629:209;2647:312:20;2761:6;2736:21;:31;;2728:73;;;;-1:-1:-1;;;2728:73:20;;27889:2:51;2728:73:20;;;27871:21:51;27928:2;27908:18;;;27901:30;27967:31;27947:18;;;27940:59;28016:18;;2728:73:20;27687:353:51;2728:73:20;2813:12;2831:9;-1:-1:-1;;;;;2831:14:20;2853:6;2831:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2812:52;;;2882:7;2874:78;;;;-1:-1:-1;;;2874:78:20;;28457:2:51;2874:78:20;;;28439:21:51;28496:2;28476:18;;;28469:30;28535:34;28515:18;;;28508:62;28606:28;28586:18;;;28579:56;28652:19;;2874:78:20;28255:422:51;2695:400:32;2804:31;2820:7;2829:5;2804:15;:31::i;:::-;2861:13;;-1:-1:-1;;;;;2861:13:32;2845:66;;;;-1:-1:-1;;;2845:66:32;;28884:2:51;2845:66:32;;;28866:21:51;28923:2;28903:18;;;28896:30;28962:19;28942:18;;;28935:47;28999:18;;2845:66:32;28682:341:51;2845:66:32;2925:5;-1:-1:-1;;;;;2925:19:32;;2921:117;;2960:67;;;;;3005:4;2960:67;;;21538:34:51;-1:-1:-1;;;;;3012:5:32;21608:15:51;;21588:18;;;21581:43;21640:18;;;21633:34;;;2968:10:32;2960:36;;;;21450:18:51;;2960:67:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2921:117;3047:13;;:41;;-1:-1:-1;;;3047:41:32;;-1:-1:-1;;;;;3077:10:32;7088:55:51;;3047:41:32;;;7070:74:51;3047:13:32;;;;:29;;7043:18:51;;3047:41:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2695:400;;:::o;1359:130:7:-;1247:7;1273:6;-1:-1:-1;;;;;1273:6:7;719:10:21;1422:23:7;1414:68;;;;-1:-1:-1;;;1414:68:7;;29230:2:51;1414:68:7;;;29212:21:51;;;29249:18;;;29242:30;29308:34;29288:18;;;29281:62;29360:18;;1414:68:7;29028:356:51;5227:117:31;5283:23;:12;5303:2;5283:19;:23::i;:::-;-1:-1:-1;5323:14:31;;;;:10;:14;;;;;5316:21;;;;;;;;;;-1:-1:-1;;5316:21:31;;;5227:117::o;1232:1005::-;1421:12;1435:35;;1533:11;;1582:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1582:21:31;;1561:42;;1645:6;1631:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1631:21:31;;1613:39;;1667:9;1662:525;1686:6;1682:1;:10;1662:525;;;1714:25;1741:22;1767:107;1799:7;1824:4;1846:11;;1858:1;1846:14;;;;;;;:::i;:::-;;;;;;;1767;:107::i;:::-;1713:161;;;;1908:32;1913:17;1932:7;1908:4;:32::i;:::-;1888:52;;1978:17;1954:18;1973:1;1954:21;;;;;;;;:::i;:::-;;;;;;:41;;;;;2030:14;2009:15;2025:1;2009:18;;;;;;;;:::i;:::-;;;;;;;;;;:35;2059:28;2070:17;2059:28;;:::i;:::-;;-1:-1:-1;2158:17:31;609:5;2110:22;2118:14;2110:5;:22;:::i;:::-;:45;;;;:::i;:::-;:65;;;;:::i;:::-;2101:75;;;;:::i;:::-;;;1699:488;;1694:3;;;;:::i;:::-;;;1662:525;;;-1:-1:-1;2214:15:31;2222:7;2214:5;:15;:::i;:::-;2205:25;;;;:::i;:::-;;;1506:731;1232:1005;;;;;;;;;;:::o;10104:460:33:-;1094:13:7;:11;:13::i;:::-;10174::33::1;::::0;-1:-1:-1;;;;;10174:13:33::1;10158:66;;;::::0;-1:-1:-1;;;10158:66:33;;29721:2:51;10158:66:33::1;::::0;::::1;29703:21:51::0;29760:2;29740:18;;;29733:30;29799:19;29779:18;;;29772:47;29836:18;;10158:66:33::1;29519:341:51::0;10158:66:33::1;10263:13;::::0;:45:::1;::::0;;;;;;;10337:4:::1;::::0;-1:-1:-1;;;;;10263:13:33::1;::::0;:43:::1;::::0;:45:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:13;:45:::1;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;10255:87:33::1;;10234:159;;;::::0;-1:-1:-1;;;10234:159:33;;30362:2:51;10234:159:33::1;::::0;::::1;30344:21:51::0;30401:2;30381:18;;;30374:30;30440:27;30420:18;;;30413:55;30485:18;;10234:159:33::1;30160:349:51::0;10234:159:33::1;10432:13;::::0;:35:::1;::::0;;;;;;;10480:4:::1;::::0;-1:-1:-1;;;;;10432:13:33::1;::::0;:33:::1;::::0;:35:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:13;:35:::1;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;10424:61:33::1;;10403:134;;;::::0;-1:-1:-1;;;10403:134:33;;31001:2:51;10403:134:33::1;::::0;::::1;30983:21:51::0;31040:2;31020:18;;;31013:30;31079:28;31059:18;;;31052:56;31125:18;;10403:134:33::1;30799:350:51::0;10403:134:33::1;10547:10;:8;:10::i;3101:693:32:-:0;3190:5;-1:-1:-1;;;;;3190:19:32;3186:32;;3101:693;;:::o;3186:32::-;3391:44;;-1:-1:-1;;;3391:44:32;;3429:4;3391:44;;;7070:74:51;3374:14:32;;3399:10;-1:-1:-1;;;;;3391:29:32;;;;7043:18:51;;3391:44:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3374:61;;3451:9;3446:342;3470:6;3466:1;:10;3446:342;;;-1:-1:-1;;;;;3519:10:32;3501:49;;3559:4;3579:1;3566:10;3575:1;3566:6;:10;:::i;:::-;:14;;;;:::i;:::-;3501:80;;-1:-1:-1;;;;;;3501:80:32;;;;;;;-1:-1:-1;;;;;27577:55:51;;;3501:80:32;;;27559:74:51;27649:18;;;27642:34;27532:18;;3501:80:32;;;;;;;;;;;;;;;;;;-1:-1:-1;3501:80:32;;;;;;;;-1:-1:-1;;3501:80:32;;;;;;;;;;;;:::i;:::-;;;3497:281;3758:5;3497:281;3626:21;3636:7;3645:1;3626:9;:21::i;:::-;3582:80;3478:3;;;:::i;:::-;;;3446:342;;;;3176:618;3101:693;;:::o;14868:1011:33:-;14951:7;;14916:25;14944:15;;;:6;:15;;;;;:22;;;-1:-1:-1;;;;;14944:22:33;;14998:15;:64;;;;-1:-1:-1;;;;;;15029:33:33;;;;14998:64;:111;;;;-1:-1:-1;15085:7:33;;15078:15;;;;:6;:15;;;;;:26;;;:31;14998:111;14976:133;;15125:14;15124:15;:52;;;;-1:-1:-1;;;;;;15143:33:33;;;;15124:52;15120:179;;;15222:10;-1:-1:-1;;;;;15222:22:33;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15199:7;;15192:15;;;;:6;:15;;;;;;;:27;;:54;;;;15260:28;;;;15283:4;15260:28;;;858:41:51;-1:-1:-1;;;;;15260:22:33;;;;;831:18:51;;15260:28:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15120:179;15314:14;15309:564;;15344:19;15366:6;:17;15375:7;;15373:9;;;;;:::i;:::-;;;;;;;15366:17;;;;;;;;;;;15344:39;;15398:16;15417:18;:7;;:16;:18::i;:::-;15398:37;;15449:18;15511:16;15529:2;15494:38;;;;;;;;;:::i;:::-;;;;;;;;;;;;;15449:97;;15560:20;15607:18;15627:2;15590:40;;;;;;;;;:::i;:::-;;;;;;;;;;;;;15560:71;;15645:22;15670:73;15701:4;15723:6;15670:13;:73::i;:::-;15758:12;;;:22;;-1:-1:-1;;15758:22:33;-1:-1:-1;;;;;15758:22:33;;;;;;;;;;-1:-1:-1;;15810:7:33;;15794:23;;-1:-1:-1;;15851:11:33;;-1:-1:-1;15831:17:33;;;:31;-1:-1:-1;;14868:1011:33:o;941:175:13:-;1050:58;;;-1:-1:-1;;;;;27577:55:51;;1050:58:13;;;27559:74:51;27649:18;;;;27642:34;;;1050:58:13;;;;;;;;;;27532:18:51;;;;1050:58:13;;;;;;;;;;1073:23;1050:58;;;1023:86;;1043:5;;1023:19;:86::i;2426:187:7:-;2499:16;2518:6;;-1:-1:-1;;;;;2534:17:7;;;-1:-1:-1;;2534:17:7;;;;;;2566:40;;2518:6;;;;;;;2566:40;;2499:16;2566:40;2489:124;2426:187;:::o;15885:515:33:-;3589:5;16065:11;:24;;;16021:11;:25;;;15980:11;:22;;;:66;;;;:::i;:::-;:109;;;;:::i;:::-;:144;;;15959:204;;;;-1:-1:-1;;;15959:204:33;;33185:2:51;15959:204:33;;;33167:21:51;33224:2;33204:18;;;33197:30;33263:15;33243:18;;;33236:43;33296:18;;15959:204:33;32983:337:51;15959:204:33;16181:20;;-1:-1:-1;;;;;16181:34:33;16173:67;;;;-1:-1:-1;;;16173:67:33;;33527:2:51;16173:67:33;;;33509:21:51;33566:2;33546:18;;;33539:30;33605:22;33585:18;;;33578:50;33645:18;;16173:67:33;33325:344:51;16173:67:33;16258:19;;;;-1:-1:-1;;;;;16258:33:33;16250:66;;;;-1:-1:-1;;;16250:66:33;;33527:2:51;16250:66:33;;;33509:21:51;33566:2;33546:18;;;33539:30;33605:22;33585:18;;;33578:50;33645:18;;16250:66:33;33325:344:51;16250:66:33;16332:26;16346:11;16332:26;;;;;33822:4:51;33864:3;33853:9;33849:19;33841:27;;-1:-1:-1;;;;;33975:2:51;33966:6;33960:13;33956:22;33945:9;33938:41;34047:2;34039:4;34031:6;34027:17;34021:24;34017:33;34010:4;33999:9;33995:20;33988:63;;34098:4;34090:6;34086:17;34080:24;34123:10;34189:2;34175:12;34171:21;34164:4;34153:9;34149:20;34142:51;34261:2;34253:4;34245:6;34241:17;34235:24;34231:33;34224:4;34213:9;34209:20;34202:63;34333:2;34325:4;34317:6;34313:17;34307:24;34303:33;34296:4;34285:9;34281:20;34274:63;;;33674:669;;;;;16332:26:33;;;;;;;;16369:24;;:10;:24;;-1:-1:-1;;16369:24:33;-1:-1:-1;;;;;16369:24:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;16369:24:33;;;;;;;;-1:-1:-1;;;16369:24:33;;;;;;;;;;;;;-1:-1:-1;;;16369:24:33;;;;;;;;;;;15885:515::o;11531:112:28:-;11591:7;11617:19;11625:3;4545:18;;4463:107;11985:135;12056:7;12090:22;12094:3;12106:5;12090:3;:22::i;:::-;12082:31;11985:135;-1:-1:-1;;;11985:135:28:o;2186:115:9:-;1239:19;:17;:19::i;:::-;2245:7:::1;:14:::0;;-1:-1:-1;;2245:14:9::1;2255:4;2245:14;::::0;;2274:20:::1;2281:12;719:10:21::0;;640:96;2281:12:9::1;2274:20;::::0;-1:-1:-1;;;;;7088:55:51;;;7070:74;;7058:2;7043:18;2274:20:9::1;;;;;;;2186:115::o:0;1945:106::-;1685:7;;;;2003:41;;;;-1:-1:-1;;;2003:41:9;;34550:2:51;2003:41:9;;;34532:21:51;34589:2;34569:18;;;34562:30;34628:22;34608:18;;;34601:50;34668:18;;2003:41:9;34348:344:51;14078:784:33;-1:-1:-1;;;;;14205:37:33;;14184:106;;;;-1:-1:-1;;;14184:106:33;;34899:2:51;14184:106:33;;;34881:21:51;34938:2;34918:18;;;34911:30;34977:24;34957:18;;;34950:52;35019:18;;14184:106:33;34697:346:51;14184:106:33;14321:120;-1:-1:-1;;;;;14321:41:33;;-1:-1:-1;;;14321:41:33;:120::i;:::-;14300:188;;;;-1:-1:-1;;;14300:188:33;;35250:2:51;14300:188:33;;;35232:21:51;35289:2;35269:18;;;35262:30;35328:23;35308:18;;;35301:51;35369:18;;14300:188:33;35048:345:51;14300:188:33;14511:13;;-1:-1:-1;;;;;14511:13:33;14503:36;14499:181;;14618:13;;14555:114;;;;;-1:-1:-1;;;;;14618:13:33;;;14555:114;;;35566:74:51;14618:13:33;35656:18:51;;;35649:50;14563:10:33;14555:37;;;;;;35539:18:51;;14555:114:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14499:181;14689:68;;;;;-1:-1:-1;;;;;35584:55:51;;;14689:68:33;;;35566:74:51;14752:4:33;35656:18:51;;;35649:50;14697:10:33;14689:37;;;;35539:18:51;;14689:68:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;14768:13:33;:30;;-1:-1:-1;;14768:30:33;-1:-1:-1;;;;;14768:30:33;;;;;;;;14814:41;;14768:30;;-1:-1:-1;14814:41:33;;-1:-1:-1;;;14814:41:33;14078:784;:::o;13887:185::-;13972:7;;13965:15;;;;:6;:15;;;;;:26;;:31;;13995:1;;13965:15;:31;;13995:1;;13965:31;:::i;:::-;;;;-1:-1:-1;;14045:7:33;;14038:15;;;;:6;:15;;;;;;;;;:26;;;14011:54;;35912:25:51;;;35953:18;;;35946:34;;;35996:18;;;35989:34;;;;14011:54:33;;35900:2:51;35885:18;14011:54:33;;;;;;;;13887:185;;:::o;998:485:34:-;1079:41;;;;;;;;1110:10;1079:41;-1:-1:-1;;;;;1079:41:34;;;;;-1:-1:-1;;;1079:41:34;;;;;;;;;;;1272:45;;;;;;;-1:-1:-1;;;;1079:41:34;;1272:43;;:45;;;;;;;;;;;;;;1079:41;1272:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1247:70;;;;;;1346:130;1387:5;1371;:22;;;;:::i;:::-;1419:8;1411:17;;412:1;1346:7;:130::i;695:297::-;-1:-1:-1;;;;;756:18:34;;752:55;;783:24;;;;;;;;;;;;;;752:55;817:14;856:4;-1:-1:-1;;;;;834:36:34;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;895:43;;;;;;;;-1:-1:-1;;;;;895:43:34;;;;;;;;;;;;;;;882:10;:56;;;;;;-1:-1:-1;;;882:56:34;;;;;953:32;;11044:74:51;;;11134:18;;;11127:45;;;;895:43:34;;-1:-1:-1;953:32:34;;11017:18:51;953:32:34;10874:304:51;4204:1017:31;4468:11;;4497:23;;;;4538:26;;;;4582:20;;;;4620;;;;550:4;4685:37;;;;;4664:107;;;;-1:-1:-1;;;4664:107:31;;36488:2:51;4664:107:31;;;36470:21:51;36527:2;36507:18;;;36500:30;36566:25;36546:18;;;36539:53;36609:18;;4664:107:31;36286:347:51;4664:107:31;4809:1;4789:17;:21;;;4781:58;;;;-1:-1:-1;;;4781:58:31;;36840:2:51;4781:58:31;;;36822:21:51;36879:2;36859:18;;;36852:30;36918:26;36898:18;;;36891:54;36962:18;;4781:58:31;36638:348:51;4781:58:31;-1:-1:-1;;;;;4857:25:31;;4849:57;;;;-1:-1:-1;;;4849:57:31;;37193:2:51;4849:57:31;;;37175:21:51;37232:2;37212:18;;;37205:30;37271:21;37251:18;;;37244:49;37310:18;;4849:57:31;36991:343:51;4849:57:31;4937:11;:16;;4952:1;4937:16;:92;;;;4974:11;:16;;4989:1;4974:16;:54;;;;-1:-1:-1;4994:20:31;;;;-1:-1:-1;;;;;4994:34:31;;;4974:54;4916:158;;;;-1:-1:-1;;;4916:158:31;;37541:2:51;4916:158:31;;;37523:21:51;37580:2;37560:18;;;37553:30;37619:21;37599:18;;;37592:49;37658:18;;4916:158:31;37339:343:51;4916:158:31;5098:11;;;5120:21;:12;5098:11;5120:16;:21::i;:::-;-1:-1:-1;5151:15:31;;;;:10;:15;;;;;;;;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;5151:26:31;;;;;;;;;;;-1:-1:-1;5151:26:31;;;;;-1:-1:-1;;5151:26:31;;;;;;;;5193:21;;;;;5151:26;;5193:21;:::i;:::-;;;;;;;;4267:954;;;;;;4204:1017;:::o;1980:459:34:-;2106:7;2160:10;2144:12;:26;:288;;2250:10;2235:12;:25;:179;;2387:25;2400:12;2387:10;:25;:::i;:::-;2373:40;;:2;:40;:::i;:::-;2364:50;;:5;:50;:::i;:::-;2144:288;;2235:179;2310:25;2325:10;2310:12;:25;:::i;:::-;2296:40;;:2;:40;:::i;:::-;2287:50;;:5;:50;:::i;2144:288::-;-1:-1:-1;2189:5:34;;2125:307;-1:-1:-1;;1980:459:34:o;2336:287:10:-;1759:1;2468:7;;:19;2460:63;;;;-1:-1:-1;;;2460:63:10;;39656:2:51;2460:63:10;;;39638:21:51;39695:2;39675:18;;;39668:30;39734:33;39714:18;;;39707:61;39785:18;;2460:63:10;39454:355:51;2460:63:10;1759:1;2598:7;:18;2336:287::o;1767:106:9:-;1685:7;;;;1836:9;1828:38;;;;-1:-1:-1;;;1828:38:9;;40016:2:51;1828:38:9;;;39998:21:51;40055:2;40035:18;;;40028:30;40094:18;40074;;;40067:46;40130:18;;1828:38:9;39814:340:51;2243:843:31;2426:12;2467:11;2426:12;2495:541;2519:6;2515:1;:10;2495:541;;;2546:18;2567:11;;2579:1;2567:14;;;;;;;:::i;:::-;;;;;;;2546:35;;2596:25;2623:22;2649:103;2681:7;2706:4;2728:10;2649:14;:103::i;:::-;2595:157;;;;2786:32;2791:17;2810:7;2786:4;:32::i;:::-;2766:52;;2876:17;2832:13;:19;2846:4;-1:-1:-1;;;;;2832:19:31;-1:-1:-1;;;;;2832:19:31;;;;;;;;;;;;:28;2852:7;2832:28;;;;;;;;;;;:40;2861:10;2832:40;;;;;;;;;;;;:61;;;;;;;:::i;:::-;;;;-1:-1:-1;2908:28:31;;-1:-1:-1;2919:17:31;2908:28;;:::i;:::-;;-1:-1:-1;3007:17:31;609:5;2959:22;2967:14;2959:5;:22;:::i;:::-;:45;;;;:::i;:::-;:65;;;;:::i;:::-;2950:75;;;;:::i;:::-;;;2532:504;;;2527:3;;;;:::i;:::-;;;2495:541;;;-1:-1:-1;3063:15:31;3071:7;3063:5;:15;:::i;:::-;3054:25;;;;:::i;:::-;;2243:843;-1:-1:-1;;;;;;;;2243:843:31:o;16406:717:33:-;16486:10;:19;16589:18;;-1:-1:-1;;;;;16486:19:33;;;;16589:18;;;16621:23;-1:-1:-1;;;16621:23:33;;;;;-1:-1:-1;;;16658:21:33;;;16467:16;3589:5;16722:28;16658:21;16722:6;:28;:::i;:::-;16721:48;;;;:::i;:::-;16700:69;-1:-1:-1;16779:20:33;3589:5;16803:30;16812:21;;;16803:6;:30;:::i;:::-;16802:62;;;;:::i;:::-;16779:85;-1:-1:-1;16874:21:33;16779:85;16898:19;16907:10;16898:6;:19;:::i;:::-;:34;;;;:::i;:::-;16874:58;;16943:53;16969:13;16985:10;16943:17;:53::i;:::-;17006:51;17032:8;17043:13;17006:17;:51::i;:::-;17067:49;17093:7;17103:12;17067:17;:49::i;:::-;16457:666;;;;;;;16406:717;:::o;11090:135:28:-;11160:4;11183:35;11191:3;11211:5;11183:7;:35::i;3092:1106:31:-;3220:15;3304:22;;;:10;:22;;;;;;;;3271:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3271:55:31;;;;;;;;;;;;;;;;;;;;;;;3752:37;;-1:-1:-1;;;3752:37:31;;7088:55:51;;;3752:37:31;;;7070:74:51;;;;3220:15:31;;3271:55;;;;;;3220:15;;3271:55;;3752:31;;7043:18:51;;3752:37:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3734:55;;3803:12;:17;;3819:1;3803:17;3799:164;;3901:20;;;;3893:45;;-1:-1:-1;;;3893:45:31;;-1:-1:-1;;;;;7088:55:51;;;3893:45:31;;;7070:74:51;3846:106:31;;3868:7;;3893:39;;;;;7043:18:51;;3893:45:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3846:4;:106::i;:::-;3836:116;;3799:164;-1:-1:-1;;;;;3988:19:31;;3973:12;3988:19;;;:13;:19;;;;;;;;:28;;;;;;;;:40;;;;;;;;;4048:37;4058:27;;;4048:7;:37;:::i;:::-;4038:47;;4112:7;4105:4;:14;:35;;4126:14;4136:4;4126:7;:14;:::i;:::-;4105:35;;;4122:1;4105:35;4095:45;4167:24;;;;;-1:-1:-1;3092:1106:31;;-1:-1:-1;;;;;;;;;;3092:1106:31:o;5350:105::-;5409:7;5439:1;5435;:5;:13;;5447:1;5435:13;;;-1:-1:-1;5443:1:31;;5350:105;-1:-1:-1;5350:105:31:o;2433:117:9:-;1486:16;:14;:16::i;:::-;2491:7:::1;:15:::0;;-1:-1:-1;;2491:15:9::1;::::0;;2521:22:::1;719:10:21::0;2530:12:9::1;640:96:21::0;447:696:22;503:13;552:14;569:17;580:5;569:10;:17::i;:::-;589:1;569:21;552:38;;604:20;638:6;627:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;627:18:22;-1:-1:-1;604:41:22;-1:-1:-1;765:28:22;;;781:2;765:28;820:280;-1:-1:-1;;851:5:22;990:8;985:2;974:14;;969:30;851:5;956:44;1044:2;1035:11;;;-1:-1:-1;1064:21:22;820:280;1064:21;-1:-1:-1;1120:6:22;447:696;-1:-1:-1;;;447:696:22:o;911:267:40:-;1016:14;1042:20;1080:22;1093:8;1080:12;:22::i;:::-;1113:36;;;;;1042:61;;-1:-1:-1;;;;;;1113:16:40;;;;;:36;;1130:4;;1136:6;;1144:4;;1113:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1166:5:40;;911:267;-1:-1:-1;;;;;;911:267:40:o;5196:642:13:-;5615:23;5641:69;5669:4;5641:69;;;;;;;;;;;;;;;;;5649:5;-1:-1:-1;;;;;5641:27:13;;;:69;;;;;:::i;:::-;5615:95;;5728:10;:17;5749:1;5728:22;:56;;;;5765:10;5754:30;;;;;;;;;;;;:::i;:::-;5720:111;;;;-1:-1:-1;;;5720:111:13;;40905:2:51;5720:111:13;;;40887:21:51;40944:2;40924:18;;;40917:30;40983:34;40963:18;;;40956:62;41054:12;41034:18;;;41027:40;41084:19;;5720:111:13;40703:406:51;4912:118:28;4979:7;5005:3;:11;;5017:5;5005:18;;;;;;;;:::i;:::-;;;;;;;;;4998:25;;4912:118;;;;:::o;1349:282:24:-;1436:4;1543:23;1558:7;1543:14;:23::i;:::-;:81;;;;;1570:54;1603:7;1612:11;1570:32;:54::i;10793:129:28:-;10860:4;10883:32;10888:3;10908:5;10883:4;:32::i;2786:1388::-;2852:4;2989:19;;;:12;;;:19;;;;;;3023:15;;3019:1149;;3392:21;3416:14;3429:1;3416:10;:14;:::i;:::-;3464:18;;3392:38;;-1:-1:-1;3444:17:28;;3464:22;;3485:1;;3464:22;:::i;:::-;3444:42;;3518:13;3505:9;:26;3501:398;;3551:17;3571:3;:11;;3583:9;3571:22;;;;;;;;:::i;:::-;;;;;;;;;3551:42;;3722:9;3693:3;:11;;3705:13;3693:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;3805:23;;;:12;;;:23;;;;;:36;;;3501:398;3977:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;4069:3;:12;;:19;4082:5;4069:19;;;;;;;;;;;4062:26;;;4110:4;4103:11;;;;;;;3019:1149;4152:5;4145:12;;;;;10139:916:26;10192:7;;10276:8;10267:17;;10263:103;;10313:8;10304:17;;;-1:-1:-1;10349:2:26;10339:12;10263:103;10392:8;10383:5;:17;10379:103;;10429:8;10420:17;;;-1:-1:-1;10465:2:26;10455:12;10379:103;10508:8;10499:5;:17;10495:103;;10545:8;10536:17;;;-1:-1:-1;10581:2:26;10571:12;10495:103;10624:7;10615:5;:16;10611:100;;10660:7;10651:16;;;-1:-1:-1;10695:1:26;10685:11;10611:100;10737:7;10728:5;:16;10724:100;;10773:7;10764:16;;;-1:-1:-1;10808:1:26;10798:11;10724:100;10850:7;10841:5;:16;10837:100;;10886:7;10877:16;;;-1:-1:-1;10921:1:26;10911:11;10837:100;10963:7;10954:5;:16;10950:66;;11000:1;10990:11;11042:6;10139:916;-1:-1:-1;;10139:916:26:o;973:759:8:-;1030:16;1362:48;1344:14;1338:4;1334:25;1328:4;1324:36;1321:90;1315:4;1308:104;1569:32;1552:14;1546:4;1542:25;1539:63;1533:4;1526:77;1644:4;1638;1635:1;1628:21;1616:33;-1:-1:-1;;;;;;1676:22:8;;1668:57;;;;-1:-1:-1;;;1668:57:8;;41505:2:51;1668:57:8;;;41487:21:51;41544:2;41524:18;;;41517:30;41583:24;41563:18;;;41556:52;41625:18;;1668:57:8;41303:346:51;1668:57:8;973:759;;;:::o;4108:223:20:-;4241:12;4272:52;4294:6;4302:4;4308:1;4311:12;4272:21;:52::i;704:427:24:-;768:4;975:68;1008:7;-1:-1:-1;;;975:32:24;:68::i;:::-;:149;;;;-1:-1:-1;1060:64:24;1093:7;-1:-1:-1;;;;;;1060:32:24;:64::i;:::-;1059:65;956:168;704:427;-1:-1:-1;;704:427:24:o;4421:647::-;4592:71;;;-1:-1:-1;;;;;;4040:79:51;;4592:71:24;;;;4022:98:51;;;;4592:71:24;;;;;;;;;;3995:18:51;;;;4592:71:24;;;;;;;;;;;-1:-1:-1;;;4592:71:24;;;4871:20;;4523:4;;4592:71;4523:4;;;;;;4592:71;4523:4;;4871:20;4836:7;4829:5;4818:86;4807:97;;4931:16;4917:30;;4981:4;4975:11;4960:26;;5013:7;:29;;;;;5038:4;5024:10;:18;;5013:29;:48;;;;;5060:1;5046:11;:15;5013:48;5006:55;4421:647;-1:-1:-1;;;;;;;4421:647:24:o;2214:404:28:-;2277:4;4351:19;;;:12;;;:19;;;;;;2293:319;;-1:-1:-1;2335:23:28;;;;;;;;:11;:23;;;;;;;;;;;;;2515:18;;2493:19;;;:12;;;:19;;;;;;:40;;;;2547:11;;2293:319;-1:-1:-1;2596:5:28;2589:12;;5165:446:20;5330:12;5387:5;5362:21;:30;;5354:81;;;;-1:-1:-1;;;5354:81:20;;41856:2:51;5354:81:20;;;41838:21:51;41895:2;41875:18;;;41868:30;41934:34;41914:18;;;41907:62;42005:8;41985:18;;;41978:36;42031:19;;5354:81:20;41654:402:51;5354:81:20;5446:12;5460:23;5487:6;-1:-1:-1;;;;;5487:11:20;5506:5;5513:4;5487:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5445:73;;;;5535:69;5562:6;5570:7;5579:10;5591:12;7851;7879:7;7875:418;;;7906:10;:17;7927:1;7906:22;7902:286;;-1:-1:-1;;;;;1702:19:20;;;8113:60;;;;-1:-1:-1;;;8113:60:20;;42555:2:51;8113:60:20;;;42537:21:51;42594:2;42574:18;;;42567:30;42633:31;42613:18;;;42606:59;42682:18;;8113:60:20;42353:353:51;8113:60:20;-1:-1:-1;8208:10:20;8201:17;;7875:418;8249:33;8257:10;8269:12;8980:17;;:21;8976:379;;9208:10;9202:17;9264:15;9251:10;9247:2;9243:19;9236:44;8976:379;9331:12;9324:20;;-1:-1:-1;;;9324:20:20;;;;;;;;:::i;14:180:51:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:51;;14:180;-1:-1:-1;14:180:51:o;381:332::-;439:6;492:2;480:9;471:7;467:23;463:32;460:52;;;508:1;505;498:12;460:52;547:9;534:23;-1:-1:-1;;;;;;590:5:51;586:78;579:5;576:89;566:117;;679:1;676;669:12;910:154;-1:-1:-1;;;;;989:5:51;985:54;978:5;975:65;965:93;;1054:1;1051;1044:12;1069:367;1132:8;1142:6;1196:3;1189:4;1181:6;1177:17;1173:27;1163:55;;1214:1;1211;1204:12;1163:55;-1:-1:-1;1237:20:51;;1280:18;1269:30;;1266:50;;;1312:1;1309;1302:12;1266:50;1349:4;1341:6;1337:17;1325:29;;1409:3;1402:4;1392:6;1389:1;1385:14;1377:6;1373:27;1369:38;1366:47;1363:67;;;1426:1;1423;1416:12;1363:67;1069:367;;;;;:::o;1441:640::-;1545:6;1553;1561;1569;1622:2;1610:9;1601:7;1597:23;1593:32;1590:52;;;1638:1;1635;1628:12;1590:52;1674:9;1661:23;1651:33;;1734:2;1723:9;1719:18;1706:32;1747:31;1772:5;1747:31;:::i;:::-;1797:5;-1:-1:-1;1853:2:51;1838:18;;1825:32;1880:18;1869:30;;1866:50;;;1912:1;1909;1902:12;1866:50;1951:70;2013:7;2004:6;1993:9;1989:22;1951:70;:::i;:::-;1441:640;;;;-1:-1:-1;2040:8:51;-1:-1:-1;;;;1441:640:51:o;2086:184::-;-1:-1:-1;;;2135:1:51;2128:88;2235:4;2232:1;2225:15;2259:4;2256:1;2249:15;2275:334;2346:2;2340:9;2402:2;2392:13;;-1:-1:-1;;2388:86:51;2376:99;;2505:18;2490:34;;2526:22;;;2487:62;2484:88;;;2552:18;;:::i;:::-;2588:2;2581:22;2275:334;;-1:-1:-1;2275:334:51:o;2614:589::-;2656:5;2709:3;2702:4;2694:6;2690:17;2686:27;2676:55;;2727:1;2724;2717:12;2676:55;2763:6;2750:20;2789:18;2785:2;2782:26;2779:52;;;2811:18;;:::i;:::-;2855:114;2963:4;-1:-1:-1;;2887:4:51;2883:2;2879:13;2875:86;2871:97;2855:114;:::i;:::-;2994:2;2985:7;2978:19;3040:3;3033:4;3028:2;3020:6;3016:15;3012:26;3009:35;3006:55;;;3057:1;3054;3047:12;3006:55;3122:2;3115:4;3107:6;3103:17;3096:4;3087:7;3083:18;3070:55;3170:1;3145:16;;;3163:4;3141:27;3134:38;;;;3149:7;2614:589;-1:-1:-1;;;2614:589:51:o;3208:665::-;3303:6;3311;3319;3327;3380:3;3368:9;3359:7;3355:23;3351:33;3348:53;;;3397:1;3394;3387:12;3348:53;3436:9;3423:23;3455:31;3480:5;3455:31;:::i;:::-;3505:5;-1:-1:-1;3562:2:51;3547:18;;3534:32;3575:33;3534:32;3575:33;:::i;:::-;3627:7;-1:-1:-1;3681:2:51;3666:18;;3653:32;;-1:-1:-1;3736:2:51;3721:18;;3708:32;3763:18;3752:30;;3749:50;;;3795:1;3792;3785:12;3749:50;3818:49;3859:7;3850:6;3839:9;3835:22;3818:49;:::i;:::-;3808:59;;;3208:665;;;;;;;:::o;4131:383::-;4208:6;4216;4224;4277:2;4265:9;4256:7;4252:23;4248:32;4245:52;;;4293:1;4290;4283:12;4245:52;4332:9;4319:23;4351:31;4376:5;4351:31;:::i;:::-;4401:5;4453:2;4438:18;;4425:32;;-1:-1:-1;4504:2:51;4489:18;;;4476:32;;4131:383;-1:-1:-1;;;4131:383:51:o;4519:118::-;4605:5;4598:13;4591:21;4584:5;4581:32;4571:60;;4627:1;4624;4617:12;4642:382;4707:6;4715;4768:2;4756:9;4747:7;4743:23;4739:32;4736:52;;;4784:1;4781;4774:12;4736:52;4823:9;4810:23;4842:31;4867:5;4842:31;:::i;:::-;4892:5;-1:-1:-1;4949:2:51;4934:18;;4921:32;4962:30;4921:32;4962:30;:::i;:::-;5011:7;5001:17;;;4642:382;;;;;:::o;5029:640::-;5133:6;5141;5149;5157;5210:2;5198:9;5189:7;5185:23;5181:32;5178:52;;;5226:1;5223;5216:12;5178:52;5265:9;5252:23;5284:31;5309:5;5284:31;:::i;:::-;5334:5;-1:-1:-1;5386:2:51;5371:18;;5358:32;;-1:-1:-1;5441:2:51;5426:18;;5413:32;5468:18;5457:30;;5454:50;;;5500:1;5497;5490:12;5674:435;5727:3;5765:5;5759:12;5792:6;5787:3;5780:19;5818:4;5847:2;5842:3;5838:12;5831:19;;5884:2;5877:5;5873:14;5905:1;5915:169;5929:6;5926:1;5923:13;5915:169;;;5990:13;;5978:26;;6024:12;;;;6059:15;;;;5951:1;5944:9;5915:169;;;-1:-1:-1;6100:3:51;;5674:435;-1:-1:-1;;;;;5674:435:51:o;6114:536::-;6399:6;6388:9;6381:25;6442:2;6437;6426:9;6422:18;6415:30;6362:4;6468:56;6520:2;6509:9;6505:18;6497:6;6468:56;:::i;:::-;6572:9;6564:6;6560:22;6555:2;6544:9;6540:18;6533:50;6600:44;6637:6;6629;6600:44;:::i;6655:248::-;6723:6;6731;6784:2;6772:9;6763:7;6759:23;6755:32;6752:52;;;6800:1;6797;6790:12;6752:52;-1:-1:-1;;6823:23:51;;;6893:2;6878:18;;;6865:32;;-1:-1:-1;6655:248:51:o;7155:247::-;7214:6;7267:2;7255:9;7246:7;7242:23;7238:32;7235:52;;;7283:1;7280;7273:12;7235:52;7322:9;7309:23;7341:31;7366:5;7341:31;:::i;7407:163::-;7474:20;;7534:10;7523:22;;7513:33;;7503:61;;7560:1;7557;7550:12;7575:864;7662:6;7715:3;7703:9;7694:7;7690:23;7686:33;7683:53;;;7732:1;7729;7722:12;7683:53;7765:2;7759:9;7807:3;7799:6;7795:16;7877:6;7865:10;7862:22;7841:18;7829:10;7826:34;7823:62;7820:88;;;7888:18;;:::i;:::-;7924:2;7917:22;7961:23;;7993:31;7961:23;7993:31;:::i;:::-;8033:21;;8106:2;8091:18;;8078:32;8119:33;8078:32;8119:33;:::i;:::-;8180:2;8168:15;;8161:32;8226:37;8259:2;8244:18;;8226:37;:::i;:::-;8221:2;8213:6;8209:15;8202:62;8297:37;8330:2;8319:9;8315:18;8297:37;:::i;:::-;8292:2;8284:6;8280:15;8273:62;8369:38;8402:3;8391:9;8387:19;8369:38;:::i;:::-;8363:3;8351:16;;8344:64;8355:6;7575:864;-1:-1:-1;;;7575:864:51:o;9011:724::-;9246:2;9298:21;;;9368:13;;9271:18;;;9390:22;;;9217:4;;9246:2;9469:15;;;;9443:2;9428:18;;;9217:4;9512:197;9526:6;9523:1;9520:13;9512:197;;;9575:52;9623:3;9614:6;9608:13;8522:6;8567:2;8559:5;8553:12;8549:21;8544:3;8537:34;8632:2;8624:4;8617:5;8613:16;8607:23;8603:32;8596:4;8591:3;8587:14;8580:56;8697:2;8689:4;8682:5;8678:16;8672:23;8668:32;8661:4;8656:3;8652:14;8645:56;;8762:4;8754;8747:5;8743:16;8737:23;8733:34;8726:4;8721:3;8717:14;8710:58;8814:4;8807:5;8803:16;8797:23;-1:-1:-1;;;;;8931:2:51;8917:12;8913:21;8906:4;8901:3;8897:14;8890:45;8996:2;8988:4;8981:5;8977:16;8971:23;8967:32;8960:4;8955:3;8951:14;8944:56;;;8444:562;;;9575:52;9684:15;;;;9656:4;9647:14;;;;;9548:1;9541:9;9512:197;;;-1:-1:-1;9726:3:51;;9011:724;-1:-1:-1;;;;;;9011:724:51:o;9740:437::-;9826:6;9834;9887:2;9875:9;9866:7;9862:23;9858:32;9855:52;;;9903:1;9900;9893:12;9855:52;9943:9;9930:23;9976:18;9968:6;9965:30;9962:50;;;10008:1;10005;9998:12;9962:50;10047:70;10109:7;10100:6;10089:9;10085:22;10047:70;:::i;:::-;10136:8;;10021:96;;-1:-1:-1;9740:437:51;-1:-1:-1;;;;9740:437:51:o;10182:456::-;10259:6;10267;10275;10328:2;10316:9;10307:7;10303:23;10299:32;10296:52;;;10344:1;10341;10334:12;10296:52;10383:9;10370:23;10402:31;10427:5;10402:31;:::i;:::-;10452:5;-1:-1:-1;10509:2:51;10494:18;;10481:32;10522:33;10481:32;10522:33;:::i;:::-;10182:456;;10574:7;;-1:-1:-1;;;10628:2:51;10613:18;;;;10600:32;;10182:456::o;13330:1081::-;13423:6;13431;13484:2;13472:9;13463:7;13459:23;13455:32;13452:52;;;13500:1;13497;13490:12;13452:52;13539:9;13526:23;13558:31;13583:5;13558:31;:::i;:::-;13608:5;-1:-1:-1;13632:2:51;13670:18;;;13657:32;13708:18;13738:14;;;13735:34;;;13765:1;13762;13755:12;13735:34;13803:6;13792:9;13788:22;13778:32;;13848:7;13841:4;13837:2;13833:13;13829:27;13819:55;;13870:1;13867;13860:12;13819:55;13906:2;13893:16;13928:2;13924;13921:10;13918:36;;;13934:18;;:::i;:::-;13980:2;13977:1;13973:10;13963:20;;14003:28;14027:2;14023;14019:11;14003:28;:::i;:::-;14065:15;;;14135:11;;;14131:20;;;14096:12;;;;14163:19;;;14160:39;;;14195:1;14192;14185:12;14160:39;14219:11;;;;14239:142;14255:6;14250:3;14247:15;14239:142;;;14321:17;;14309:30;;14272:12;;;;14359;;;;14239:142;;;14400:5;14390:15;;;;;;;;13330:1081;;;;;:::o;15013:159::-;15080:20;;15140:6;15129:18;;15119:29;;15109:57;;15162:1;15159;15152:12;15177:114;15261:4;15254:5;15250:16;15243:5;15240:27;15230:55;;15281:1;15278;15271:12;15296:1007;15387:6;15440:3;15428:9;15419:7;15415:23;15411:33;15408:53;;;15457:1;15454;15447:12;15408:53;15490:2;15484:9;15532:3;15524:6;15520:16;15602:6;15590:10;15587:22;15566:18;15554:10;15551:34;15548:62;15545:88;;;15613:18;;:::i;:::-;15649:2;15642:22;15688:28;15706:9;15688:28;:::i;:::-;15680:6;15673:44;15750:37;15783:2;15772:9;15768:18;15750:37;:::i;:::-;15745:2;15737:6;15733:15;15726:62;15821:37;15854:2;15843:9;15839:18;15821:37;:::i;:::-;15816:2;15808:6;15804:15;15797:62;15909:2;15898:9;15894:18;15881:32;15922:29;15945:5;15922:29;:::i;:::-;15979:2;15967:15;;15960:30;16042:3;16027:19;;16014:33;16056;16014;16056;:::i;:::-;16117:3;16105:16;;16098:33;16183:3;16168:19;;16155:33;16197;16155;16197;:::i;:::-;16258:3;16246:16;;16239:33;16250:6;15296:1007;-1:-1:-1;;;15296:1007:51:o;16308:1131::-;16432:6;16440;16448;16456;16464;16472;16480;16533:3;16521:9;16512:7;16508:23;16504:33;16501:53;;;16550:1;16547;16540:12;16501:53;16589:9;16576:23;16608:31;16633:5;16608:31;:::i;:::-;16658:5;-1:-1:-1;16710:2:51;16695:18;;16682:32;;-1:-1:-1;16761:2:51;16746:18;;16733:32;;-1:-1:-1;16816:2:51;16801:18;;16788:32;16839:18;16869:14;;;16866:34;;;16896:1;16893;16886:12;16866:34;16934:6;16923:9;16919:22;16909:32;;16979:7;16972:4;16968:2;16964:13;16960:27;16950:55;;17001:1;16998;16991:12;16950:55;17041:2;17028:16;17067:2;17059:6;17056:14;17053:34;;;17083:1;17080;17073:12;17053:34;17128:7;17123:2;17114:6;17110:2;17106:15;17102:24;17099:37;17096:57;;;17149:1;17146;17139:12;17096:57;17180:2;17176;17172:11;17162:21;;17202:6;17192:16;;;17255:3;17244:9;17240:19;17227:33;17217:43;;17313:3;17302:9;17298:19;17285:33;17269:49;;17343:2;17333:8;17330:16;17327:36;;;17359:1;17356;17349:12;17327:36;;17382:51;17425:7;17414:8;17403:9;17399:24;17382:51;:::i;:::-;17372:61;;;16308:1131;;;;;;;;;;:::o;17444:241::-;17500:6;17553:2;17541:9;17532:7;17528:23;17524:32;17521:52;;;17569:1;17566;17559:12;17521:52;17608:9;17595:23;17627:28;17649:5;17627:28;:::i;18042:184::-;-1:-1:-1;;;18091:1:51;18084:88;18191:4;18188:1;18181:15;18215:4;18212:1;18205:15;18231:128;18298:9;;;18319:11;;;18316:37;;;18333:18;;:::i;19040:245::-;19107:6;19160:2;19148:9;19139:7;19135:23;19131:32;19128:52;;;19176:1;19173;19166:12;19128:52;19208:9;19202:16;19227:28;19249:5;19227:28;:::i;19997:184::-;20067:6;20120:2;20108:9;20099:7;20095:23;20091:32;20088:52;;;20136:1;20133;20126:12;20088:52;-1:-1:-1;20159:16:51;;19997:184;-1:-1:-1;19997:184:51:o;20542:::-;-1:-1:-1;;;20591:1:51;20584:88;20691:4;20688:1;20681:15;20715:4;20712:1;20705:15;20731:195;20770:3;-1:-1:-1;;20794:5:51;20791:77;20788:103;;20871:18;;:::i;:::-;-1:-1:-1;20918:1:51;20907:13;;20731:195::o;23058:261::-;23237:2;23226:9;23219:21;23200:4;23257:56;23309:2;23298:9;23294:18;23286:6;23257:56;:::i;24016:250::-;24101:1;24111:113;24125:6;24122:1;24119:13;24111:113;;;24201:11;;;24195:18;24182:11;;;24175:39;24147:2;24140:10;24111:113;;;-1:-1:-1;;24258:1:51;24240:16;;24233:27;24016:250::o;24271:329::-;24312:3;24350:5;24344:12;24377:6;24372:3;24365:19;24393:76;24462:6;24455:4;24450:3;24446:14;24439:4;24432:5;24428:16;24393:76;:::i;:::-;24514:2;24502:15;-1:-1:-1;;24498:88:51;24489:98;;;;24589:4;24485:109;;24271:329;-1:-1:-1;;24271:329:51:o;24605:1065::-;24911:4;-1:-1:-1;;;;;25021:2:51;25013:6;25009:15;24998:9;24991:34;25061:6;25056:2;25045:9;25041:18;25034:34;25104:6;25099:2;25088:9;25084:18;25077:34;25147:3;25142:2;25131:9;25127:18;25120:31;25188:6;25182:3;25171:9;25167:19;25160:35;25214:3;25267:6;25259;25254:2;25243:9;25239:18;25226:48;25323:1;25318:2;25309:6;25298:9;25294:22;25290:31;25283:42;-1:-1:-1;;25375:2:51;25367:6;25363:15;25359:88;25348:9;25344:104;25485:6;25479:3;25468:9;25464:19;25457:35;25553:2;25541:9;25537:2;25533:18;25529:27;25523:3;25512:9;25508:19;25501:56;25574:37;25607:2;25603;25599:11;25591:6;25574:37;:::i;:::-;25566:45;;;;25660:2;25652:6;25648:15;25642:3;25631:9;25627:19;25620:44;;24605:1065;;;;;;;;;;;:::o;26082:179::-;26160:13;;26213:22;26202:34;;26192:45;;26182:73;;26251:1;26248;26241:12;26266:473;26369:6;26377;26385;26393;26401;26454:3;26442:9;26433:7;26429:23;26425:33;26422:53;;;26471:1;26468;26461:12;26422:53;26494:39;26523:9;26494:39;:::i;:::-;26484:49;;26573:2;26562:9;26558:18;26552:25;26542:35;;26617:2;26606:9;26602:18;26596:25;26586:35;;26661:2;26650:9;26646:18;26640:25;26630:35;;26684:49;26728:3;26717:9;26713:19;26684:49;:::i;:::-;26674:59;;26266:473;;;;;;;;:::o;26933:274::-;26973:1;26999;26989:189;;-1:-1:-1;;;27031:1:51;27024:88;27135:4;27132:1;27125:15;27163:4;27160:1;27153:15;26989:189;-1:-1:-1;27192:9:51;;26933:274::o;27212:168::-;27285:9;;;27316;;27333:15;;;27327:22;;27313:37;27303:71;;27354:18;;:::i;29389:125::-;29454:9;;;29475:10;;;29472:36;;;29488:18;;:::i;29865:290::-;29974:6;30027:2;30015:9;30006:7;30002:23;29998:32;29995:52;;;30043:1;30040;30033:12;29995:52;30075:9;30069:16;30094:31;30119:5;30094:31;:::i;31280:198::-;31322:3;31360:5;31354:12;31375:65;31433:6;31428:3;31421:4;31414:5;31410:16;31375:65;:::i;:::-;31456:16;;;;;31280:198;-1:-1:-1;;31280:198:51:o;31483:1318::-;31659:3;31688:1;31721:6;31715:13;31751:3;31773:1;31801:9;31797:2;31793:18;31783:28;;31861:2;31850:9;31846:18;31883;31873:61;;31927:4;31919:6;31915:17;31905:27;;31873:61;31953:2;32001;31993:6;31990:14;31970:18;31967:38;31964:222;;-1:-1:-1;;;32035:3:51;32028:90;32141:4;32138:1;32131:15;32171:4;32166:3;32159:17;31964:222;32202:18;32229:191;;;;32434:1;32429:320;;;;32195:554;;32229:191;-1:-1:-1;;32266:9:51;32262:82;32257:3;32250:95;32400:6;32393:14;32386:22;32378:6;32374:35;32369:3;32365:45;32358:52;;32229:191;;32429:320;31227:1;31220:14;;;31264:4;31251:18;;32524:1;32538:165;32552:6;32549:1;32546:13;32538:165;;;32630:14;;32617:11;;;32610:35;32673:16;;;;32567:10;;32538:165;;;32542:3;;32732:6;32727:3;32723:16;32716:23;;32195:554;;;;;;;32765:30;32791:3;32783:6;32765:30;:::i;:::-;32758:37;31483:1318;-1:-1:-1;;;;;31483:1318:51:o;32806:172::-;32873:10;32903;;;32915;;;32899:27;;32938:11;;;32935:37;;;32952:18;;:::i;36034:247::-;36102:6;36155:2;36143:9;36134:7;36130:23;36126:32;36123:52;;;36171:1;36168;36161:12;36123:52;36203:9;36197:16;36222:29;36245:5;36222:29;:::i;37687:268::-;37885:3;37870:19;;37898:51;37874:9;37931:6;8522;8567:2;8559:5;8553:12;8549:21;8544:3;8537:34;8632:2;8624:4;8617:5;8613:16;8607:23;8603:32;8596:4;8591:3;8587:14;8580:56;8697:2;8689:4;8682:5;8678:16;8672:23;8668:32;8661:4;8656:3;8652:14;8645:56;;8762:4;8754;8747:5;8743:16;8737:23;8733:34;8726:4;8721:3;8717:14;8710:58;8814:4;8807:5;8803:16;8797:23;-1:-1:-1;;;;;8931:2:51;8917:12;8913:21;8906:4;8901:3;8897:14;8890:45;8996:2;8988:4;8981:5;8977:16;8971:23;8967:32;8960:4;8955:3;8951:14;8944:56;;;8444:562;;;37960:482;38049:1;38092:5;38049:1;38106:330;38127:7;38117:8;38114:21;38106:330;;;38246:4;-1:-1:-1;;38174:77:51;38168:4;38165:87;38162:113;;;38255:18;;:::i;:::-;38305:7;38295:8;38291:22;38288:55;;;38325:16;;;;38288:55;38404:22;;;;38364:15;;;;38106:330;;;38110:3;37960:482;;;;;:::o;38447:866::-;38496:5;38526:8;38516:80;;-1:-1:-1;38567:1:51;38581:5;;38516:80;38615:4;38605:76;;-1:-1:-1;38652:1:51;38666:5;;38605:76;38697:4;38715:1;38710:59;;;;38783:1;38778:130;;;;38690:218;;38710:59;38740:1;38731:10;;38754:5;;;38778:130;38815:3;38805:8;38802:17;38799:43;;;38822:18;;:::i;:::-;-1:-1:-1;;38878:1:51;38864:16;;38893:5;;38690:218;;38992:2;38982:8;38979:16;38973:3;38967:4;38964:13;38960:36;38954:2;38944:8;38941:16;38936:2;38930:4;38927:12;38923:35;38920:77;38917:159;;;-1:-1:-1;39029:19:51;;;39061:5;;38917:159;39108:34;39133:8;39127:4;39108:34;:::i;:::-;39238:6;-1:-1:-1;;39166:79:51;39157:7;39154:92;39151:118;;;39249:18;;:::i;:::-;39287:20;;38447:866;-1:-1:-1;;;38447:866:51:o;39318:131::-;39378:5;39407:36;39434:8;39428:4;39407:36;:::i;40159:539::-;40422:2;40411:9;40404:21;40385:4;40448:44;40488:2;40477:9;40473:18;40465:6;40448:44;:::i;:::-;40540:9;40532:6;40528:22;40523:2;40512:9;40508:18;40501:50;40568:32;40593:6;40585;40568:32;:::i;:::-;40560:40;;;-1:-1:-1;;;;;40640:6:51;40636:55;40631:2;40620:9;40616:18;40609:83;40159:539;;;;;;:::o;41114:184::-;-1:-1:-1;;;41163:1:51;41156:88;41263:4;41260:1;41253:15;41287:4;41284:1;41277:15;42061:287;42190:3;42228:6;42222:13;42244:66;42303:6;42298:3;42291:4;42283:6;42279:17;42244:66;:::i;:::-;42326:16;;;;;42061:287;-1:-1:-1;;42061:287:51:o;42711:219::-;42860:2;42849:9;42842:21;42823:4;42880:44;42920:2;42909:9;42905:18;42897:6;42880:44;:::i
Swarm Source
ipfs://decd3853b6f9dc7408f97569a16fbf24d058d5955cc03659b32c600e26e9415a
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
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.