Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
9.124874 ETH
Eth Value
$30,449.27 (@ $3,336.95/ETH)Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 7,329 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Claim Refund | 18481981 | 417 days ago | IN | 0 ETH | 0.00117538 | ||||
Claim Prizes | 18192063 | 457 days ago | IN | 0 ETH | 0.00098912 | ||||
Claim Refund | 18141404 | 465 days ago | IN | 0 ETH | 0.0005965 | ||||
Claim Refund | 18124938 | 467 days ago | IN | 0 ETH | 0.00036553 | ||||
Claim Refund | 18123792 | 467 days ago | IN | 0 ETH | 0.0004057 | ||||
Claim Refund | 18122468 | 467 days ago | IN | 0 ETH | 0.00076044 | ||||
Claim Refund | 18122466 | 467 days ago | IN | 0 ETH | 0.00074353 | ||||
Claim Refund | 18121319 | 467 days ago | IN | 0 ETH | 0.001399 | ||||
Claim Refund | 18121021 | 467 days ago | IN | 0 ETH | 0.0011249 | ||||
Claim Refund | 18121004 | 467 days ago | IN | 0 ETH | 0.00097387 | ||||
Claim Refund | 18120927 | 467 days ago | IN | 0 ETH | 0.00091079 | ||||
Claim Refund | 18120768 | 467 days ago | IN | 0 ETH | 0.00111018 | ||||
Claim Refund | 18120763 | 467 days ago | IN | 0 ETH | 0.00113406 | ||||
Claim Refund | 18120565 | 467 days ago | IN | 0 ETH | 0.0011338 | ||||
Claim Refund | 18119247 | 468 days ago | IN | 0 ETH | 0.00054106 | ||||
Claim Refund | 18118948 | 468 days ago | IN | 0 ETH | 0.00043506 | ||||
Claim Refund | 17899463 | 498 days ago | IN | 0 ETH | 0.00070024 | ||||
Claim Prizes | 17887580 | 500 days ago | IN | 0 ETH | 0.00129321 | ||||
Claim Refund | 17847698 | 506 days ago | IN | 0 ETH | 0.0005906 | ||||
Claim Refund | 17795733 | 513 days ago | IN | 0 ETH | 0.00076385 | ||||
Claim Refund | 17795732 | 513 days ago | IN | 0 ETH | 0.00076342 | ||||
Claim Prizes | 17794307 | 513 days ago | IN | 0 ETH | 0.00175894 | ||||
Claim Prizes | 17794096 | 513 days ago | IN | 0 ETH | 0.00277259 | ||||
Claim Refund | 17768539 | 517 days ago | IN | 0 ETH | 0.00089421 | ||||
Claim Refund | 17699443 | 526 days ago | IN | 0 ETH | 0.00062885 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
18141404 | 465 days ago | 0.0196 ETH | ||||
18124938 | 467 days ago | 0.0196 ETH | ||||
18123792 | 467 days ago | 0.11 ETH | ||||
18122468 | 467 days ago | 0.1372 ETH | ||||
18122466 | 467 days ago | 0.11 ETH | ||||
18121319 | 467 days ago | 0.0196 ETH | ||||
18121021 | 467 days ago | 1.47 ETH | ||||
18121004 | 467 days ago | 0.98 ETH | ||||
18120927 | 467 days ago | 0.0392 ETH | ||||
18120768 | 467 days ago | 0.0196 ETH | ||||
18120763 | 467 days ago | 0.0196 ETH | ||||
18120565 | 467 days ago | 0.11 ETH | ||||
18119247 | 468 days ago | 0.294 ETH | ||||
18118948 | 468 days ago | 0.11 ETH | ||||
17899463 | 498 days ago | 0.196 ETH | ||||
17847698 | 506 days ago | 0.0196 ETH | ||||
17795733 | 513 days ago | 0.0196 ETH | ||||
17795732 | 513 days ago | 0.024 ETH | ||||
17768539 | 517 days ago | 0.11 ETH | ||||
17699443 | 526 days ago | 0.024 ETH | ||||
17688499 | 528 days ago | 0.024 ETH | ||||
17684934 | 528 days ago | 0.0196 ETH | ||||
17621653 | 537 days ago | 0.0196 ETH | ||||
17621134 | 537 days ago | 0.024 ETH | ||||
17621072 | 537 days ago | 0.024 ETH |
Loading...
Loading
Contract Name:
Raffle
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {LowLevelWETH} from "@looksrare/contracts-libs/contracts/lowLevelCallers/LowLevelWETH.sol"; import {LowLevelERC20Transfer} from "@looksrare/contracts-libs/contracts/lowLevelCallers/LowLevelERC20Transfer.sol"; import {LowLevelERC721Transfer} from "@looksrare/contracts-libs/contracts/lowLevelCallers/LowLevelERC721Transfer.sol"; import {LowLevelERC1155Transfer} from "@looksrare/contracts-libs/contracts/lowLevelCallers/LowLevelERC1155Transfer.sol"; import {OwnableTwoSteps} from "@looksrare/contracts-libs/contracts/OwnableTwoSteps.sol"; import {PackableReentrancyGuard} from "@looksrare/contracts-libs/contracts/PackableReentrancyGuard.sol"; import {Pausable} from "@looksrare/contracts-libs/contracts/Pausable.sol"; import {VRFCoordinatorV2Interface} from "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol"; import {VRFConsumerBaseV2} from "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol"; import {Arrays} from "./libraries/Arrays.sol"; import {WinningEntrySearchLogic} from "./WinningEntrySearchLogic.sol"; import "./interfaces/IRaffle.sol"; // .................................................................................................... // .......................................,,,,,,....................................................... // ....................................,;+??????*;;:..................,,,,,,,,......................... // ..................................,+?????????????*;,............:;*????????*;,...................... // ................................,+??????????????*???+,.......:+*??????????????*:.................... // ..............................:+?????????*????????*???+:,.,;*???????????????????*,.................. // ............................,*???????????%%%%%%%%%%??*???*???????????????????????*,................. // ..........................,;???????????%%??????????%%%?*????????????????????????*?;................. // .........................:???????????%%???????????????%%???????*?????????????*?**?*................. // ........................:%%%???????%%?*??????????????**?%?**???%%%%%%%%%%%%%%??????,,,,............. // ......................,*SSSSS?????%?*??????????*??????%??%%??????????????***???????????*;:.......... // .....................:%S%%%%SS??????????????*??%%%%%%%?????%%%%??*????????????????????????+,........ // ....................:SS%%%%%%#?*????????????%%%????**???????*??%%%?*??%%%%%%%?????????%%%%%:........ // ....................+S?%%%%%%S%*?????????*?%%?**??%%%%%%%%%%%??*?%??%%??????????%%%%%?????%?+,...... // ..................,;%%%%%%%%%%S*???????*??%?*??%%%???????????%%%??S%????%%%%%%???????%%%%????*,..... // .................;?S#%%%%?SS%%S*???????%%%?*?%%??*??****????????%%%?%%%?????????*++++*?%%%%%??:..... // ...............,*%?S%%%%%%S%%SS*????%%%????%%??*????%SSS##S***?????%???*????*;,,:::;:,,:+???%S+..... // ..............,*?*?S%%%%%%#SSS?????%???*?%%???????%@@@@@@##S:.,:+????????+:,..:%@@@%@#*,..:*???+.... // ..............+????S%%%%%%S%???????????%%??*???+:+#@@@@@SS@@#:...,;????+,....;@@@@@%@@@#+...:???:... // .............:?????S%%%%%%S*????%%%%%%%??????+,.,#+S@@@;.+@@@%.....+%*,.....,S@@@@@?;*#@@+...,+?,... // .............*?????S%%%%%%S*????%**???**???+,...?@#@@@S..,#@@@;....;*.......+%?@@@%...;@@#,....;:... // ............;??????S%%%%%%S?????%%???????+,....,#@@@@@#:.,#@@@%....;,.......S@@@@@*....#@@+....,;... // ...........,???????S%%%%%%S????????%%%%:,......:@@@@@@@S*%@@@@#,..,;.......,#@@@@@?....S@@%....:;... // ...........;???????%S%%%%%SS*??????**???:......:@@@@@@@@@@@@@@@+..::.......,@@@@@@#;,.;@@@#,..,+,... // ..........,?????????S%%%%%%S?????????????*:....,#@@@@@@@@@@@@@@?.,+:.......,@@@@@@@@#S@@@@@:.;+,.... // ..........;????????*S%%%%%%SS*?????????????*:...S@@@@@@@@@@@@@@S+?%*::,....,#@@@@@@@@@@@@@@?*%;..... // ..........*????????*SS%S#S?%S??????????%?**??*;,*@@@@@@@@@@@@#S%???%???**+;:S@@@@@@@@##S%?????:..... // .........:?????????*%#S%%S%%%S???*??????%%%??????####@@@@#S%?***?%%?????????%%%%??????*****?*:...... // .........*?????????*%#?*%S%%%S?*?%%%%%%%%?%%%%%%%%???????****??%%%????????????????????????%;........ // ........:?????????*%#?**S%?%%%S%%%?????%%%%%????????%%%%%%%%%%%?????????????%%%%%%%%%%%%%%+......... // ........*??????????#%*?*%SSSS%S#???????????%%%%%??***???????????????????????*??*??*?????*%+:........ // .......:?????????*%#?????%%%S%%S%??????????????%%%%%???***??????????????????????????**??%%%%+....... // .......*??????????#%*???***S%%%%#????S#S%%?????????%%%%%%?????*?????????????????**???%%%%????....... // ......:?????????*SS*???????SSSS%SS??SS%S#%%%%???????????%%%%%%%%?????????????????%%%%%???????....... // ......+????????*?#????????????%S%SSSS%%%SS?%%%%%%?????????????%%%%%%%%%%%%%%%%%%%%?????????%+....... // ......*?????????#S??????????*?S%%%SS%%%%%S%????%%%%%?????????????????????????????????????%%+,....... // ......*???????*%#SS?????????*%%%%%%%%%%%%%#???????%%%%%%%?????????????????????????????%%?+:......... // ......*????????SS%SS?*?????*%%%%%%%%%%%%%%SS???????????%%%%%%%??????????????????%%%%%%%%*........... // .....;S%???????#%%%SS?*???*%#%%%%%%%%%%%%%%#%%?????????????%%%%%%%%%%%%%%%%%%%%%%%%??????,.......... // ...,?SSS%*???*SS%%%%S#?*?*%#%#%%%%%%%%%%%%%S?%%%%????????????????????????????????????????,.......... // ...?S%%%S?*???S%%%%%%S#?*?#?*%SS%%%%%%%%%%%S?*??%%%%???????????????????????????????????%?........... // .,?S%%%%SS%?*%S%%%%%%%SS?S%*?*?SS%%%%%%%%%%S????*??%%%%%%%????????????????????????????%%:........... // .*#%%%%%%%SS%S%%%%%%%%%S#S??????%S#S%%%%?%SS???????*?????%%%%%%%%%%%%%%%%%??????????%%*:............ // ;S%%%%%%%%%S#S%%%%%%%%%S#????????*?SSSSSSS#??????????????*?????????%%%%%%%%%%%%%S%??+,.............. // %S%%%%%%%%%SS%%%%%%%%%%S%*????????**%%%%%##????????????????????????*******??????+,.................. // S%%%%%%%%%SS%%%%%%%%%%S#%%?????**???****?SS%*??????????????????????????????**+:,.................... // %%%%%%%%S#S%%%%%%%%%%%S???%%%%%%?????????SSS*??????????????????***??+;;;::,......................... // %%%%%%%S#S%%%%%%%%%%%SS?***??????%%%%%%%%SSS?????????????????????%?:................................ // %%%%%%SSS%%%%%%%%%%%S#SS%????*****???????%SS%%%%%%%%%%%%%%%%%??%%+,................................. // %%%%%%%%%%%%%%%%%%%%SS%SSSSSS%%????******%SS?************?***?%*:................................... // %%%%%%%%%%%%%%%%%%%%#S%%%%%%SSSSSSS%%%???%SS%???????????????%S#+.................................... // %%%%%%%%%%%%%%%%%%%S#%%%%%%%%%%%%%SSSSSSSS#%#SSSSSSSSSSSSSSSS%S%,................................... // %%%%%%%%%%%%%%%%%%%#S%%%%%%%%%%%%%%%%%S####%#%%%%%%%%%%%%%%%%%%S+................................... // %%%%%%%%%%%%%%%%%%S#%%%%%%%%%%%%%%%%%%#S%S@%#S%%%%%%%%%%%%%%%%%S%,.................................. // %%%%%%%%%%%%%%%%%%#S%%%%%%%%%%%%%%%%%SS%#S#%SS%%%%%%%%%%%%%%%%%%S*.................................. // %%%%%%%%%%%%%%%%%S#S%%%%%%%%%%%%%%%%%SSSS##S%#%%%%%%%%%%%%%%%%%%%S:................................. // %%%%%%%%%%%%%%%%%SS%%%%%%%%%%%%%%%%%%%#####%%#%%%%%%%%%%%%%%%%%%%S*................................. // %%%%%%%%%%%%%%%%%#S%%%%%%%%%%%%%%%%%%%S#S%%?S#%%%%%%%%%%%%%%%%%%%SS,................................ // %%%%%%%%%%%%%%%%S#S%%%%%%%%%%%%%%%%%%%%S#SS##S%%%%%%%%%%%%%%%%%%%%S;................................ // %%%%%%%%%%%%%%%%SS%%%%%%%%%%%%%%%%%%%%%%SS##S%%%%%%%%%%%%%%%%%%%%%S?................................ // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%SSS%%%%%%%%%%%%%%%%%%%%%S%,............................... // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%#SS%%%%%%%%%%%%%%%%%%%%%%S:............................... // ...................... [Calling the blockchain to get provably fair results] ....................... /** * @title Raffle * @notice This contract allows anyone to permissionlessly host raffles on LooksRare. * @author LooksRare protocol team (👀,💎) */ contract Raffle is IRaffle, LowLevelWETH, LowLevelERC20Transfer, LowLevelERC721Transfer, LowLevelERC1155Transfer, VRFConsumerBaseV2, OwnableTwoSteps, PackableReentrancyGuard, Pausable, WinningEntrySearchLogic { using Arrays for uint256[]; address public immutable WETH; uint256 public constant ONE_DAY = 86_400 seconds; uint256 public constant ONE_WEEK = 604_800 seconds; /** * @notice 100% in basis points. */ uint256 public constant ONE_HUNDRED_PERCENT_BP = 10_000; /** * @notice The number of raffles created. */ uint256 public rafflesCount; /** * @notice The raffles created. * @dev The key is the raffle ID. */ mapping(uint256 => Raffle) public raffles; /** * @notice The participants stats of the raffles. * @dev The key is the raffle ID and the nested key is the participant address. */ mapping(uint256 => mapping(address => ParticipantStats)) public rafflesParticipantsStats; /** * @notice It checks whether the currency is allowed. */ mapping(address => bool) public isCurrencyAllowed; /** * @notice The maximum number of prizes per raffle. * Each individual ERC-721 counts as one prize. * Each ETH/ERC-20/ERC-1155 with winnersCount > 1 counts as one prize. */ uint256 public constant MAXIMUM_NUMBER_OF_PRIZES_PER_RAFFLE = 20; /** * @notice The maximum number of winners per raffle. */ uint40 public constant MAXIMUM_NUMBER_OF_WINNERS_PER_RAFFLE = 110; /** * @notice A Chainlink node should wait for 3 confirmations before responding. */ uint16 public constant REQUEST_CONFIRMATIONS = 3; /** * @notice The key hash of the Chainlink VRF. */ bytes32 public immutable KEY_HASH; /** * @notice The subscription ID of the Chainlink VRF. */ uint64 public immutable SUBSCRIPTION_ID; /** * @notice The Chainlink VRF coordinator. */ VRFCoordinatorV2Interface public immutable VRF_COORDINATOR; /** * @notice The randomness requests. * @dev The key is the request ID returned by Chainlink. */ mapping(uint256 => RandomnessRequest) public randomnessRequests; /** * @notice The maximum protocol fee in basis points, which is 25%. */ uint16 public constant MAXIMUM_PROTOCOL_FEE_BP = 2_500; /** * @notice The protocol fee recipient. */ address public protocolFeeRecipient; /** * @notice The protocol fee in basis points. */ uint16 public protocolFeeBp; /** * @notice The claimable fees of the protocol fee recipient. * @dev The key is the currency address. */ mapping(address => uint256) public protocolFeeRecipientClaimableFees; /** * @notice The number of pricing options per raffle. */ uint256 public constant PRICING_OPTIONS_PER_RAFFLE = 5; /** * @param _weth The WETH address * @param _keyHash Chainlink VRF key hash * @param _subscriptionId Chainlink VRF subscription ID * @param _vrfCoordinator Chainlink VRF coordinator address * @param _owner The owner of the contract * @param _protocolFeeRecipient The recipient of the protocol fees * @param _protocolFeeBp The protocol fee in basis points */ constructor( address _weth, bytes32 _keyHash, uint64 _subscriptionId, address _vrfCoordinator, address _owner, address _protocolFeeRecipient, uint16 _protocolFeeBp ) VRFConsumerBaseV2(_vrfCoordinator) OwnableTwoSteps(_owner) { _setProtocolFeeBp(_protocolFeeBp); _setProtocolFeeRecipient(_protocolFeeRecipient); WETH = _weth; KEY_HASH = _keyHash; VRF_COORDINATOR = VRFCoordinatorV2Interface(_vrfCoordinator); SUBSCRIPTION_ID = _subscriptionId; } /** * @inheritdoc IRaffle * @dev This function can still be called when the contract is paused because the raffle creator * would not be able to deposit prizes and open the raffle anyway. The restriction to disallow * raffles creation when the contract is paused will be enforced in the frontend. */ function createRaffle(CreateRaffleCalldata calldata params) external returns (uint256 raffleId) { uint40 cutoffTime = params.cutoffTime; if (_unsafeAdd(block.timestamp, ONE_DAY) > cutoffTime || cutoffTime > _unsafeAdd(block.timestamp, ONE_WEEK)) { revert InvalidCutoffTime(); } uint16 agreedProtocolFeeBp = params.protocolFeeBp; if (agreedProtocolFeeBp != protocolFeeBp) { revert InvalidProtocolFeeBp(); } address feeTokenAddress = params.feeTokenAddress; if (feeTokenAddress != address(0)) { if (!isCurrencyAllowed[feeTokenAddress]) { revert InvalidCurrency(); } } unchecked { raffleId = ++rafflesCount; } uint256 prizesCount = params.prizes.length; if (prizesCount == 0 || prizesCount > MAXIMUM_NUMBER_OF_PRIZES_PER_RAFFLE) { revert InvalidPrizesCount(); } Raffle storage raffle = raffles[raffleId]; uint40 cumulativeWinnersCount; uint8 currentPrizeTier; for (uint256 i; i < prizesCount; ) { Prize memory prize = params.prizes[i]; if (prize.prizeTier < currentPrizeTier) { revert InvalidPrize(); } _validatePrize(prize); cumulativeWinnersCount += prize.winnersCount; prize.cumulativeWinnersCount = cumulativeWinnersCount; currentPrizeTier = prize.prizeTier; raffle.prizes.push(prize); unchecked { ++i; } } uint40 minimumEntries = params.minimumEntries; if (cumulativeWinnersCount > minimumEntries || cumulativeWinnersCount > MAXIMUM_NUMBER_OF_WINNERS_PER_RAFFLE) { revert InvalidWinnersCount(); } _validateAndSetPricingOptions(raffleId, params.pricingOptions); raffle.owner = msg.sender; raffle.isMinimumEntriesFixed = params.isMinimumEntriesFixed; raffle.cutoffTime = cutoffTime; raffle.minimumEntries = minimumEntries; raffle.maximumEntriesPerParticipant = params.maximumEntriesPerParticipant; raffle.protocolFeeBp = agreedProtocolFeeBp; raffle.feeTokenAddress = feeTokenAddress; _setRaffleStatus(raffle, raffleId, RaffleStatus.Created); } /** * @inheritdoc IRaffle */ function depositPrizes(uint256 raffleId) external payable nonReentrant whenNotPaused { Raffle storage raffle = raffles[raffleId]; _validateRaffleStatus(raffle, RaffleStatus.Created); _validateCaller(raffle.owner); Prize[] storage prizes = raffle.prizes; uint256 prizesCount = prizes.length; uint256 expectedEthValue; for (uint256 i; i < prizesCount; ) { Prize storage prize = prizes[i]; TokenType prizeType = prize.prizeType; if (prizeType == TokenType.ERC721) { _executeERC721TransferFrom(prize.prizeAddress, msg.sender, address(this), prize.prizeId); } else if (prizeType == TokenType.ERC20) { _executeERC20TransferFrom( prize.prizeAddress, msg.sender, address(this), prize.prizeAmount * prize.winnersCount ); } else if (prizeType == TokenType.ETH) { expectedEthValue += (prize.prizeAmount * prize.winnersCount); } else { _executeERC1155SafeTransferFrom( prize.prizeAddress, msg.sender, address(this), prize.prizeId, prize.prizeAmount * prize.winnersCount ); } unchecked { ++i; } } _validateExpectedEthValueOrRefund(expectedEthValue); _setRaffleStatus(raffle, raffleId, RaffleStatus.Open); } /** * @dev This function is required in order for the contract to receive ERC-1155 tokens. */ function onERC1155Received( address, address, uint256, uint256, bytes calldata ) external pure returns (bytes4) { return this.onERC1155Received.selector; } /** * @inheritdoc IRaffle */ function enterRaffles(EntryCalldata[] calldata entries) external payable nonReentrant whenNotPaused { uint256 entriesCount = entries.length; uint208 expectedEthValue; for (uint256 i; i < entriesCount; ) { EntryCalldata calldata entry = entries[i]; if (entry.pricingOptionIndex >= PRICING_OPTIONS_PER_RAFFLE) { revert InvalidIndex(); } uint256 raffleId = entry.raffleId; Raffle storage raffle = raffles[raffleId]; _validateRaffleStatus(raffle, RaffleStatus.Open); if (block.timestamp >= raffle.cutoffTime) { revert CutoffTimeReached(); } PricingOption memory pricingOption = raffle.pricingOptions[entry.pricingOptionIndex]; uint40 newParticipantEntriesCount = rafflesParticipantsStats[raffleId][msg.sender].entriesCount + pricingOption.entriesCount; if (newParticipantEntriesCount > raffle.maximumEntriesPerParticipant) { revert MaximumEntriesPerParticipantReached(); } rafflesParticipantsStats[raffleId][msg.sender].entriesCount = newParticipantEntriesCount; uint208 price = pricingOption.price; if (raffle.feeTokenAddress == address(0)) { expectedEthValue += price; } else { _executeERC20TransferFrom(raffle.feeTokenAddress, msg.sender, address(this), price); } uint40 currentEntryIndex; uint256 raffleEntriesCount = raffle.entries.length; if (raffleEntriesCount == 0) { currentEntryIndex = uint40(_unsafeSubtract(pricingOption.entriesCount, 1)); } else { currentEntryIndex = raffle.entries[_unsafeSubtract(raffleEntriesCount, 1)].currentEntryIndex + pricingOption.entriesCount; } if (raffle.isMinimumEntriesFixed) { if (currentEntryIndex >= raffle.minimumEntries) { revert MaximumEntriesReached(); } } raffle.entries.push(Entry({currentEntryIndex: currentEntryIndex, participant: msg.sender})); raffle.claimableFees += price; rafflesParticipantsStats[raffleId][msg.sender].amountPaid += price; emit EntrySold(raffleId, msg.sender, pricingOption.entriesCount, price); if (currentEntryIndex >= _unsafeSubtract(raffle.minimumEntries, 1)) { _drawWinners(raffleId, raffle); } unchecked { ++i; } } _validateExpectedEthValueOrRefund(expectedEthValue); } /** * @param _requestId The ID of the request * @param _randomWords The random words returned by Chainlink */ function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override { if (randomnessRequests[_requestId].exists) { uint256 raffleId = randomnessRequests[_requestId].raffleId; Raffle storage raffle = raffles[raffleId]; if (raffle.status == RaffleStatus.Drawing) { _setRaffleStatus(raffle, raffleId, RaffleStatus.RandomnessFulfilled); // We ignore the most significant byte to pack the random word with `exists` randomnessRequests[_requestId].randomWord = uint248(_randomWords[0]); } } } /** * @inheritdoc IRaffle */ function selectWinners(uint256 requestId) external { RandomnessRequest memory randomnessRequest = randomnessRequests[requestId]; if (!randomnessRequest.exists) { revert RandomnessRequestDoesNotExist(); } uint256 raffleId = randomnessRequest.raffleId; Raffle storage raffle = raffles[raffleId]; _validateRaffleStatus(raffle, RaffleStatus.RandomnessFulfilled); _setRaffleStatus(raffle, raffleId, RaffleStatus.Drawn); Prize[] storage prizes = raffle.prizes; uint256 prizesCount = prizes.length; uint256 winnersCount = prizes[prizesCount - 1].cumulativeWinnersCount; Entry[] memory entries = raffle.entries; uint256 entriesCount = entries.length; uint256 currentEntryIndex = uint256(entries[entriesCount - 1].currentEntryIndex); uint256[] memory winningEntriesBitmap = new uint256[]((currentEntryIndex >> 8) + 1); uint256[] memory currentEntryIndexArray = new uint256[](entriesCount); for (uint256 i; i < entriesCount; ) { currentEntryIndexArray[i] = entries[i].currentEntryIndex; unchecked { ++i; } } uint256[] memory cumulativeWinnersCountArray = new uint256[](prizesCount); for (uint256 i; i < prizesCount; ) { cumulativeWinnersCountArray[i] = prizes[i].cumulativeWinnersCount; unchecked { ++i; } } uint256 randomWord = randomnessRequest.randomWord; for (uint256 i; i < winnersCount; ) { uint256 winningEntry = randomWord % (currentEntryIndex + 1); (winningEntry, winningEntriesBitmap) = _incrementWinningEntryUntilThereIsNotADuplicate( currentEntryIndex, winningEntry, winningEntriesBitmap ); raffle.winners.push( Winner({ participant: entries[currentEntryIndexArray.findUpperBound(winningEntry)].participant, claimed: false, prizeIndex: uint8(cumulativeWinnersCountArray.findUpperBound(_unsafeAdd(i, 1))), entryIndex: uint40(winningEntry) }) ); randomWord = uint256(keccak256(abi.encodePacked(randomWord))); unchecked { ++i; } } } /** * @inheritdoc IRaffle */ function claimPrizes(ClaimPrizesCalldata[] calldata claimPrizesCalldata) external nonReentrant whenNotPaused { uint256 claimsCount = claimPrizesCalldata.length; for (uint256 i; i < claimsCount; ) { _claimPrizesPerRaffle(claimPrizesCalldata[i]); unchecked { ++i; } } } /** * @inheritdoc IRaffle */ function claimProtocolFees(address currency) external onlyOwner { uint256 claimableFees = protocolFeeRecipientClaimableFees[currency]; protocolFeeRecipientClaimableFees[currency] = 0; _transferFungibleTokens(currency, protocolFeeRecipient, claimableFees); } /** * @inheritdoc IRaffle */ function claimFees(uint256 raffleId) external nonReentrant whenNotPaused { Raffle storage raffle = raffles[raffleId]; _validateRaffleStatus(raffle, RaffleStatus.Drawn); address raffleOwner = raffle.owner; if (msg.sender != raffleOwner) { _validateCaller(owner); } uint208 claimableFees = raffle.claimableFees; uint208 protocolFees = (claimableFees * uint208(raffle.protocolFeeBp)) / uint208(ONE_HUNDRED_PERCENT_BP); unchecked { claimableFees -= protocolFees; } _setRaffleStatus(raffle, raffleId, RaffleStatus.Complete); raffle.claimableFees = 0; address feeTokenAddress = raffle.feeTokenAddress; _transferFungibleTokens(feeTokenAddress, raffleOwner, claimableFees); if (protocolFees != 0) { protocolFeeRecipientClaimableFees[feeTokenAddress] += protocolFees; } emit FeesClaimed(raffleId, claimableFees); } /** * @inheritdoc IRaffle */ function cancel(uint256 raffleId) external nonReentrant whenNotPaused { Raffle storage raffle = raffles[raffleId]; bool isOpen = raffle.status == RaffleStatus.Open; if (isOpen) { if (raffle.cutoffTime > block.timestamp) { revert CutoffTimeNotReached(); } } else { _validateRaffleStatus(raffle, RaffleStatus.Created); } _setRaffleStatus(raffle, raffleId, isOpen ? RaffleStatus.Refundable : RaffleStatus.Cancelled); } /** * @inheritdoc IRaffle */ function cancelAfterRandomnessRequest(uint256 raffleId) external onlyOwner nonReentrant { Raffle storage raffle = raffles[raffleId]; _validateRaffleStatus(raffle, RaffleStatus.Drawing); if (block.timestamp < raffle.drawnAt + ONE_DAY) { revert DrawExpirationTimeNotReached(); } _setRaffleStatus(raffle, raffleId, RaffleStatus.Refundable); } /** * @inheritdoc IRaffle */ function withdrawPrizes(uint256 raffleId) external nonReentrant whenNotPaused { Raffle storage raffle = raffles[raffleId]; _validateRaffleStatus(raffle, RaffleStatus.Refundable); _setRaffleStatus(raffle, raffleId, RaffleStatus.Cancelled); uint256 prizesCount = raffle.prizes.length; address raffleOwner = raffle.owner; for (uint256 i; i < prizesCount; ) { Prize storage prize = raffle.prizes[i]; _transferPrize({prize: prize, recipient: raffleOwner, multiplier: uint256(prize.winnersCount)}); unchecked { ++i; } } } /** * @inheritdoc IRaffle * @dev Refundable and Cancelled are the only statuses that allow refunds. */ function claimRefund(uint256[] calldata raffleIds) external nonReentrant whenNotPaused { uint256 count = raffleIds.length; for (uint256 i; i < count; ) { uint256 raffleId = raffleIds[i]; Raffle storage raffle = raffles[raffleId]; if (raffle.status < RaffleStatus.Refundable) { revert InvalidStatus(); } ParticipantStats storage stats = rafflesParticipantsStats[raffleId][msg.sender]; if (stats.refunded) { revert AlreadyRefunded(); } stats.refunded = true; uint208 amountPaid = stats.amountPaid; _transferFungibleTokens(raffle.feeTokenAddress, msg.sender, amountPaid); emit EntryRefunded(raffleId, msg.sender, amountPaid); unchecked { ++i; } } } /** * @inheritdoc IRaffle */ function setProtocolFeeRecipient(address _protocolFeeRecipient) external onlyOwner { _setProtocolFeeRecipient(_protocolFeeRecipient); } /** * @inheritdoc IRaffle */ function setProtocolFeeBp(uint16 _protocolFeeBp) external onlyOwner { _setProtocolFeeBp(_protocolFeeBp); } /** * @inheritdoc IRaffle */ function updateCurrenciesStatus(address[] calldata currencies, bool isAllowed) external onlyOwner { uint256 count = currencies.length; for (uint256 i; i < count; ) { isCurrencyAllowed[currencies[i]] = isAllowed; unchecked { ++i; } } emit CurrenciesStatusUpdated(currencies, isAllowed); } /** * @inheritdoc IRaffle */ function togglePaused() external onlyOwner { paused() ? _unpause() : _pause(); } /** * @inheritdoc IRaffle */ function getWinners(uint256 raffleId) external view returns (Winner[] memory winners) { winners = raffles[raffleId].winners; } /** * @inheritdoc IRaffle */ function getPrizes(uint256 raffleId) external view returns (Prize[] memory prizes) { prizes = raffles[raffleId].prizes; } /** * @inheritdoc IRaffle */ function getEntries(uint256 raffleId) external view returns (Entry[] memory entries) { entries = raffles[raffleId].entries; } /** * @inheritdoc IRaffle */ function getPricingOptions(uint256 raffleId) external view returns (PricingOption[PRICING_OPTIONS_PER_RAFFLE] memory pricingOptions) { pricingOptions = raffles[raffleId].pricingOptions; } /** * @param _protocolFeeRecipient The new protocol fee recipient address */ function _setProtocolFeeRecipient(address _protocolFeeRecipient) private { if (_protocolFeeRecipient == address(0)) { revert InvalidProtocolFeeRecipient(); } protocolFeeRecipient = _protocolFeeRecipient; emit ProtocolFeeRecipientUpdated(_protocolFeeRecipient); } /** * @param _protocolFeeBp The new protocol fee in basis points */ function _setProtocolFeeBp(uint16 _protocolFeeBp) private { if (_protocolFeeBp > MAXIMUM_PROTOCOL_FEE_BP) { revert InvalidProtocolFeeBp(); } protocolFeeBp = _protocolFeeBp; emit ProtocolFeeBpUpdated(_protocolFeeBp); } /** * @param raffleId The ID of the raffle. * @param pricingOptions The pricing options for the raffle. */ function _validateAndSetPricingOptions( uint256 raffleId, PricingOption[PRICING_OPTIONS_PER_RAFFLE] calldata pricingOptions ) private { for (uint256 i; i < PRICING_OPTIONS_PER_RAFFLE; ) { PricingOption memory pricingOption = pricingOptions[i]; uint40 entriesCount = pricingOption.entriesCount; uint208 price = pricingOption.price; if (i == 0) { if (entriesCount != 1 || price == 0) { revert InvalidPricingOption(); } } else { PricingOption memory lastPricingOption = pricingOptions[_unsafeSubtract(i, 1)]; uint208 lastPrice = lastPricingOption.price; uint40 lastEntriesCount = lastPricingOption.entriesCount; if ( price % entriesCount != 0 || entriesCount <= lastEntriesCount || price <= lastPrice || price / entriesCount > lastPrice / lastEntriesCount ) { revert InvalidPricingOption(); } } raffles[raffleId].pricingOptions[i] = pricingOption; unchecked { ++i; } } } /** * @param prize The prize. */ function _validatePrize(Prize memory prize) private view { if (prize.prizeType == TokenType.ERC721) { if (prize.prizeAmount != 1 || prize.winnersCount != 1) { revert InvalidPrize(); } } else { if (prize.prizeType == TokenType.ERC20) { if (!isCurrencyAllowed[prize.prizeAddress]) { revert InvalidCurrency(); } } if (prize.prizeAmount == 0 || prize.winnersCount == 0) { revert InvalidPrize(); } } } /** * @param prize The prize to transfer. * @param recipient The recipient of the prize. * @param multiplier The multiplier to apply to the prize amount. */ function _transferPrize( Prize storage prize, address recipient, uint256 multiplier ) private { TokenType prizeType = prize.prizeType; address prizeAddress = prize.prizeAddress; if (prizeType == TokenType.ERC721) { _executeERC721TransferFrom(prizeAddress, address(this), recipient, prize.prizeId); } else if (prizeType == TokenType.ERC1155) { _executeERC1155SafeTransferFrom( prizeAddress, address(this), recipient, prize.prizeId, prize.prizeAmount * multiplier ); } else { _transferFungibleTokens(prizeAddress, recipient, prize.prizeAmount * multiplier); } } /** * @param currency The currency to transfer. * @param recipient The recipient of the currency. * @param amount The amount of currency to transfer. */ function _transferFungibleTokens( address currency, address recipient, uint256 amount ) private { if (currency == address(0)) { _transferETHAndWrapIfFailWithGasLimit(WETH, recipient, amount, gasleft()); } else { _executeERC20DirectTransfer(currency, recipient, amount); } } /** * @param claimPrizesCalldata The calldata for claiming prizes. */ function _claimPrizesPerRaffle(ClaimPrizesCalldata calldata claimPrizesCalldata) private { uint256 raffleId = claimPrizesCalldata.raffleId; Raffle storage raffle = raffles[raffleId]; RaffleStatus status = raffle.status; if (status != RaffleStatus.Drawn) { _validateRaffleStatus(raffle, RaffleStatus.Complete); } Winner[] storage winners = raffle.winners; uint256[] calldata winnerIndices = claimPrizesCalldata.winnerIndices; uint256 winnersCount = winners.length; uint256 claimsCount = winnerIndices.length; for (uint256 i; i < claimsCount; ) { uint256 winnerIndex = winnerIndices[i]; if (winnerIndex >= winnersCount) { revert InvalidIndex(); } Winner storage winner = winners[winnerIndex]; if (winner.claimed) { revert PrizeAlreadyClaimed(); } _validateCaller(winner.participant); winner.claimed = true; Prize storage prize = raffle.prizes[winner.prizeIndex]; _transferPrize({prize: prize, recipient: msg.sender, multiplier: 1}); unchecked { ++i; } } emit PrizesClaimed(raffleId, winnerIndices); } /** * @param raffleId The ID of the raffle to draw winners for. * @param raffle The raffle to draw winners for. */ function _drawWinners(uint256 raffleId, Raffle storage raffle) private { _setRaffleStatus(raffle, raffleId, RaffleStatus.Drawing); raffle.drawnAt = uint40(block.timestamp); uint256 requestId = VRF_COORDINATOR.requestRandomWords( KEY_HASH, SUBSCRIPTION_ID, REQUEST_CONFIRMATIONS, uint32(500_000), uint32(1) ); if (randomnessRequests[requestId].exists) { revert RandomnessRequestAlreadyExists(); } randomnessRequests[requestId].exists = true; randomnessRequests[requestId].raffleId = raffleId; emit RandomnessRequested(raffleId, requestId); } /** * @param raffle The raffle to check the status of. * @param status The expected status of the raffle */ function _validateRaffleStatus(Raffle storage raffle, RaffleStatus status) private view { if (raffle.status != status) { revert InvalidStatus(); } } /** * @param caller The expected caller. */ function _validateCaller(address caller) private view { if (msg.sender != caller) { revert InvalidCaller(); } } /** * @param expectedEthValue The expected ETH value to be sent by the caller. */ function _validateExpectedEthValueOrRefund(uint256 expectedEthValue) private { if (expectedEthValue > msg.value) { revert InsufficientNativeTokensSupplied(); } else if (msg.value > expectedEthValue) { _transferETHAndWrapIfFailWithGasLimit( WETH, msg.sender, _unsafeSubtract(msg.value, expectedEthValue), gasleft() ); } } /** * @param raffle The raffle to set the status of. * @param raffleId The ID of the raffle to set the status of. * @param status The status to set. */ function _setRaffleStatus( Raffle storage raffle, uint256 raffleId, RaffleStatus status ) private { raffle.status = status; emit RaffleStatusUpdated(raffleId, status); } function _unsafeAdd(uint256 a, uint256 b) private pure returns (uint256) { unchecked { return a + b; } } function _unsafeSubtract(uint256 a, uint256 b) private pure returns (uint256) { unchecked { return a - b; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; // Interfaces import {IWETH} from "../interfaces/generic/IWETH.sol"; /** * @title LowLevelWETH * @notice This contract contains a function to transfer ETH with an option to wrap to WETH. * If the ETH transfer fails within a gas limit, the amount in ETH is wrapped to WETH and then transferred. * @author LooksRare protocol team (👀,💎) */ contract LowLevelWETH { /** * @notice It transfers ETH to a recipient with a specified gas limit. * If the original transfers fails, it wraps to WETH and transfers the WETH to recipient. * @param _WETH WETH address * @param _to Recipient address * @param _amount Amount to transfer * @param _gasLimit Gas limit to perform the ETH transfer */ function _transferETHAndWrapIfFailWithGasLimit( address _WETH, address _to, uint256 _amount, uint256 _gasLimit ) internal { bool status; assembly { status := call(_gasLimit, _to, _amount, 0, 0, 0, 0) } if (!status) { IWETH(_WETH).deposit{value: _amount}(); IWETH(_WETH).transfer(_to, _amount); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; // Interfaces import {IERC20} from "../interfaces/generic/IERC20.sol"; // Errors import {ERC20TransferFail, ERC20TransferFromFail} from "../errors/LowLevelErrors.sol"; import {NotAContract} from "../errors/GenericErrors.sol"; /** * @title LowLevelERC20Transfer * @notice This contract contains low-level calls to transfer ERC20 tokens. * @author LooksRare protocol team (👀,💎) */ contract LowLevelERC20Transfer { /** * @notice Execute ERC20 transferFrom * @param currency Currency address * @param from Sender address * @param to Recipient address * @param amount Amount to transfer */ function _executeERC20TransferFrom(address currency, address from, address to, uint256 amount) internal { if (currency.code.length == 0) { revert NotAContract(); } (bool status, bytes memory data) = currency.call(abi.encodeCall(IERC20.transferFrom, (from, to, amount))); if (!status) { revert ERC20TransferFromFail(); } if (data.length > 0) { if (!abi.decode(data, (bool))) { revert ERC20TransferFromFail(); } } } /** * @notice Execute ERC20 (direct) transfer * @param currency Currency address * @param to Recipient address * @param amount Amount to transfer */ function _executeERC20DirectTransfer(address currency, address to, uint256 amount) internal { if (currency.code.length == 0) { revert NotAContract(); } (bool status, bytes memory data) = currency.call(abi.encodeCall(IERC20.transfer, (to, amount))); if (!status) { revert ERC20TransferFail(); } if (data.length > 0) { if (!abi.decode(data, (bool))) { revert ERC20TransferFail(); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; // Interfaces import {IERC721} from "../interfaces/generic/IERC721.sol"; // Errors import {ERC721TransferFromFail} from "../errors/LowLevelErrors.sol"; import {NotAContract} from "../errors/GenericErrors.sol"; /** * @title LowLevelERC721Transfer * @notice This contract contains low-level calls to transfer ERC721 tokens. * @author LooksRare protocol team (👀,💎) */ contract LowLevelERC721Transfer { /** * @notice Execute ERC721 transferFrom * @param collection Address of the collection * @param from Address of the sender * @param to Address of the recipient * @param tokenId tokenId to transfer */ function _executeERC721TransferFrom(address collection, address from, address to, uint256 tokenId) internal { if (collection.code.length == 0) { revert NotAContract(); } (bool status, ) = collection.call(abi.encodeCall(IERC721.transferFrom, (from, to, tokenId))); if (!status) { revert ERC721TransferFromFail(); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; // Interfaces import {IERC1155} from "../interfaces/generic/IERC1155.sol"; // Errors import {ERC1155SafeTransferFromFail, ERC1155SafeBatchTransferFromFail} from "../errors/LowLevelErrors.sol"; import {NotAContract} from "../errors/GenericErrors.sol"; /** * @title LowLevelERC1155Transfer * @notice This contract contains low-level calls to transfer ERC1155 tokens. * @author LooksRare protocol team (👀,💎) */ contract LowLevelERC1155Transfer { /** * @notice Execute ERC1155 safeTransferFrom * @param collection Address of the collection * @param from Address of the sender * @param to Address of the recipient * @param tokenId tokenId to transfer * @param amount Amount to transfer */ function _executeERC1155SafeTransferFrom( address collection, address from, address to, uint256 tokenId, uint256 amount ) internal { if (collection.code.length == 0) { revert NotAContract(); } (bool status, ) = collection.call(abi.encodeCall(IERC1155.safeTransferFrom, (from, to, tokenId, amount, ""))); if (!status) { revert ERC1155SafeTransferFromFail(); } } /** * @notice Execute ERC1155 safeBatchTransferFrom * @param collection Address of the collection * @param from Address of the sender * @param to Address of the recipient * @param tokenIds Array of tokenIds to transfer * @param amounts Array of amounts to transfer */ function _executeERC1155SafeBatchTransferFrom( address collection, address from, address to, uint256[] calldata tokenIds, uint256[] calldata amounts ) internal { if (collection.code.length == 0) { revert NotAContract(); } (bool status, ) = collection.call( abi.encodeCall(IERC1155.safeBatchTransferFrom, (from, to, tokenIds, amounts, "")) ); if (!status) { revert ERC1155SafeBatchTransferFromFail(); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; // Interfaces import {IOwnableTwoSteps} from "./interfaces/IOwnableTwoSteps.sol"; /** * @title OwnableTwoSteps * @notice This contract offers transfer of ownership in two steps with potential owner * having to confirm the transaction to become the owner. * Renouncement of the ownership is also a two-step process since the next potential owner is the address(0). * @author LooksRare protocol team (👀,💎) */ abstract contract OwnableTwoSteps is IOwnableTwoSteps { /** * @notice Address of the current owner. */ address public owner; /** * @notice Address of the potential owner. */ address public potentialOwner; /** * @notice Ownership status. */ Status public ownershipStatus; /** * @notice Modifier to wrap functions for contracts that inherit this contract. */ modifier onlyOwner() { _onlyOwner(); _; } /** * @notice Constructor * @param _owner The contract's owner */ constructor(address _owner) { owner = _owner; emit NewOwner(_owner); } /** * @notice This function is used to cancel the ownership transfer. * @dev This function can be used for both cancelling a transfer to a new owner and * cancelling the renouncement of the ownership. */ function cancelOwnershipTransfer() external onlyOwner { Status _ownershipStatus = ownershipStatus; if (_ownershipStatus == Status.NoOngoingTransfer) { revert NoOngoingTransferInProgress(); } if (_ownershipStatus == Status.TransferInProgress) { delete potentialOwner; } delete ownershipStatus; emit CancelOwnershipTransfer(); } /** * @notice This function is used to confirm the ownership renouncement. */ function confirmOwnershipRenouncement() external onlyOwner { if (ownershipStatus != Status.RenouncementInProgress) { revert RenouncementNotInProgress(); } delete owner; delete ownershipStatus; emit NewOwner(address(0)); } /** * @notice This function is used to confirm the ownership transfer. * @dev This function can only be called by the current potential owner. */ function confirmOwnershipTransfer() external { if (ownershipStatus != Status.TransferInProgress) { revert TransferNotInProgress(); } if (msg.sender != potentialOwner) { revert WrongPotentialOwner(); } owner = msg.sender; delete ownershipStatus; delete potentialOwner; emit NewOwner(msg.sender); } /** * @notice This function is used to initiate the transfer of ownership to a new owner. * @param newPotentialOwner New potential owner address */ function initiateOwnershipTransfer(address newPotentialOwner) external onlyOwner { if (ownershipStatus != Status.NoOngoingTransfer) { revert TransferAlreadyInProgress(); } ownershipStatus = Status.TransferInProgress; potentialOwner = newPotentialOwner; /** * @dev This function can only be called by the owner, so msg.sender is the owner. * We don't have to SLOAD the owner again. */ emit InitiateOwnershipTransfer(msg.sender, newPotentialOwner); } /** * @notice This function is used to initiate the ownership renouncement. */ function initiateOwnershipRenouncement() external onlyOwner { if (ownershipStatus != Status.NoOngoingTransfer) { revert TransferAlreadyInProgress(); } ownershipStatus = Status.RenouncementInProgress; emit InitiateOwnershipRenouncement(); } function _onlyOwner() private view { if (msg.sender != owner) revert NotOwner(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; // Interfaces import {IReentrancyGuard} from "./interfaces/IReentrancyGuard.sol"; /** * @title PackableReentrancyGuard * @notice This contract protects against reentrancy attacks. * It is adjusted from OpenZeppelin. * The only difference between this contract and ReentrancyGuard * is that _status is uint8 instead of uint256 so that it can be * packed with other contracts' storage variables. * @author LooksRare protocol team (👀,💎) */ abstract contract PackableReentrancyGuard is IReentrancyGuard { uint8 private _status; /** * @notice Modifier to wrap functions to prevent reentrancy calls. */ modifier nonReentrant() { if (_status == 2) { revert ReentrancyFail(); } _status = 2; _; _status = 1; } constructor() { _status = 1; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; /** * @title Pausable * @notice This contract makes it possible to pause the contract. * It is adjusted from OpenZeppelin. * @author LooksRare protocol team (👀,💎) */ abstract contract Pausable { /** * @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); error IsPaused(); error NotPaused(); bool private _paused; /** * @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 { if (paused()) { revert IsPaused(); } } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { if (!paused()) { revert NotPaused(); } } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(msg.sender); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(msg.sender); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface VRFCoordinatorV2Interface { /** * @notice Get configuration relevant for making requests * @return minimumRequestConfirmations global min for request confirmations * @return maxGasLimit global max for request gas limit * @return s_provingKeyHashes list of registered key hashes */ function getRequestConfig() external view returns ( uint16, uint32, bytes32[] memory ); /** * @notice Request a set of random words. * @param keyHash - Corresponds to a particular oracle job which uses * that key for generating the VRF proof. Different keyHash's have different gas price * ceilings, so you can select a specific one to bound your maximum per request cost. * @param subId - The ID of the VRF subscription. Must be funded * with the minimum subscription balance required for the selected keyHash. * @param minimumRequestConfirmations - How many blocks you'd like the * oracle to wait before responding to the request. See SECURITY CONSIDERATIONS * for why you may want to request more. The acceptable range is * [minimumRequestBlockConfirmations, 200]. * @param callbackGasLimit - How much gas you'd like to receive in your * fulfillRandomWords callback. Note that gasleft() inside fulfillRandomWords * may be slightly less than this amount because of gas used calling the function * (argument decoding etc.), so you may need to request slightly more than you expect * to have inside fulfillRandomWords. The acceptable range is * [0, maxGasLimit] * @param numWords - The number of uint256 random values you'd like to receive * in your fulfillRandomWords callback. Note these numbers are expanded in a * secure way by the VRFCoordinator from a single random value supplied by the oracle. * @return requestId - A unique identifier of the request. Can be used to match * a request to a response in fulfillRandomWords. */ function requestRandomWords( bytes32 keyHash, uint64 subId, uint16 minimumRequestConfirmations, uint32 callbackGasLimit, uint32 numWords ) external returns (uint256 requestId); /** * @notice Create a VRF subscription. * @return subId - A unique subscription id. * @dev You can manage the consumer set dynamically with addConsumer/removeConsumer. * @dev Note to fund the subscription, use transferAndCall. For example * @dev LINKTOKEN.transferAndCall( * @dev address(COORDINATOR), * @dev amount, * @dev abi.encode(subId)); */ function createSubscription() external returns (uint64 subId); /** * @notice Get a VRF subscription. * @param subId - ID of the subscription * @return balance - LINK balance of the subscription in juels. * @return reqCount - number of requests for this subscription, determines fee tier. * @return owner - owner of the subscription. * @return consumers - list of consumer address which are able to use this subscription. */ function getSubscription(uint64 subId) external view returns ( uint96 balance, uint64 reqCount, address owner, address[] memory consumers ); /** * @notice Request subscription owner transfer. * @param subId - ID of the subscription * @param newOwner - proposed new owner of the subscription */ function requestSubscriptionOwnerTransfer(uint64 subId, address newOwner) external; /** * @notice Request subscription owner transfer. * @param subId - ID of the subscription * @dev will revert if original owner of subId has * not requested that msg.sender become the new owner. */ function acceptSubscriptionOwnerTransfer(uint64 subId) external; /** * @notice Add a consumer to a VRF subscription. * @param subId - ID of the subscription * @param consumer - New consumer which can use the subscription */ function addConsumer(uint64 subId, address consumer) external; /** * @notice Remove a consumer from a VRF subscription. * @param subId - ID of the subscription * @param consumer - Consumer to remove from the subscription */ function removeConsumer(uint64 subId, address consumer) external; /** * @notice Cancel a subscription * @param subId - ID of the subscription * @param to - Where to send the remaining LINK to */ function cancelSubscription(uint64 subId, address to) external; /* * @notice Check to see if there exists a request commitment consumers * for all consumers and keyhashes for a given sub. * @param subId - ID of the subscription * @return true if there exists at least one unfulfilled request for the subscription, false * otherwise. */ function pendingRequestExists(uint64 subId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /** **************************************************************************** * @notice Interface for contracts using VRF randomness * ***************************************************************************** * @dev PURPOSE * * @dev Reggie the Random Oracle (not his real job) wants to provide randomness * @dev to Vera the verifier in such a way that Vera can be sure he's not * @dev making his output up to suit himself. Reggie provides Vera a public key * @dev to which he knows the secret key. Each time Vera provides a seed to * @dev Reggie, he gives back a value which is computed completely * @dev deterministically from the seed and the secret key. * * @dev Reggie provides a proof by which Vera can verify that the output was * @dev correctly computed once Reggie tells it to her, but without that proof, * @dev the output is indistinguishable to her from a uniform random sample * @dev from the output space. * * @dev The purpose of this contract is to make it easy for unrelated contracts * @dev to talk to Vera the verifier about the work Reggie is doing, to provide * @dev simple access to a verifiable source of randomness. It ensures 2 things: * @dev 1. The fulfillment came from the VRFCoordinator * @dev 2. The consumer contract implements fulfillRandomWords. * ***************************************************************************** * @dev USAGE * * @dev Calling contracts must inherit from VRFConsumerBase, and can * @dev initialize VRFConsumerBase's attributes in their constructor as * @dev shown: * * @dev contract VRFConsumer { * @dev constructor(<other arguments>, address _vrfCoordinator, address _link) * @dev VRFConsumerBase(_vrfCoordinator) public { * @dev <initialization with other arguments goes here> * @dev } * @dev } * * @dev The oracle will have given you an ID for the VRF keypair they have * @dev committed to (let's call it keyHash). Create subscription, fund it * @dev and your consumer contract as a consumer of it (see VRFCoordinatorInterface * @dev subscription management functions). * @dev Call requestRandomWords(keyHash, subId, minimumRequestConfirmations, * @dev callbackGasLimit, numWords), * @dev see (VRFCoordinatorInterface for a description of the arguments). * * @dev Once the VRFCoordinator has received and validated the oracle's response * @dev to your request, it will call your contract's fulfillRandomWords method. * * @dev The randomness argument to fulfillRandomWords is a set of random words * @dev generated from your requestId and the blockHash of the request. * * @dev If your contract could have concurrent requests open, you can use the * @dev requestId returned from requestRandomWords to track which response is associated * @dev with which randomness request. * @dev See "SECURITY CONSIDERATIONS" for principles to keep in mind, * @dev if your contract could have multiple requests in flight simultaneously. * * @dev Colliding `requestId`s are cryptographically impossible as long as seeds * @dev differ. * * ***************************************************************************** * @dev SECURITY CONSIDERATIONS * * @dev A method with the ability to call your fulfillRandomness method directly * @dev could spoof a VRF response with any random value, so it's critical that * @dev it cannot be directly called by anything other than this base contract * @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method). * * @dev For your users to trust that your contract's random behavior is free * @dev from malicious interference, it's best if you can write it so that all * @dev behaviors implied by a VRF response are executed *during* your * @dev fulfillRandomness method. If your contract must store the response (or * @dev anything derived from it) and use it later, you must ensure that any * @dev user-significant behavior which depends on that stored value cannot be * @dev manipulated by a subsequent VRF request. * * @dev Similarly, both miners and the VRF oracle itself have some influence * @dev over the order in which VRF responses appear on the blockchain, so if * @dev your contract could have multiple VRF requests in flight simultaneously, * @dev you must ensure that the order in which the VRF responses arrive cannot * @dev be used to manipulate your contract's user-significant behavior. * * @dev Since the block hash of the block which contains the requestRandomness * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful * @dev miner could, in principle, fork the blockchain to evict the block * @dev containing the request, forcing the request to be included in a * @dev different block with a different hash, and therefore a different input * @dev to the VRF. However, such an attack would incur a substantial economic * @dev cost. This cost scales with the number of blocks the VRF oracle waits * @dev until it calls responds to a request. It is for this reason that * @dev that you can signal to an oracle you'd like them to wait longer before * @dev responding to the request (however this is not enforced in the contract * @dev and so remains effective only in the case of unmodified oracle software). */ abstract contract VRFConsumerBaseV2 { error OnlyCoordinatorCanFulfill(address have, address want); address private immutable vrfCoordinator; /** * @param _vrfCoordinator address of VRFCoordinator contract */ constructor(address _vrfCoordinator) { vrfCoordinator = _vrfCoordinator; } /** * @notice fulfillRandomness handles the VRF response. Your contract must * @notice implement it. See "SECURITY CONSIDERATIONS" above for important * @notice principles to keep in mind when implementing your fulfillRandomness * @notice method. * * @dev VRFConsumerBaseV2 expects its subcontracts to have a method with this * @dev signature, and will call it once it has verified the proof * @dev associated with the randomness. (It is triggered via a call to * @dev rawFulfillRandomness, below.) * * @param requestId The Id initially returned by requestRandomness * @param randomWords the VRF output expanded to the requested number of words */ function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal virtual; // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF // proof. rawFulfillRandomness then calls fulfillRandomness, after validating // the origin of the call function rawFulfillRandomWords(uint256 requestId, uint256[] memory randomWords) external { if (msg.sender != vrfCoordinator) { revert OnlyCoordinatorCanFulfill(msg.sender, vrfCoordinator); } fulfillRandomWords(requestId, randomWords); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; /** * @dev Collection of functions related to array types. * Modified from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Arrays.sol */ library Arrays { /** * @dev Searches a sorted `array` and returns the first index that contains * a value greater or equal to `element`. If no such index exists (i.e. all * values in the array are strictly less than `element`), the array length is * returned. Time complexity O(log n). * * `array` is expected to be sorted in ascending order, and to contain no * repeated elements. */ function findUpperBound(uint256[] memory array, uint256 element) internal pure returns (uint256) { if (array.length == 0) { return 0; } uint256 low = 0; uint256 high = array.length; while (low < high) { uint256 mid = Math.average(low, high); // Note that mid will always be strictly less than high (i.e. it will be a valid array index) // because Math.average rounds down (it does integer division with truncation). if (array[mid] > element) { high = mid; } else { unchecked { low = mid + 1; } } } // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound. if (low > 0 && array[low - 1] == element) { unchecked { return low - 1; } } else { return low; } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; /** * @title WinningEntrySearchLogic * @notice This contract contains the logic to search for a winning entry. * @author LooksRare protocol team (👀,💎) */ contract WinningEntrySearchLogic { /** * @param currentEntryIndex The current entry index. * @param winningEntry The winning entry. * @param winningEntriesBitmap The bitmap of winning entries. */ function _incrementWinningEntryUntilThereIsNotADuplicate( uint256 currentEntryIndex, uint256 winningEntry, uint256[] memory winningEntriesBitmap ) internal pure returns (uint256, uint256[] memory) { uint256 bucket = winningEntry >> 8; uint256 mask = 1 << (winningEntry & 0xff); while (winningEntriesBitmap[bucket] & mask != 0) { if (winningEntry == currentEntryIndex) { bucket = 0; winningEntry = 0; } else { winningEntry += 1; if (winningEntry % 256 == 0) { unchecked { bucket += 1; } } } mask = 1 << (winningEntry & 0xff); } winningEntriesBitmap[bucket] |= mask; return (winningEntry, winningEntriesBitmap); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface IRaffle { enum RaffleStatus { None, Created, Open, Drawing, RandomnessFulfilled, Drawn, Complete, Refundable, Cancelled } enum TokenType { ERC721, ERC1155, ETH, ERC20 } /** * @param entriesCount The number of entries that can be purchased for the given price. * @param price The price of the entries. */ struct PricingOption { uint40 entriesCount; uint208 price; } /** * @param currentEntryIndex The cumulative number of entries in the raffle. * @param participant The address of the participant. */ struct Entry { uint40 currentEntryIndex; address participant; } /** * @param participant The address of the winner. * @param claimed Whether the winner has claimed the prize. * @param prizeIndex The index of the prize that was won. * @param entryIndex The index of the entry that won. */ struct Winner { address participant; bool claimed; uint8 prizeIndex; uint40 entryIndex; } /** * @param winnersCount The number of winners. * @param cumulativeWinnersCount The cumulative number of winners in the raffle. * @param prizeType The type of the prize. * @param prizeTier The tier of the prize. * @param prizeAddress The address of the prize. * @param prizeId The id of the prize. * @param prizeAmount The amount of the prize. */ struct Prize { uint40 winnersCount; uint40 cumulativeWinnersCount; TokenType prizeType; uint8 prizeTier; address prizeAddress; uint256 prizeId; uint256 prizeAmount; } /** * @param owner The address of the raffle owner. * @param status The status of the raffle. * @param isMinimumEntriesFixed Whether the minimum number of entries is fixed. * @param cutoffTime The time after which the raffle cannot be entered. * @param drawnAt The time at which the raffle was drawn. It is still pending Chainlink to fulfill the randomness request. * @param minimumEntries The minimum number of entries required to draw the raffle. * @param maximumEntriesPerParticipant The maximum number of entries allowed per participant. * @param feeTokenAddress The address of the token to be used as a fee. If the fee token type is ETH, then this address is ignored. * @param protocolFeeBp The protocol fee in basis points. It must be equal to the protocol fee basis points when the raffle was created. * @param claimableFees The amount of fees collected from selling entries. * @param pricingOptions The pricing options for the raffle. * @param prizes The prizes to be distributed. * @param entries The entries that have been sold. * @param winners The winners of the raffle. */ struct Raffle { address owner; RaffleStatus status; bool isMinimumEntriesFixed; uint40 cutoffTime; uint40 drawnAt; uint40 minimumEntries; uint40 maximumEntriesPerParticipant; address feeTokenAddress; uint16 protocolFeeBp; uint208 claimableFees; PricingOption[5] pricingOptions; Prize[] prizes; Entry[] entries; Winner[] winners; } /** * @param amountPaid The amount paid by the participant. * @param entriesCount The number of entries purchased by the participant. * @param refunded Whether the participant has been refunded. */ struct ParticipantStats { uint208 amountPaid; uint40 entriesCount; bool refunded; } /** * @param raffleId The id of the raffle. * @param pricingOptionIndex The index of the selected pricing option. */ struct EntryCalldata { uint256 raffleId; uint256 pricingOptionIndex; } /** * @param cutoffTime The time at which the raffle will be closed. * @param minimumEntries The minimum number of entries required to draw the raffle. * @param isMinimumEntriesFixed Whether the minimum number of entries is fixed. * @param maximumEntriesPerParticipant The maximum number of entries allowed per participant. * @param protocolFeeBp The protocol fee in basis points. It must be equal to the protocol fee basis points when the raffle was created. * @param feeTokenAddress The address of the token to be used as a fee. If the fee token type is ETH, then this address is ignored. * @param prizes The prizes to be distributed. * @param pricingOptions The pricing options for the raffle. */ struct CreateRaffleCalldata { uint40 cutoffTime; bool isMinimumEntriesFixed; uint40 minimumEntries; uint40 maximumEntriesPerParticipant; uint16 protocolFeeBp; address feeTokenAddress; Prize[] prizes; PricingOption[5] pricingOptions; } struct ClaimPrizesCalldata { uint256 raffleId; uint256[] winnerIndices; } /** * @param exists Whether the request exists. * @param raffleId The id of the raffle. * @param randomWord The random words returned by Chainlink VRF. * If randomWord == 0, then the request is still pending. */ struct RandomnessRequest { bool exists; uint248 randomWord; uint256 raffleId; } event CurrenciesStatusUpdated(address[] currencies, bool isAllowed); event EntryRefunded(uint256 raffleId, address buyer, uint208 amount); event EntrySold(uint256 raffleId, address buyer, uint40 entriesCount, uint208 price); event FeesClaimed(uint256 raffleId, uint256 amount); event PrizesClaimed(uint256 raffleId, uint256[] winnerIndex); event ProtocolFeeBpUpdated(uint16 protocolFeeBp); event ProtocolFeeRecipientUpdated(address protocolFeeRecipient); event RaffleStatusUpdated(uint256 raffleId, RaffleStatus status); event RandomnessRequested(uint256 raffleId, uint256 requestId); error AlreadyRefunded(); error CutoffTimeNotReached(); error CutoffTimeReached(); error DrawExpirationTimeNotReached(); error InsufficientNativeTokensSupplied(); error InvalidCaller(); error InvalidCurrency(); error InvalidCutoffTime(); error InvalidIndex(); error InvalidPricingOption(); error InvalidPrize(); error InvalidPrizesCount(); error InvalidProtocolFeeBp(); error InvalidProtocolFeeRecipient(); error InvalidStatus(); error InvalidWinnersCount(); error MaximumEntriesPerParticipantReached(); error MaximumEntriesReached(); error PrizeAlreadyClaimed(); error RandomnessRequestAlreadyExists(); error RandomnessRequestDoesNotExist(); /** * @notice Creates a new raffle. * @param params The parameters of the raffle. * @return raffleId The id of the newly created raffle. */ function createRaffle(CreateRaffleCalldata calldata params) external returns (uint256 raffleId); /** * @notice Deposits prizes for a raffle. * @param raffleId The id of the raffle. */ function depositPrizes(uint256 raffleId) external payable; /** * @notice Enters a raffle or multiple raffles. * @param entries The entries to be made. */ function enterRaffles(EntryCalldata[] calldata entries) external payable; /** * @notice Select the winners for a raffle based on the random words returned by Chainlink. * @param requestId The request id returned by Chainlink. */ function selectWinners(uint256 requestId) external; /** * @notice Claims the prizes for a winner. A winner can claim multiple prizes * from multiple raffles in a single transaction. * @param claimPrizesCalldata The calldata for claiming prizes. */ function claimPrizes(ClaimPrizesCalldata[] calldata claimPrizesCalldata) external; /** * @notice Claims the fees collected for a raffle. * @param raffleId The id of the raffle. */ function claimFees(uint256 raffleId) external; /** * @notice Cancels a raffle beyond cut-off time without meeting minimum entries. * @param raffleId The id of the raffle. */ function cancel(uint256 raffleId) external; /** * @notice Cancels a raffle after randomness request if the randomness request * does not arrive after a certain amount of time. * Only callable by contract owner. * @param raffleId The id of the raffle. */ function cancelAfterRandomnessRequest(uint256 raffleId) external; /** * @notice Withdraws the prizes for a raffle after it has been marked as refundable. * @param raffleId The id of the raffle. */ function withdrawPrizes(uint256 raffleId) external; /** * @notice Claims the refund for a cancelled raffle. * @param raffleIds The ids of the raffles. */ function claimRefund(uint256[] calldata raffleIds) external; /** * @notice Claims the protocol fees collected for a raffle. * @param currency The currency of the fees to be claimed. */ function claimProtocolFees(address currency) external; /** * @notice Sets the protocol fee in basis points. Only callable by contract owner. * @param protocolFeeBp The protocol fee in basis points. */ function setProtocolFeeBp(uint16 protocolFeeBp) external; /** * @notice Sets the protocol fee recipient. Only callable by contract owner. * @param protocolFeeRecipient The protocol fee recipient. */ function setProtocolFeeRecipient(address protocolFeeRecipient) external; /** * @notice This function allows the owner to update currency statuses. * @param currencies Currency addresses (address(0) for ETH) * @param isAllowed Whether the currencies should be allowed for trading * @dev Only callable by owner. */ function updateCurrenciesStatus(address[] calldata currencies, bool isAllowed) external; /** * @notice Toggle the contract's paused status. Only callable by contract owner. */ function togglePaused() external; /** * @notice Gets the winners for a raffle. * @param raffleId The id of the raffle. * @return winners The winners of the raffle. */ function getWinners(uint256 raffleId) external view returns (Winner[] memory); /** * @notice Gets the pricing options for a raffle. * @param raffleId The id of the raffle. * @return pricingOptions The pricing options for the raffle. */ function getPricingOptions(uint256 raffleId) external view returns (PricingOption[5] memory); /** * @notice Gets the prizes for a raffle. * @param raffleId The id of the raffle. * @return prizes The prizes to be distributed. */ function getPrizes(uint256 raffleId) external view returns (Prize[] memory); /** * @notice Gets the entries for a raffle. * @param raffleId The id of the raffle. * @return entries The entries entered for the raffle. */ function getEntries(uint256 raffleId) external view returns (Entry[] memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface IWETH { function deposit() external payable; function transfer(address dst, uint256 wad) external returns (bool); function withdraw(uint256 wad) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; interface IERC20 { event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address to, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; /** * @notice It is emitted if the ETH transfer fails. */ error ETHTransferFail(); /** * @notice It is emitted if the ERC20 approval fails. */ error ERC20ApprovalFail(); /** * @notice It is emitted if the ERC20 transfer fails. */ error ERC20TransferFail(); /** * @notice It is emitted if the ERC20 transferFrom fails. */ error ERC20TransferFromFail(); /** * @notice It is emitted if the ERC721 transferFrom fails. */ error ERC721TransferFromFail(); /** * @notice It is emitted if the ERC1155 safeTransferFrom fails. */ error ERC1155SafeTransferFromFail(); /** * @notice It is emitted if the ERC1155 safeBatchTransferFrom fails. */ error ERC1155SafeBatchTransferFromFail();
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; /** * @notice It is emitted if the call recipient is not a contract. */ error NotAContract();
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; interface IERC721 { event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); function balanceOf(address owner) external view returns (uint256 balance); function ownerOf(uint256 tokenId) external view returns (address owner); function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; function safeTransferFrom(address from, address to, uint256 tokenId) external; function transferFrom(address from, address to, uint256 tokenId) external; function approve(address to, uint256 tokenId) external; function setApprovalForAll(address operator, bool _approved) external; function getApproved(uint256 tokenId) external view returns (address operator); function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; interface IERC1155 { event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); event ApprovalForAll(address indexed account, address indexed operator, bool approved); event URI(string value, uint256 indexed id); function balanceOf(address account, uint256 id) external view returns (uint256); function balanceOfBatch( address[] calldata accounts, uint256[] calldata ids ) external view returns (uint256[] memory); function setApprovalForAll(address operator, bool approved) external; function isApprovedForAll(address account, address operator) external view returns (bool); function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external; function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; /** * @title IOwnableTwoSteps * @author LooksRare protocol team (👀,💎) */ interface IOwnableTwoSteps { /** * @notice This enum keeps track of the ownership status. * @param NoOngoingTransfer The default status when the owner is set * @param TransferInProgress The status when a transfer to a new owner is initialized * @param RenouncementInProgress The status when a transfer to address(0) is initialized */ enum Status { NoOngoingTransfer, TransferInProgress, RenouncementInProgress } /** * @notice This is returned when there is no transfer of ownership in progress. */ error NoOngoingTransferInProgress(); /** * @notice This is returned when the caller is not the owner. */ error NotOwner(); /** * @notice This is returned when there is no renouncement in progress but * the owner tries to validate the ownership renouncement. */ error RenouncementNotInProgress(); /** * @notice This is returned when the transfer is already in progress but the owner tries * initiate a new ownership transfer. */ error TransferAlreadyInProgress(); /** * @notice This is returned when there is no ownership transfer in progress but the * ownership change tries to be approved. */ error TransferNotInProgress(); /** * @notice This is returned when the ownership transfer is attempted to be validated by the * a caller that is not the potential owner. */ error WrongPotentialOwner(); /** * @notice This is emitted if the ownership transfer is cancelled. */ event CancelOwnershipTransfer(); /** * @notice This is emitted if the ownership renouncement is initiated. */ event InitiateOwnershipRenouncement(); /** * @notice This is emitted if the ownership transfer is initiated. * @param previousOwner Previous/current owner * @param potentialOwner Potential/future owner */ event InitiateOwnershipTransfer(address previousOwner, address potentialOwner); /** * @notice This is emitted when there is a new owner. */ event NewOwner(address newOwner); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; /** * @title IReentrancyGuard * @author LooksRare protocol team (👀,💎) */ interface IReentrancyGuard { /** * @notice This is returned when there is a reentrant call. */ error ReentrancyFail(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @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 / b + (a % b == 0 ? 0 : 1); } }
{ "remappings": [ "@chainlink/=node_modules/@chainlink/", "@ensdomains/=node_modules/@ensdomains/", "@eth-optimism/=node_modules/@eth-optimism/", "@looksrare/=node_modules/@looksrare/", "@openzeppelin/=node_modules/@openzeppelin/", "ds-test/=lib/forge-std/lib/ds-test/src/", "eth-gas-reporter/=node_modules/eth-gas-reporter/", "forge-std/=lib/forge-std/src/", "hardhat/=node_modules/hardhat/" ], "optimizer": { "enabled": true, "runs": 888888 }, "metadata": { "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "evmVersion": "london", "viaIR": true, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_weth","type":"address"},{"internalType":"bytes32","name":"_keyHash","type":"bytes32"},{"internalType":"uint64","name":"_subscriptionId","type":"uint64"},{"internalType":"address","name":"_vrfCoordinator","type":"address"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_protocolFeeRecipient","type":"address"},{"internalType":"uint16","name":"_protocolFeeBp","type":"uint16"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyRefunded","type":"error"},{"inputs":[],"name":"CutoffTimeNotReached","type":"error"},{"inputs":[],"name":"CutoffTimeReached","type":"error"},{"inputs":[],"name":"DrawExpirationTimeNotReached","type":"error"},{"inputs":[],"name":"ERC1155SafeTransferFromFail","type":"error"},{"inputs":[],"name":"ERC20TransferFail","type":"error"},{"inputs":[],"name":"ERC20TransferFromFail","type":"error"},{"inputs":[],"name":"ERC721TransferFromFail","type":"error"},{"inputs":[],"name":"InsufficientNativeTokensSupplied","type":"error"},{"inputs":[],"name":"InvalidCaller","type":"error"},{"inputs":[],"name":"InvalidCurrency","type":"error"},{"inputs":[],"name":"InvalidCutoffTime","type":"error"},{"inputs":[],"name":"InvalidIndex","type":"error"},{"inputs":[],"name":"InvalidPricingOption","type":"error"},{"inputs":[],"name":"InvalidPrize","type":"error"},{"inputs":[],"name":"InvalidPrizesCount","type":"error"},{"inputs":[],"name":"InvalidProtocolFeeBp","type":"error"},{"inputs":[],"name":"InvalidProtocolFeeRecipient","type":"error"},{"inputs":[],"name":"InvalidStatus","type":"error"},{"inputs":[],"name":"InvalidWinnersCount","type":"error"},{"inputs":[],"name":"IsPaused","type":"error"},{"inputs":[],"name":"MaximumEntriesPerParticipantReached","type":"error"},{"inputs":[],"name":"MaximumEntriesReached","type":"error"},{"inputs":[],"name":"NoOngoingTransferInProgress","type":"error"},{"inputs":[],"name":"NotAContract","type":"error"},{"inputs":[],"name":"NotOwner","type":"error"},{"inputs":[],"name":"NotPaused","type":"error"},{"inputs":[{"internalType":"address","name":"have","type":"address"},{"internalType":"address","name":"want","type":"address"}],"name":"OnlyCoordinatorCanFulfill","type":"error"},{"inputs":[],"name":"PrizeAlreadyClaimed","type":"error"},{"inputs":[],"name":"RandomnessRequestAlreadyExists","type":"error"},{"inputs":[],"name":"RandomnessRequestDoesNotExist","type":"error"},{"inputs":[],"name":"ReentrancyFail","type":"error"},{"inputs":[],"name":"RenouncementNotInProgress","type":"error"},{"inputs":[],"name":"TransferAlreadyInProgress","type":"error"},{"inputs":[],"name":"TransferNotInProgress","type":"error"},{"inputs":[],"name":"WrongPotentialOwner","type":"error"},{"anonymous":false,"inputs":[],"name":"CancelOwnershipTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"currencies","type":"address[]"},{"indexed":false,"internalType":"bool","name":"isAllowed","type":"bool"}],"name":"CurrenciesStatusUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint208","name":"amount","type":"uint208"}],"name":"EntryRefunded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint40","name":"entriesCount","type":"uint40"},{"indexed":false,"internalType":"uint208","name":"price","type":"uint208"}],"name":"EntrySold","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeesClaimed","type":"event"},{"anonymous":false,"inputs":[],"name":"InitiateOwnershipRenouncement","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":false,"internalType":"address","name":"potentialOwner","type":"address"}],"name":"InitiateOwnershipTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"NewOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"winnerIndex","type":"uint256[]"}],"name":"PrizesClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"protocolFeeBp","type":"uint16"}],"name":"ProtocolFeeBpUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"protocolFeeRecipient","type":"address"}],"name":"ProtocolFeeRecipientUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":false,"internalType":"enum IRaffle.RaffleStatus","name":"status","type":"uint8"}],"name":"RaffleStatusUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"RandomnessRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"KEY_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAXIMUM_NUMBER_OF_PRIZES_PER_RAFFLE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAXIMUM_NUMBER_OF_WINNERS_PER_RAFFLE","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAXIMUM_PROTOCOL_FEE_BP","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ONE_DAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ONE_HUNDRED_PERCENT_BP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ONE_WEEK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICING_OPTIONS_PER_RAFFLE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REQUEST_CONFIRMATIONS","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUBSCRIPTION_ID","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VRF_COORDINATOR","outputs":[{"internalType":"contract VRFCoordinatorV2Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"}],"name":"cancel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"}],"name":"cancelAfterRandomnessRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cancelOwnershipTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"}],"name":"claimFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"raffleId","type":"uint256"},{"internalType":"uint256[]","name":"winnerIndices","type":"uint256[]"}],"internalType":"struct IRaffle.ClaimPrizesCalldata[]","name":"claimPrizesCalldata","type":"tuple[]"}],"name":"claimPrizes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"currency","type":"address"}],"name":"claimProtocolFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"raffleIds","type":"uint256[]"}],"name":"claimRefund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"confirmOwnershipRenouncement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"confirmOwnershipTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint40","name":"cutoffTime","type":"uint40"},{"internalType":"bool","name":"isMinimumEntriesFixed","type":"bool"},{"internalType":"uint40","name":"minimumEntries","type":"uint40"},{"internalType":"uint40","name":"maximumEntriesPerParticipant","type":"uint40"},{"internalType":"uint16","name":"protocolFeeBp","type":"uint16"},{"internalType":"address","name":"feeTokenAddress","type":"address"},{"components":[{"internalType":"uint40","name":"winnersCount","type":"uint40"},{"internalType":"uint40","name":"cumulativeWinnersCount","type":"uint40"},{"internalType":"enum IRaffle.TokenType","name":"prizeType","type":"uint8"},{"internalType":"uint8","name":"prizeTier","type":"uint8"},{"internalType":"address","name":"prizeAddress","type":"address"},{"internalType":"uint256","name":"prizeId","type":"uint256"},{"internalType":"uint256","name":"prizeAmount","type":"uint256"}],"internalType":"struct IRaffle.Prize[]","name":"prizes","type":"tuple[]"},{"components":[{"internalType":"uint40","name":"entriesCount","type":"uint40"},{"internalType":"uint208","name":"price","type":"uint208"}],"internalType":"struct IRaffle.PricingOption[5]","name":"pricingOptions","type":"tuple[5]"}],"internalType":"struct IRaffle.CreateRaffleCalldata","name":"params","type":"tuple"}],"name":"createRaffle","outputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"}],"name":"depositPrizes","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"raffleId","type":"uint256"},{"internalType":"uint256","name":"pricingOptionIndex","type":"uint256"}],"internalType":"struct IRaffle.EntryCalldata[]","name":"entries","type":"tuple[]"}],"name":"enterRaffles","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"}],"name":"getEntries","outputs":[{"components":[{"internalType":"uint40","name":"currentEntryIndex","type":"uint40"},{"internalType":"address","name":"participant","type":"address"}],"internalType":"struct IRaffle.Entry[]","name":"entries","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"}],"name":"getPricingOptions","outputs":[{"components":[{"internalType":"uint40","name":"entriesCount","type":"uint40"},{"internalType":"uint208","name":"price","type":"uint208"}],"internalType":"struct IRaffle.PricingOption[5]","name":"pricingOptions","type":"tuple[5]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"}],"name":"getPrizes","outputs":[{"components":[{"internalType":"uint40","name":"winnersCount","type":"uint40"},{"internalType":"uint40","name":"cumulativeWinnersCount","type":"uint40"},{"internalType":"enum IRaffle.TokenType","name":"prizeType","type":"uint8"},{"internalType":"uint8","name":"prizeTier","type":"uint8"},{"internalType":"address","name":"prizeAddress","type":"address"},{"internalType":"uint256","name":"prizeId","type":"uint256"},{"internalType":"uint256","name":"prizeAmount","type":"uint256"}],"internalType":"struct IRaffle.Prize[]","name":"prizes","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"}],"name":"getWinners","outputs":[{"components":[{"internalType":"address","name":"participant","type":"address"},{"internalType":"bool","name":"claimed","type":"bool"},{"internalType":"uint8","name":"prizeIndex","type":"uint8"},{"internalType":"uint40","name":"entryIndex","type":"uint40"}],"internalType":"struct IRaffle.Winner[]","name":"winners","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initiateOwnershipRenouncement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPotentialOwner","type":"address"}],"name":"initiateOwnershipTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isCurrencyAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownershipStatus","outputs":[{"internalType":"enum IOwnableTwoSteps.Status","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"potentialOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeeBp","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeeRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"protocolFeeRecipientClaimableFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"raffles","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"enum IRaffle.RaffleStatus","name":"status","type":"uint8"},{"internalType":"bool","name":"isMinimumEntriesFixed","type":"bool"},{"internalType":"uint40","name":"cutoffTime","type":"uint40"},{"internalType":"uint40","name":"drawnAt","type":"uint40"},{"internalType":"uint40","name":"minimumEntries","type":"uint40"},{"internalType":"uint40","name":"maximumEntriesPerParticipant","type":"uint40"},{"internalType":"address","name":"feeTokenAddress","type":"address"},{"internalType":"uint16","name":"protocolFeeBp","type":"uint16"},{"internalType":"uint208","name":"claimableFees","type":"uint208"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rafflesCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"rafflesParticipantsStats","outputs":[{"internalType":"uint208","name":"amountPaid","type":"uint208"},{"internalType":"uint40","name":"entriesCount","type":"uint40"},{"internalType":"bool","name":"refunded","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"randomnessRequests","outputs":[{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"uint248","name":"randomWord","type":"uint248"},{"internalType":"uint256","name":"raffleId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"uint256[]","name":"randomWords","type":"uint256[]"}],"name":"rawFulfillRandomWords","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"selectWinners","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_protocolFeeBp","type":"uint16"}],"name":"setProtocolFeeBp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_protocolFeeRecipient","type":"address"}],"name":"setProtocolFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"togglePaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"currencies","type":"address[]"},{"internalType":"bool","name":"isAllowed","type":"bool"}],"name":"updateCurrenciesStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"}],"name":"withdrawPrizes","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
610120346200022257601f62005fd538819003918201601f19168301916001600160401b03918284118585101762000227578160e09286926040968752833981010312620002225762000052836200023d565b926020810151838201519283168303620002225762000074606083016200023d565b9462000083608084016200023d565b9260c06200009460a083016200023d565b9101519061ffff82169081830362000222576080899052600080546001600160a01b0319166001600160a01b0397881690811790915588519081527f3edd90e7770f06fafde38004653b33870066c33bfc923ff6102acd601f85dfbc90602090a16001805460ff60a81b1916600160a81b1790556109c48211620002115785907fede4aee4284b8033b84c1aadcc51b229a4e46e6b42ab40092e237f07508b46266020600754948b51908152a11691821562000200576001600160b01b031990911660a09190911b61ffff60a01b1617811760075585519081527fc1b5345cce283376356748dc57f2dfa7120431d016fc7ca9ba641bc65f91411d90602090a160a05260c0526101009316835260e05251615d8291826200025383396080518261571b015260a05182818161294501528181614bf3015261518e015260c0518281816114970152614e6f015260e05182818161044f0152614e950152518181816104bf0152614ee40152f35b8751633106a0c760e01b8152600490fd5b8751634929acd760e01b8152600490fd5b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b0382168203620002225756fe60806040526004361015610013575b600080fd5b60003560e01c8063030932bb146103fb57806305f6a924146103f25780631e9f1a82146103e95780631fe543e3146103e057806323452b9c146103d75780632a6a4eb8146103ce5780632bb5a9e6146103c557806331fe74a9146103bc57806336566f06146103b357806339a2eb2a146103aa5780633b6cb153146103a15780633e5675391461039857806340e58ee51461038f578063436313b21461038657806349890e151461037d5780634d2c53cd1461037457806351dc86a51461036b578063534fff0e146103625780635708b502146103595780635a195d19146103505780635b6ac011146103475780635c975abb1461033e5780635cb6dfff146103355780635d4bc0ce1461032c57806364df049e1461032357806365d697f71461031a57806367f082b014610311578063689869121461030857806369ce6d47146102ff5780636b1426a4146102f65780636f30d7b5146102ed5780637200b829146102e45780637762df25146102db57806382d6848c146102d2578063863e76db146102c95780638da5cb5b146102c05780638e6f6b77146102b757806398753c46146102ae578063a17be154146102a5578063a72844ba1461029c578063ac68a74814610293578063ad5c46481461028a578063c0b6f56114610281578063cc30779514610278578063d3549ebd1461026f578063d49a563014610266578063e521cb921461025d578063f23a6e6114610254578063f42df1321461024b5763f54a6f831461024357600080fd5b61000e613a4c565b5061000e6133de565b5061000e613338565b5061000e613257565b5061000e612d0c565b5061000e612c55565b5061000e612b3c565b5061000e612969565b5061000e6128f9565b5061000e61261b565b5061000e612520565b5061000e61246a565b5061000e612426565b5061000e6123e9565b5061000e612396565b5061000e612359565b5061000e612162565b5061000e61210f565b5061000e611f9e565b5061000e611cf1565b5061000e611bc4565b5061000e611ac1565b5061000e611a86565b5061000e611a4b565b5061000e611a10565b5061000e6119bd565b5061000e6118f1565b5061000e6117d3565b5061000e61178e565b5061000e6116a3565b5061000e611634565b5061000e6115f8565b5061000e6114ba565b5061000e611460565b5061000e611423565b5061000e6113e7565b5061000e61137d565b5061000e6111c9565b5061000e6110bc565b5061000e611081565b5061000e610db4565b5061000e610c6d565b5061000e610ba5565b5061000e610af0565b5061000e6109bd565b5061000e610897565b5061000e6107ea565b5061000e61051e565b5061000e610473565b5061000e61040f565b600091031261000e57565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060405167ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b9181601f8401121561000e5782359167ffffffffffffffff831161000e576020808501948460051b01011161000e57565b8015150361000e57565b503461000e576040807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760043567ffffffffffffffff811161000e5761056f9036906004016104e3565b91906024359261057e84610514565b610586615885565b60005b8181106106145750808351938085019085525260608301919060005b8181106105dc5785151560208601527fcb2fef16ee9f3ea43e174daf88ffcdc8beee4ad884c7570093d998d71058698785850386a1005b90919260019073ffffffffffffffffffffffffffffffffffffffff853561060281611354565b168152602090810194019291016105a5565b8073ffffffffffffffffffffffffffffffffffffffff6106376001938587614627565b3561064181611354565b16600052600560205261068286866000209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b01610589565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040810190811067ffffffffffffffff8211176106d457604052565b6106dc610688565b604052565b60a0810190811067ffffffffffffffff8211176106d457604052565b6080810190811067ffffffffffffffff8211176106d457604052565b60e0810190811067ffffffffffffffff8211176106d457604052565b67ffffffffffffffff81116106d457604052565b610100810190811067ffffffffffffffff8211176106d457604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176106d457604052565b604051906107b4826106fd565b565b604051906107b4826106b8565b60209067ffffffffffffffff81116107dd575b60051b0190565b6107e5610688565b6107d6565b503461000e5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760243567ffffffffffffffff811161000e573660238201121561000e57806004013590610846826107c3565b906108546040519283610766565b82825260209260248484019160051b8301019136831161000e57602401905b8282106108885761088684600435615719565b005b81358152908401908401610873565b503461000e576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126109ae576108d0615885565b60015460ff8160a01c1660038110156109a1575b801561097757806108f6600192610ade565b1461094c575b507fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff600154166001557f8eca980489e87f7dba4f26917aa4bfc906eb3f2b4f7b4b9fd0ff2b8bb3e21ae38180a180f35b7fffffffffffffffffffffffff000000000000000000000000000000000000000016600155386108fc565b60046040517fccf69db7000000000000000000000000000000000000000000000000000000008152fd5b6109a9610aae565b6108e4565b80fd5b61ffff81160361000e57565b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576004356109f9816109b1565b610a01615885565b61ffff8116906109c48211610a84577fede4aee4284b8033b84c1aadcc51b229a4e46e6b42ab40092e237f07508b4626916020917fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff75ffff00000000000000000000000000000000000000006007549260a01b16911617600755604051908152a1005b60046040517f4929acd7000000000000000000000000000000000000000000000000000000008152fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60031115610ae857565b6107b4610aae565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060ff60015460a01c16604051906003811015610b3c578152f35b610b44610aae565b8152f35b610140810192916000915b60058310610b6057505050565b600190604083519164ffffffffff835116815279ffffffffffffffffffffffffffffffffffffffffffffffffffff602080940151168382015201920192019190610b53565b503461000e576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576040908151610be4816106e1565b8160005b60a08110610c4c57505050600435600052600381526003826000200190825191610c11836106e1565b90600090835b60058310610c3057855180610c2c8782610b48565b0390f35b6001828192610c3e8761413a565b815201940192019192610c17565b8451610c57816106b8565b6000815260008382015281840152018290610be8565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57610ca5615885565b60015460ff8160b01c16600014610d41575060015460ff8160b01c1615610d17577fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff166001557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a1005b60046040517f6cd60201000000000000000000000000000000000000000000000000000000008152fd5b7fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff76010000000000000000000000000000000000000000000091610d836158d0565b16176001557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a1005b503461000e576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57610e03610dfe6004356000526006602052604060002090565b614272565b610e14610e108251151590565b1590565b611057576040908181015190610e47610e37836000526003602052604060002090565b92610e418461503b565b836151b2565b6008820193845493610e80610e76610e67610e61886142bd565b89613eb0565b505460281c64ffffffffff1690565b64ffffffffff1690565b610e8c600986016142ea565b90815194610eb4610e76610ea8610ea2896142bd565b8661438d565b515164ffffffffff1690565b90610ec9610ec48360081c6140e3565b6143af565b98610ed3886143af565b9760005b818110611029575050610ee9816143af565b9a60005b828110610ffa575050508501517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690600a60009801915b838910610f2d57005b8a99610f38836140e3565b610f42908361442e565b90610f4d91846155c7565b999088610f5a828c615677565b610f64908961438d565b51015173ffffffffffffffffffffffffffffffffffffffff16916001019b8c610f8c91615677565b60ff16610f976107a7565b73ffffffffffffffffffffffffffffffffffffffff90931683526000838b015260ff168883015264ffffffffff166060820152610fd49084614444565b8551878101918252808203808252610fef9060200182610766565b519020989798610f24565b808d61101d82979e9d9897611017610e76610e6760019789613eb0565b9261438d565b52019a9394999a610eed565b80611041610e76610ea8979e9d98976001948b61438d565b61104b828d61438d565b52019a9394999a610ed7565b60046040517f1b71a84c000000000000000000000000000000000000000000000000000000008152fd5b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576020604051606e8152f35b503461000e576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126109ae576110f5615885565b600260ff60015460a01c1660038110156111bc575b03611192577fffffffffffffffffffffffff000000000000000000000000000000000000000081541681556111627fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff60015416600155565b604051600081527f3edd90e7770f06fafde38004653b33870066c33bfc923ff6102acd601f85dfbc90602090a180f35b60046040517f045c5122000000000000000000000000000000000000000000000000000000008152fd5b6111c4610aae565b61110a565b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57600435600154600260ff8260a81c161461132a577fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff167502000000000000000000000000000000000000000000176001556112526158d0565b8060005260036020526040600020805491600260ff8460a01c1661127581611837565b149283156113175764ffffffffff429160b01c16116112ed576112a0925b156112e557600791615532565b61088675010000000000000000000000000000000000000000007fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff6001541617600155565b600891615532565b60046040517ff9ad93f5000000000000000000000000000000000000000000000000000000008152fd5b506112a09261132583615063565b611293565b60046040517f1bbee726000000000000000000000000000000000000000000000000000000008152fd5b73ffffffffffffffffffffffffffffffffffffffff81160361000e57565b35906107b482611354565b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5773ffffffffffffffffffffffffffffffffffffffff6004356113ce81611354565b1660005260086020526020604060002054604051908152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760206040516109c48152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576020600254604051908152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576004356001908154600260ff8260a81c161461132a577fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675020000000000000000000000000000000000000000001782556115446158d0565b80600052600360205261156560406000209161155f8361507d565b82615222565b6008810173ffffffffffffffffffffffffffffffffffffffff815492541660005b8381106115d25761088675010000000000000000000000000000000000000000007fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff6001541617600155565b806115f26115e1879386613eb0565b508464ffffffffff82541691614b5c565b01611586565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760206040516127108152f35b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5773ffffffffffffffffffffffffffffffffffffffff60043561168581611354565b166000526005602052602060ff604060002054166040519015158152f35b503461000e576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126109ae576116dc615885565b60015460ff8160a01c166003811015611781575b611757577fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674020000000000000000000000000000000000000000176001557f3ff05a45e46337fa1cbf20996d2eeb927280bce099f37252bcca1040609604ec8180a180f35b60046040517f74ed79ae000000000000000000000000000000000000000000000000000000008152fd5b611789610aae565b6116f0565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060ff60015460b01c166040519015158152f35b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57600435600052600660205260606040600020600181549101546040519160ff81161515835260081c60208301526040820152f35b60091115610ae857565b90600982101561184e5752565b611856610aae565b52565b9896929a99979493919a9590956101408a019b73ffffffffffffffffffffffffffffffffffffffff8098168b5260208b0161189391611841565b151560408a015264ffffffffff80948180941660608c01521660808a01521660a08801521660c08601521660e084015261ffff1661010083015279ffffffffffffffffffffffffffffffffffffffffffffffffffff16906101200152565b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57600435600052600360205260406000208054610c2c6119626002600185015494015479ffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b60405193849373ffffffffffffffffffffffffffffffffffffffff9164ffffffffff928160f01c93818360501c169381808560281c169416928160d81c928260b01c169160ff8160a81c169160ff8260a01c1691168b611859565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602073ffffffffffffffffffffffffffffffffffffffff60075416604051908152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060405160148152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060405160038152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060405160058152f35b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57600435611afd81611354565b611b05615885565b611b4073ffffffffffffffffffffffffffffffffffffffff600092818116845260086020526040842054918460408120556007541690614bcb565b80f35b60208082019080835283518092528060408094019401926000905b838210611b6d57505050505090565b8451805173ffffffffffffffffffffffffffffffffffffffff168752808401511515878501528082015160ff168783015260609081015164ffffffffff169087015260809095019493820193600190910190611b5e565b503461000e576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760043560005260038152604090600a8260002001805490611c15826107c3565b92611c2285519485610766565b82845260009182528082208185015b848410611c4557865180610c2c8882611b43565b60018381928951611c55816106fd565b64ffffffffff865473ffffffffffffffffffffffffffffffffffffffff8116835260ff808260a01c161515868501528160a81c168d84015260b01c166060820152815201920193019290611c31565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc82011261000e576004359067ffffffffffffffff821161000e57611ced916004016104e3565b9091565b503461000e57611d0036611ca4565b60019182549060ff916002838260a81c161461132a577fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff167502000000000000000000000000000000000000000000178455611d5a6158d0565b60005b838110611da95761088675010000000000000000000000000000000000000000007fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff6001541617600155565b60059080821b830135917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18436030183121561000e5786928401803590611dfa826000526003602052604060002090565b92611e0a845460ff9060a01c1690565b611e1381611837565b03611f90575b91611e2c600a8201936020810190614d36565b919093805490600860009301905b848410611e81575050505090611e787f0d0ab4a45afc0276ae825be9eeb4552011b19aad5c92b4bb782f3ca0356fedc5939260405193849384614d8a565b0390a101611d5d565b9091929750611e91888588614627565b3583811015611f6657611ea490826141a7565b508054988b8a60a01c16611f3c57611f33611f2b8f9b8c94611ede73ffffffffffffffffffffffffffffffffffffffff611f2593166150ff565b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001781555460a81c60ff1690565b86613eb0565b503390614ada565b01929190611e3a565b60046040517fc2356312000000000000000000000000000000000000000000000000000000008152fd5b60046040517f63df8171000000000000000000000000000000000000000000000000000000008152fd5b611f9983615097565b611e19565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57600154600160ff8260a01c16611fe381610ade565b036120e55773ffffffffffffffffffffffffffffffffffffffff1633036120bb57600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317905561205b7fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff60015416600155565b6120887fffffffffffffffffffffffff000000000000000000000000000000000000000060015416600155565b6040513381527f3edd90e7770f06fafde38004653b33870066c33bfc923ff6102acd601f85dfbc9080602081015b0390a1005b60046040517fafdcfb92000000000000000000000000000000000000000000000000000000008152fd5b60046040517f5e4f2826000000000000000000000000000000000000000000000000000000008152fd5b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602073ffffffffffffffffffffffffffffffffffffffff60015416604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760043560019081549160029060ff9382858260a81c161461132a577fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675020000000000000000000000000000000000000000001781556121ec6158d0565b612200836000526003602052604060002090565b9361220a85615063565b61223061222b865473ffffffffffffffffffffffffffffffffffffffff1690565b6150ff565b6008850192835491600094855b848110612257576112a0888a6122528a615147565b615292565b80612263879284613eb0565b508054858160501c1661227581612a79565b8061229f575050808361228c612299935460601c90565b9101549030903390615b27565b0161223d565b90919293506122ad81612a79565b600381036122e6575050906122e1826122d4878a955492015464ffffffffff8316906140d0565b903090339060601c615a4d565b612299565b806122f488929b959b612a79565b0361232b5750869161231f82612319610e7689612325960154925464ffffffffff1690565b906140d0565b906140f1565b96612299565b6122e1908261234c888b80979d96015492015464ffffffffff8416906140d0565b913090339060601c615975565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576020604051620151808152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602073ffffffffffffffffffffffffffffffffffffffff60005416604051908152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060405162093a808152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602061ffff60075460a01c16604051908152f35b503461000e5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760606124e06024356124ab81611354565b600435600052600460205260406000209073ffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b546040519079ffffffffffffffffffffffffffffffffffffffffffffffffffff8116825264ffffffffff8160d01c16602083015260f81c15156040820152f35b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760043561255b615885565b600154600260ff8260a81c161461132a577fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff75020000000000000000000000000000000000000000009116176001558060005260036020526040600020906125c2826150b1565b815460d81c62015180810180911161260e575b42106125e4576112a091615302565b60046040517ff4c0ca6e000000000000000000000000000000000000000000000000000000008152fd5b612616613e5f565b6125d5565b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760043560015490600260ff8360a81c161461132a5775020000000000000000000000000000000000000000007fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff7fa1f87f32d0f17fab0242ca800d736293de8988c14b27747e218cf13d5c249f539316176001556126c76158d0565b806126dc816000526003602052604060002090565b6126e5816150cb565b6127cd612706825473ffffffffffffffffffffffffffffffffffffffff1690565b9173ffffffffffffffffffffffffffffffffffffffff831633036128d2575b6128196002820191612812612754845479ffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b936127f560018401916127a261277e612778612771865460f01c90565b61ffff1690565b896145b8565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff61271091160490565b97889779ffffffffffffffffffffffffffffffffffffffffffffffffffff998a9103169b8c96615372565b7fffffffffffff00000000000000000000000000000000000000000000000000008154169055565b5460501c73ffffffffffffffffffffffffffffffffffffffff1690565b9485614bcb565b169081612894575b50506040805191825279ffffffffffffffffffffffffffffffffffffffffffffffffffff929092166020820152a161088675010000000000000000000000000000000000000000007fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff6001541617600155565b6128c16128c99173ffffffffffffffffffffffffffffffffffffffff166000526008602052604060002090565b9182546140f1565b90553880612821565b6128f461222b60005473ffffffffffffffffffffffffffffffffffffffff1690565b612725565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576004356129a581611354565b6129ad615885565b60015460ff8160a01c166003811015612a6c575b611757577fffffffffffffffffffffff0000000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff82161774010000000000000000000000000000000000000000176001557fb86c75c9bffca616b2d314cc914f7c3f1d174255b16b941c3f3ededee276d5ef906120b6906040805133815273ffffffffffffffffffffffffffffffffffffffff909216602083015290918291820190565b612a74610aae565b6129c1565b60041115610ae857565b60208082019080835283518092528060408094019401926000905b838210612aad57505050505090565b90919293948360e0600192885164ffffffffff808251168352848201511684830152858101516004811015612b2f575b8287015260608181015160ff169083015260808082015173ffffffffffffffffffffffffffffffffffffffff169083015260a0818101519083015260c090810151908201520196019493920190612a9e565b612b37610aae565b612add565b503461000e576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576004356000526003908181526040916008836000200190815491612b90836107c3565b93612b9d86519586610766565b83855260009182528082208186015b858410612bc057875180610c2c8982612a83565b84836001928a51612bd081610719565b612c34865464ffffffffff80821684528160281c16858401528d612bfe60ff91828460501c1690860161463f565b612c146060918360581c168286019060ff169052565b1c608083019073ffffffffffffffffffffffffffffffffffffffff169052565b8486015460a0820152600286015460c0820152815201920193019290612bac565b503461000e576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760043560005260038152604090612ca2600983600020016142ea565b8251928284938401908085528351809252808386019401926000905b838210612ccb5786860387f35b8451805164ffffffffff16875283015173ffffffffffffffffffffffffffffffffffffffff1686840152879650948501949382019360019190910190612cbe565b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc90808236011261000e57600480359167ffffffffffffffff831161000e5761022083830194843603011261000e57612d6c84613ce3565b64ffffffffff938482168062015180420111908115613248575b5061321f57612d9760848201613cf0565b91612dac61277160075461ffff9060a01c1690565b61ffff8416036131f657612dc260a48301613cfa565b9473ffffffffffffffffffffffffffffffffffffffff8616613192575b60025460010196612def88600255565b60c4840195612dfe878b613d04565b809150158015613188575b61315f5790612e228a6000526003602052604060002090565b9a8b916000998a9260088c9501945b8681106130bd575050505050505080612e4c60448601613ce3565b961690861681119081156130b2575b5061308a5750938593613026610c2c9894612fd7612f9c606487612f5c61307a9c612e8d8d60e46130759d019061477f565b8b547fffffffffffffffffffffffff00000000000000000000000000000000000000001633178c55612f10612ec4602485016140b5565b8d805490917fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff90911690151560a81b75ff00000000000000000000000000000000000000000016179055565b8b547fffffffffff0000000000ffffffffffffffffffffffffffffffffffffffffffff1660b09190911b7affffffffff0000000000000000000000000000000000000000000016178b55565b612f9660018b0197889064ffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000825416179055565b01613ce3565b84547fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff1660289190911b69ffffffffff000000000016178455565b82547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f09190911b7fffff00000000000000000000000000000000000000000000000000000000000016178255565b907fffff0000000000000000000000000000000000000000ffffffffffffffffffff7dffffffffffffffffffffffffffffffffffffffff0000000000000000000083549260501b169116179055565b6153e2565b6040519081529081906020820190565b6040517f804a1e02000000000000000000000000000000000000000000000000000000008152fd5b606e91501138612e5b565b6130eb9c6130dd6130d8836130d28787613d04565b90613d88565b613dc0565b95606087019e8f5160ff1690565b60ff91821691161061313657613100866149a7565b855164ffffffffff1661311291613e8f565b64ffffffffff8116868601529c5160ff169461312e9087613f0a565b600101612e31565b896040517f5f12e2ee000000000000000000000000000000000000000000000000000000008152fd5b836040517fab13062d000000000000000000000000000000000000000000000000000000008152fd5b5060148111612e09565b6131c9610e106131c28873ffffffffffffffffffffffffffffffffffffffff166000526005602052604060002090565b5460ff1690565b15612ddf576040517ff5993428000000000000000000000000000000000000000000000000000000008152fd5b846040517f4929acd7000000000000000000000000000000000000000000000000000000008152fd5b836040517fce8f4bfd000000000000000000000000000000000000000000000000000000008152fd5b905062093a8042011038612d86565b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5773ffffffffffffffffffffffffffffffffffffffff6004356132a881611354565b6132b0615885565b16801561330e576020817fc1b5345cce283376356748dc57f2dfa7120431d016fc7ca9ba641bc65f91411d927fffffffffffffffffffffffff00000000000000000000000000000000000000006007541617600755604051908152a1005b60046040517f3106a0c7000000000000000000000000000000000000000000000000000000008152fd5b503461000e5760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57613373600435611354565b61337e602435611354565b60843567ffffffffffffffff80821161000e573660238301121561000e57816004013590811161000e573691016024011161000e576040517ff23a6e61000000000000000000000000000000000000000000000000000000008152602090f35b506020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57600490813567ffffffffffffffff9283821161000e573660238301121561000e578181013593841161000e576024820191602436918660061b01011161000e5760019283546002908160ff8260a81c1614613a23577fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675020000000000000000000000000000000000000000001785556134a36158d0565b600095865b8181106134d4576112a079ffffffffffffffffffffffffffffffffffffffffffffffffffff8916615147565b6134df8183886140fe565b848101359060058210156139fa573590613503826000526003602052604060002090565b9061350d826150e5565b81546135229060b01c64ffffffffff16610e76565b4210156139d15761353961353f916003840161411c565b5061413a565b6135a06135906135823361355d876000526004602052604060002090565b9073ffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b5460d01c64ffffffffff1690565b825164ffffffffff165b90613e8f565b828b0180546135b89060281c64ffffffffff16610e76565b9164ffffffffff92838216116139a857613634906135e43361355d896000526004602052604060002090565b907fff0000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff7effffffffff000000000000000000000000000000000000000000000000000083549260d01b169116179055565b8289015179ffffffffffffffffffffffffffffffffffffffffffffffffffff169c613677825473ffffffffffffffffffffffffffffffffffffffff9060501c1690565b73ffffffffffffffffffffffffffffffffffffffff811661396f5750906136a48e8e989796959493614179565b9d5b60098501938a8554801560001461391d57506136f97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6136ee610e76855164ffffffffff1690565b0164ffffffffff1690565b955b87548e9060a81c60ff166138bc575b9361384c610e76946137fd7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff98956137898c7fc25cd4cec0cbfb9bc40ad8f59ac733efcddf6ed3b7519369c9b9ceb2ee7846019761378461389a9c61377d6137706107b6565b64ffffffffff9095168552565b3390840152565b6141cd565b8c016137b8856137b3835479ffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b614179565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffffffff0000000000000000000000000000000000000000000000000000825416179055565b6138416138198d61355d33916000526004602052604060002090565b6137b8856137b3835479ffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b5164ffffffffff1690565b604080518c815233602082015264ffffffffff929092169082015279ffffffffffffffffffffffffffffffffffffffffffffffffffff919091166060820152608090a15464ffffffffff1690565b01911610156138ac575b5050016134a8565b6138b591614dee565b38806138a4565b5091929394959697989950506138da610e76855464ffffffffff1690565b85871610156138f457908a8f99989796959493928d61370a565b8c6040517f34b3fb3b000000000000000000000000000000000000000000000000000000008152fd5b61395b61394f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6139699301896141a7565b505464ffffffffff1690565b835164ffffffffff1661359a565b956136fb565b9d6139a38e989796959493929f79ffffffffffffffffffffffffffffffffffffffffffffffffffff83169030903390615a4d565b6136a6565b8a6040517fd085f161000000000000000000000000000000000000000000000000000000008152fd5b876040517fb68c78dc000000000000000000000000000000000000000000000000000000008152fd5b866040517f63df8171000000000000000000000000000000000000000000000000000000008152fd5b836040517f1bbee726000000000000000000000000000000000000000000000000000000008152fd5b503461000e57613a5b36611ca4565b906001918254600260ff8260a81c161461132a577fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff167502000000000000000000000000000000000000000000178355613ab36158d0565b60005b818110613b025761088675010000000000000000000000000000000000000000007fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff6001541617600155565b613b0d818385614627565b3590613b23826000526003602052604060002090565b805460079060a01c60ff16613b3781611837565b10613caa57613b543361355d856000526004602052604060002090565b90613b60825460f81c90565b613c80578693613c43613c1e86613bff86613bdf7fc0b7cf12926534c2d86d0abb17d620a3a06e07a84b3b8156a4b21189222b16d2987f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff825416179055565b5479ffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b94015460501c73ffffffffffffffffffffffffffffffffffffffff1690565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff8416903390614bcb565b6040805191825233602083015279ffffffffffffffffffffffffffffffffffffffffffffffffffff9290921691810191909152606090a101613ab6565b60046040517fa85e6f1a000000000000000000000000000000000000000000000000000000008152fd5b60046040517ff525e320000000000000000000000000000000000000000000000000000000008152fd5b64ffffffffff81160361000e57565b35613ced81613cd4565b90565b35613ced816109b1565b35613ced81611354565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561000e570180359067ffffffffffffffff821161000e576020019160e082023603831361000e57565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9160e091811015613d9857020190565b613da0613d58565b020190565b3590600482101561000e57565b359060ff8216820361000e57565b60e08136031261000e5760c06040519160e0830183811067ffffffffffffffff821117613e52575b6040528035613df681613cd4565b83526020810135613e0681613cd4565b6020840152613e1760408201613da5565b6040840152613e2860608201613db2565b6060840152613e3960808201611372565b608084015260a081013560a0840152013560c082015290565b613e5a610688565b613de8565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b91909164ffffffffff80809416911601918211613ea857565b6107b4613e5f565b8054821015613ecd575b6000526003602060002091020190600090565b613ed5613d58565b613eba565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b60c0613f32600292805490680100000000000000008210156140a8575b600182018155613eb0565b93909361409b575b80518454602083015164ffffffffff9092167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000009091161760289190911b69ffffffffff0000000000161784556040810151600481101561408e575b7fffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff6aff0000000000000000000086549260501b16911617845561401c613fdf606083015160ff1690565b85547fffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffff1660589190911b6bff000000000000000000000016178555565b61407d614040608083015173ffffffffffffffffffffffffffffffffffffffff1690565b85546bffffffffffffffffffffffff1660609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016178555565b60a081015160018501550151910155565b614096610aae565b613f95565b6140a3613eda565b613f3a565b6140b0610688565b613f27565b35613ced81610514565b9081156001838004141715613ea857565b81810292918115918404141715613ea857565b9060018201809211613ea857565b91908201809211613ea857565b919081101561410f575b60061b0190565b614117613d58565b614108565b600582101561412d575b0190600090565b614135613d58565b614126565b90604051614147816106b8565b915464ffffffffff8116835260281c79ffffffffffffffffffffffffffffffffffffffffffffffffffff166020830152565b91909179ffffffffffffffffffffffffffffffffffffffffffffffffffff80809416911601918211613ea857565b80548210156141c0575b60005260206000200190600090565b6141c8613d58565b6141b1565b6141f360209180549068010000000000000000821015614265575b6001820181556141a7565b929092614258575b8051835492909101517fffffffffffffff0000000000000000000000000000000000000000000000000090921664ffffffffff9091161760289190911b78ffffffffffffffffffffffffffffffffffffffff000000000016179055565b614260613eda565b6141fb565b61426d610688565b6141e8565b906040516060810181811067ffffffffffffffff8211176142b0575b604052604060018294805460ff81161515855260081c60208501520154910152565b6142b8610688565b61428e565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201918211613ea857565b9081546142f6816107c3565b9260409361430685519182610766565b828152809460208092019260005281600020906000935b85851061432c57505050505050565b6001848192845161433c816106b8565b73ffffffffffffffffffffffffffffffffffffffff875464ffffffffff8116835260281c168382015281520193019401939161431d565b602090805115614381570190565b614389613d58565b0190565b60209181518110156143a2575b60051b010190565b6143aa613d58565b61439a565b906143b9826107c3565b6143c66040519182610766565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06143f482946107c3565b0190602036910137565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8115614438570690565b6144406143fe565b0690565b9064ffffffffff60606144736107b49480549068010000000000000000821015614265576001820181556141a7565b9390936145ab575b805184547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9190911617845561455d61450f6020830151151586549074ff00000000000000000000000000000000000000007fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9160a01b1691161790565b80865560ff60408401511675ff0000000000000000000000000000000000000000007fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff9160a81b1691161790565b9101517fffffffffff0000000000ffffffffffffffffffffffffffffffffffffffffffff909116911660b01b7affffffffff0000000000000000000000000000000000000000000016179055565b6145b3613eda565b61447b565b919079ffffffffffffffffffffffffffffffffffffffffffffffffffff8080941691169283820216928184041490151715613ea857565b9079ffffffffffffffffffffffffffffffffffffffffffffffffffff80911691821561461a57160490565b6146226143fe565b160490565b91908110156146375760051b0190565b6107e5613d58565b600482101561184e5752565b90600581101561410f5760061b0190565b60408136031261000e576020604051916040830183811067ffffffffffffffff8211176146c1575b604052803561469281613cd4565b8352013579ffffffffffffffffffffffffffffffffffffffffffffffffffff8116810361000e57602082015290565b6146c9610688565b614684565b9079ffffffffffffffffffffffffffffffffffffffffffffffffffff8091169182156146f957160690565b6147016143fe565b160690565b91602091614772575b8051835492909101517fff0000000000000000000000000000000000000000000000000000000000000090921664ffffffffff9091161760289190911b7effffffffffffffffffffffffffffffffffffffffffffffffffff000000000016179055565b61477a613eda565b61470f565b60005b6005811061478f57505050565b6147a161479c828561464b565b61465c565b906147b1825164ffffffffff1690565b6020906147da8285015179ffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b918361487b575064ffffffffff1660011480159190614856575b5061482c576148266001925b61482083600361481a886000526003602052604060002090565b0161411c565b90614706565b01614782565b60046040517f0b9752e0000000000000000000000000000000000000000000000000000000008152fd5b79ffffffffffffffffffffffffffffffffffffffffffffffffffff91501615386147f4565b91906148e16148d56148b261479c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff88018b61464b565b9485015179ffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b935164ffffffffff1690565b9064ffffffffff8091169379ffffffffffffffffffffffffffffffffffffffffffffffffffff918261491387876146ce565b16159485159561499a575b851561498b575b8515614942575b5050505050905061482c57614826600192614800565b61495e93955061497d9496614956916145ef565b9516906145ef565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b91161180388080808061492c565b82841684821611159550614925565b848216871115955061491e565b6040810180516149b681612a79565b6149bf81612a79565b614a1a5750600160c08201511490811591614a06575b506149dc57565b60046040517f5f12e2ee000000000000000000000000000000000000000000000000000000008152fd5b5164ffffffffff16600114159050386149d5565b60039051614a2781612a79565b614a3081612a79565b14614a5b575b60c081015115908115614a4a57506149dc57565b5164ffffffffff16159050386149d5565b614aab610e106131c2614a85608085015173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff166000526005602052604060002090565b15614a365760046040517ff5993428000000000000000000000000000000000000000000000000000000008152fd5b9081549060ff8260501c169160601c91614af381612a79565b80614b09575060016107b4930154913090615b27565b80614b15600192612a79565b03614b3957916107b492614b31600260018401549301546140bf565b923090615975565b60026107b493015491828004600114831517614bcb57614b57613e5f565b614bcb565b80549192606083901c9260501c60ff16614b7581612a79565b80614b8d5750509160016107b4930154913090615b27565b80614b9c600192969396612a79565b03614bb757614b316107b494600260018501549401546140d0565b906107b4936002614bc99201546140d0565b915b90919073ffffffffffffffffffffffffffffffffffffffff8116614c175750906107b4915a917f0000000000000000000000000000000000000000000000000000000000000000615bdd565b803b15614d0c576040517fa9059cbb000000000000000000000000000000000000000000000000000000006020820190815273ffffffffffffffffffffffffffffffffffffffff9094166024820152604481019290925260009283928390614caa81606481015b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282610766565b51925af1614cb6615909565b9015614ce257805180614cc7575050565b81602080610e1093614cdc9501019101615a38565b614ce257565b60046040517ff1568f95000000000000000000000000000000000000000000000000000000008152fd5b60046040517f09ee12d5000000000000000000000000000000000000000000000000000000008152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561000e570180359067ffffffffffffffff821161000e57602001918160051b3603831361000e57565b908152604060208201528260408201527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831161000e5760609260051b809284830137010190565b9081602091031261000e575190565b506040513d6000823e3d90fd5b90614e4790614dfd8382615452565b80547affffffffffffffffffffffffffffffffffffffffffffffffffffff164260d81b7fffffffffff00000000000000000000000000000000000000000000000000000016179055565b6040517f5d3b1d300000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff166024820152600360448201526207a12060648201526001608482015260208160a48160007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff165af190811561502e575b600091615000575b50614f436131c2826000526006602052604060002090565b614fd6577f3d94fecedaa4f90b8bd459797adb95f5bb11426025c5541390d9ccc1ad1b60a191614fab614f80836000526006602052604060002090565b60017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00825416179055565b806001614fc2846000526006602052604060002090565b0155604080519182526020820192909252a1565b60046040517ff9012132000000000000000000000000000000000000000000000000000000008152fd5b615021915060203d8111615027575b6150198183610766565b810190614dd2565b38614f2b565b503d61500f565b615036614de1565b614f23565b60ff6004915460a01c166009811015615056575b03613caa57565b61505e610aae565b61504f565b60ff6001915460a01c1660098110156150565703613caa57565b60ff6007915460a01c1660098110156150565703613caa57565b60ff6006915460a01c1660098110156150565703613caa57565b60ff6003915460a01c1660098110156150565703613caa57565b60ff6005915460a01c1660098110156150565703613caa57565b60ff6002915460a01c1660098110156150565703613caa57565b73ffffffffffffffffffffffffffffffffffffffff16330361511d57565b60046040517f48f5c3ed000000000000000000000000000000000000000000000000000000008152fd5b348111156151795760046040517f8ffff980000000000000000000000000000000000000000000000000000000008152fd5b8034116151835750565b6107b4905a903403337f0000000000000000000000000000000000000000000000000000000000000000615bdd565b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167405000000000000000000000000000000000000000017905560408051918252600560208301527fc1191e7178b58ad510709587719f39ec315fa79e81ee7ba5c5ef3c894e94a65191a1565b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167408000000000000000000000000000000000000000017905560408051918252600860208301527fc1191e7178b58ad510709587719f39ec315fa79e81ee7ba5c5ef3c894e94a65191a1565b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167402000000000000000000000000000000000000000017905560408051918252600260208301527fc1191e7178b58ad510709587719f39ec315fa79e81ee7ba5c5ef3c894e94a65191a1565b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167407000000000000000000000000000000000000000017905560408051918252600760208301527fc1191e7178b58ad510709587719f39ec315fa79e81ee7ba5c5ef3c894e94a65191a1565b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167406000000000000000000000000000000000000000017905560408051918252600660208301527fc1191e7178b58ad510709587719f39ec315fa79e81ee7ba5c5ef3c894e94a65191a1565b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000017905560408051918252600160208301527fc1191e7178b58ad510709587719f39ec315fa79e81ee7ba5c5ef3c894e94a65191a1565b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167403000000000000000000000000000000000000000017905560408051918252600360208301527fc1191e7178b58ad510709587719f39ec315fa79e81ee7ba5c5ef3c894e94a65191a1565b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167404000000000000000000000000000000000000000017905560408051918252600460208301527fc1191e7178b58ad510709587719f39ec315fa79e81ee7ba5c5ef3c894e94a65191a1565b906155b77fc1191e7178b58ad510709587719f39ec315fa79e81ee7ba5c5ef3c894e94a6519360409360098210156155ba575b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1660a083901b74ff00000000000000000000000000000000000000001617905583519283526020830190611841565ba1565b6155c2610aae565b615565565b909291928060081c600160ff81808286161b925b615601575b5050819293506155f36155fc928761438d565b5117918561438d565b529190565b9290939180615610838a61438d565b51161561566d57508185036156375750508060009283945b94939284821683901b926155db565b91909392818501809511615660575b80851615615657575b819293615628565b9181019161564f565b615668613e5f565b615646565b91938193506155e0565b8051918215615711576000925b8084106156e0575082151591826156c2575b505015613ced577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b6156d79192506156d1846142bd565b9061438d565b51143880615696565b6156ea8185615d2f565b9081836156f7828761438d565b511115615705575050615684565b60010194509050615684565b505050600090565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff81163303615836575080600052600660205260ff60406000205416615772575050565b600160406000200154918260005260036020526040600020600360ff825460a01c1661579d81611837565b146157a9575b50505050565b6157c56157fb926157c061582d966157ea946154c2565b614373565b517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b916000526006602052604060002090565b9060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083549260081b169116179055565b388080806157a3565b6040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff919091166024820152604490fd5b73ffffffffffffffffffffffffffffffffffffffff6000541633036158a657565b60046040517f30cd7471000000000000000000000000000000000000000000000000000000008152fd5b60ff60015460b01c166158df57565b60046040517f1309a563000000000000000000000000000000000000000000000000000000008152fd5b3d15615970573d9067ffffffffffffffff8211615963575b6040519161595760207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160184610766565b82523d6000602084013e565b61596b610688565b615921565b606090565b91909392823b15614d0c57600094859485926040519260208401957ff242432a00000000000000000000000000000000000000000000000000000000875273ffffffffffffffffffffffffffffffffffffffff80921660248601521660448401526064830152608482015260a060a48201528160c482015260c481526159fa81610749565b51925af1615a06615909565b5015615a0e57565b60046040517f02f8f11e000000000000000000000000000000000000000000000000000000008152fd5b9081602091031261000e5751613ced81610514565b90929192813b15614d0c576040517f23b872dd000000000000000000000000000000000000000000000000000000006020820190815273ffffffffffffffffffffffffffffffffffffffff9283166024830152949091166044820152606481019290925260009283928390615ac58160848101614c7e565b51925af1615ad1615909565b9015615afd57805180615ae2575050565b81602080610e1093615af79501019101615a38565b615afd57565b60046040517fe5605213000000000000000000000000000000000000000000000000000000008152fd5b90929192813b15614d0c576040517f23b872dd000000000000000000000000000000000000000000000000000000006020820190815273ffffffffffffffffffffffffffffffffffffffff9283166024830152949091166044820152606481019290925260009283928390615b9f8160848101614c7e565b51925af1615bab615909565b5015615bb357565b60046040517fe0f5c508000000000000000000000000000000000000000000000000000000008152fd5b615bf1828495600080809781948294f11590565b615bfb5750505050565b73ffffffffffffffffffffffffffffffffffffffff1691823b156109ae5791615cb693916020936040517fd0e30db0000000000000000000000000000000000000000000000000000000008152818160048188885af18015615d22575b615d09575b506040518096819582947fa9059cbb000000000000000000000000000000000000000000000000000000008452600484016020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b03925af18015615cfc575b615cce575b8080806157a3565b615cee9060203d8111615cf5575b615ce68183610766565b810190615a38565b5038615cc6565b503d615cdc565b615d04614de1565b615cc1565b80615d16615d1c92610735565b80610404565b38615c5d565b615d2a614de1565b615c58565b90808216911860011c8101809111615d445790565b613ced613e5f56fea2646970667358221220333d426aac2099c9c3169823ea4ce62867fd4773c40055754f9c9bbe95597e4464736f6c63430008110033000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef00000000000000000000000000000000000000000000000000000000000002de000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909000000000000000000000000b5a9e5a319c7fda551a30be592c77394bf935c6f0000000000000000000000001838de7d4e4e42c8eb7b204a91e28e9fad14f5360000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x60806040526004361015610013575b600080fd5b60003560e01c8063030932bb146103fb57806305f6a924146103f25780631e9f1a82146103e95780631fe543e3146103e057806323452b9c146103d75780632a6a4eb8146103ce5780632bb5a9e6146103c557806331fe74a9146103bc57806336566f06146103b357806339a2eb2a146103aa5780633b6cb153146103a15780633e5675391461039857806340e58ee51461038f578063436313b21461038657806349890e151461037d5780634d2c53cd1461037457806351dc86a51461036b578063534fff0e146103625780635708b502146103595780635a195d19146103505780635b6ac011146103475780635c975abb1461033e5780635cb6dfff146103355780635d4bc0ce1461032c57806364df049e1461032357806365d697f71461031a57806367f082b014610311578063689869121461030857806369ce6d47146102ff5780636b1426a4146102f65780636f30d7b5146102ed5780637200b829146102e45780637762df25146102db57806382d6848c146102d2578063863e76db146102c95780638da5cb5b146102c05780638e6f6b77146102b757806398753c46146102ae578063a17be154146102a5578063a72844ba1461029c578063ac68a74814610293578063ad5c46481461028a578063c0b6f56114610281578063cc30779514610278578063d3549ebd1461026f578063d49a563014610266578063e521cb921461025d578063f23a6e6114610254578063f42df1321461024b5763f54a6f831461024357600080fd5b61000e613a4c565b5061000e6133de565b5061000e613338565b5061000e613257565b5061000e612d0c565b5061000e612c55565b5061000e612b3c565b5061000e612969565b5061000e6128f9565b5061000e61261b565b5061000e612520565b5061000e61246a565b5061000e612426565b5061000e6123e9565b5061000e612396565b5061000e612359565b5061000e612162565b5061000e61210f565b5061000e611f9e565b5061000e611cf1565b5061000e611bc4565b5061000e611ac1565b5061000e611a86565b5061000e611a4b565b5061000e611a10565b5061000e6119bd565b5061000e6118f1565b5061000e6117d3565b5061000e61178e565b5061000e6116a3565b5061000e611634565b5061000e6115f8565b5061000e6114ba565b5061000e611460565b5061000e611423565b5061000e6113e7565b5061000e61137d565b5061000e6111c9565b5061000e6110bc565b5061000e611081565b5061000e610db4565b5061000e610c6d565b5061000e610ba5565b5061000e610af0565b5061000e6109bd565b5061000e610897565b5061000e6107ea565b5061000e61051e565b5061000e610473565b5061000e61040f565b600091031261000e57565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060405167ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000002de168152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909168152f35b9181601f8401121561000e5782359167ffffffffffffffff831161000e576020808501948460051b01011161000e57565b8015150361000e57565b503461000e576040807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760043567ffffffffffffffff811161000e5761056f9036906004016104e3565b91906024359261057e84610514565b610586615885565b60005b8181106106145750808351938085019085525260608301919060005b8181106105dc5785151560208601527fcb2fef16ee9f3ea43e174daf88ffcdc8beee4ad884c7570093d998d71058698785850386a1005b90919260019073ffffffffffffffffffffffffffffffffffffffff853561060281611354565b168152602090810194019291016105a5565b8073ffffffffffffffffffffffffffffffffffffffff6106376001938587614627565b3561064181611354565b16600052600560205261068286866000209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b01610589565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040810190811067ffffffffffffffff8211176106d457604052565b6106dc610688565b604052565b60a0810190811067ffffffffffffffff8211176106d457604052565b6080810190811067ffffffffffffffff8211176106d457604052565b60e0810190811067ffffffffffffffff8211176106d457604052565b67ffffffffffffffff81116106d457604052565b610100810190811067ffffffffffffffff8211176106d457604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176106d457604052565b604051906107b4826106fd565b565b604051906107b4826106b8565b60209067ffffffffffffffff81116107dd575b60051b0190565b6107e5610688565b6107d6565b503461000e5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760243567ffffffffffffffff811161000e573660238201121561000e57806004013590610846826107c3565b906108546040519283610766565b82825260209260248484019160051b8301019136831161000e57602401905b8282106108885761088684600435615719565b005b81358152908401908401610873565b503461000e576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126109ae576108d0615885565b60015460ff8160a01c1660038110156109a1575b801561097757806108f6600192610ade565b1461094c575b507fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff600154166001557f8eca980489e87f7dba4f26917aa4bfc906eb3f2b4f7b4b9fd0ff2b8bb3e21ae38180a180f35b7fffffffffffffffffffffffff000000000000000000000000000000000000000016600155386108fc565b60046040517fccf69db7000000000000000000000000000000000000000000000000000000008152fd5b6109a9610aae565b6108e4565b80fd5b61ffff81160361000e57565b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576004356109f9816109b1565b610a01615885565b61ffff8116906109c48211610a84577fede4aee4284b8033b84c1aadcc51b229a4e46e6b42ab40092e237f07508b4626916020917fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff75ffff00000000000000000000000000000000000000006007549260a01b16911617600755604051908152a1005b60046040517f4929acd7000000000000000000000000000000000000000000000000000000008152fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60031115610ae857565b6107b4610aae565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060ff60015460a01c16604051906003811015610b3c578152f35b610b44610aae565b8152f35b610140810192916000915b60058310610b6057505050565b600190604083519164ffffffffff835116815279ffffffffffffffffffffffffffffffffffffffffffffffffffff602080940151168382015201920192019190610b53565b503461000e576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576040908151610be4816106e1565b8160005b60a08110610c4c57505050600435600052600381526003826000200190825191610c11836106e1565b90600090835b60058310610c3057855180610c2c8782610b48565b0390f35b6001828192610c3e8761413a565b815201940192019192610c17565b8451610c57816106b8565b6000815260008382015281840152018290610be8565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57610ca5615885565b60015460ff8160b01c16600014610d41575060015460ff8160b01c1615610d17577fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff166001557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a1005b60046040517f6cd60201000000000000000000000000000000000000000000000000000000008152fd5b7fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff76010000000000000000000000000000000000000000000091610d836158d0565b16176001557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a1005b503461000e576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57610e03610dfe6004356000526006602052604060002090565b614272565b610e14610e108251151590565b1590565b611057576040908181015190610e47610e37836000526003602052604060002090565b92610e418461503b565b836151b2565b6008820193845493610e80610e76610e67610e61886142bd565b89613eb0565b505460281c64ffffffffff1690565b64ffffffffff1690565b610e8c600986016142ea565b90815194610eb4610e76610ea8610ea2896142bd565b8661438d565b515164ffffffffff1690565b90610ec9610ec48360081c6140e3565b6143af565b98610ed3886143af565b9760005b818110611029575050610ee9816143af565b9a60005b828110610ffa575050508501517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690600a60009801915b838910610f2d57005b8a99610f38836140e3565b610f42908361442e565b90610f4d91846155c7565b999088610f5a828c615677565b610f64908961438d565b51015173ffffffffffffffffffffffffffffffffffffffff16916001019b8c610f8c91615677565b60ff16610f976107a7565b73ffffffffffffffffffffffffffffffffffffffff90931683526000838b015260ff168883015264ffffffffff166060820152610fd49084614444565b8551878101918252808203808252610fef9060200182610766565b519020989798610f24565b808d61101d82979e9d9897611017610e76610e6760019789613eb0565b9261438d565b52019a9394999a610eed565b80611041610e76610ea8979e9d98976001948b61438d565b61104b828d61438d565b52019a9394999a610ed7565b60046040517f1b71a84c000000000000000000000000000000000000000000000000000000008152fd5b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576020604051606e8152f35b503461000e576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126109ae576110f5615885565b600260ff60015460a01c1660038110156111bc575b03611192577fffffffffffffffffffffffff000000000000000000000000000000000000000081541681556111627fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff60015416600155565b604051600081527f3edd90e7770f06fafde38004653b33870066c33bfc923ff6102acd601f85dfbc90602090a180f35b60046040517f045c5122000000000000000000000000000000000000000000000000000000008152fd5b6111c4610aae565b61110a565b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57600435600154600260ff8260a81c161461132a577fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff167502000000000000000000000000000000000000000000176001556112526158d0565b8060005260036020526040600020805491600260ff8460a01c1661127581611837565b149283156113175764ffffffffff429160b01c16116112ed576112a0925b156112e557600791615532565b61088675010000000000000000000000000000000000000000007fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff6001541617600155565b600891615532565b60046040517ff9ad93f5000000000000000000000000000000000000000000000000000000008152fd5b506112a09261132583615063565b611293565b60046040517f1bbee726000000000000000000000000000000000000000000000000000000008152fd5b73ffffffffffffffffffffffffffffffffffffffff81160361000e57565b35906107b482611354565b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5773ffffffffffffffffffffffffffffffffffffffff6004356113ce81611354565b1660005260086020526020604060002054604051908152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760206040516109c48152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576020600254604051908152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760206040517f8af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef8152f35b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576004356001908154600260ff8260a81c161461132a577fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675020000000000000000000000000000000000000000001782556115446158d0565b80600052600360205261156560406000209161155f8361507d565b82615222565b6008810173ffffffffffffffffffffffffffffffffffffffff815492541660005b8381106115d25761088675010000000000000000000000000000000000000000007fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff6001541617600155565b806115f26115e1879386613eb0565b508464ffffffffff82541691614b5c565b01611586565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760206040516127108152f35b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5773ffffffffffffffffffffffffffffffffffffffff60043561168581611354565b166000526005602052602060ff604060002054166040519015158152f35b503461000e576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126109ae576116dc615885565b60015460ff8160a01c166003811015611781575b611757577fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674020000000000000000000000000000000000000000176001557f3ff05a45e46337fa1cbf20996d2eeb927280bce099f37252bcca1040609604ec8180a180f35b60046040517f74ed79ae000000000000000000000000000000000000000000000000000000008152fd5b611789610aae565b6116f0565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060ff60015460b01c166040519015158152f35b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57600435600052600660205260606040600020600181549101546040519160ff81161515835260081c60208301526040820152f35b60091115610ae857565b90600982101561184e5752565b611856610aae565b52565b9896929a99979493919a9590956101408a019b73ffffffffffffffffffffffffffffffffffffffff8098168b5260208b0161189391611841565b151560408a015264ffffffffff80948180941660608c01521660808a01521660a08801521660c08601521660e084015261ffff1661010083015279ffffffffffffffffffffffffffffffffffffffffffffffffffff16906101200152565b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57600435600052600360205260406000208054610c2c6119626002600185015494015479ffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b60405193849373ffffffffffffffffffffffffffffffffffffffff9164ffffffffff928160f01c93818360501c169381808560281c169416928160d81c928260b01c169160ff8160a81c169160ff8260a01c1691168b611859565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602073ffffffffffffffffffffffffffffffffffffffff60075416604051908152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060405160148152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060405160038152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060405160058152f35b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57600435611afd81611354565b611b05615885565b611b4073ffffffffffffffffffffffffffffffffffffffff600092818116845260086020526040842054918460408120556007541690614bcb565b80f35b60208082019080835283518092528060408094019401926000905b838210611b6d57505050505090565b8451805173ffffffffffffffffffffffffffffffffffffffff168752808401511515878501528082015160ff168783015260609081015164ffffffffff169087015260809095019493820193600190910190611b5e565b503461000e576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760043560005260038152604090600a8260002001805490611c15826107c3565b92611c2285519485610766565b82845260009182528082208185015b848410611c4557865180610c2c8882611b43565b60018381928951611c55816106fd565b64ffffffffff865473ffffffffffffffffffffffffffffffffffffffff8116835260ff808260a01c161515868501528160a81c168d84015260b01c166060820152815201920193019290611c31565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc82011261000e576004359067ffffffffffffffff821161000e57611ced916004016104e3565b9091565b503461000e57611d0036611ca4565b60019182549060ff916002838260a81c161461132a577fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff167502000000000000000000000000000000000000000000178455611d5a6158d0565b60005b838110611da95761088675010000000000000000000000000000000000000000007fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff6001541617600155565b60059080821b830135917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18436030183121561000e5786928401803590611dfa826000526003602052604060002090565b92611e0a845460ff9060a01c1690565b611e1381611837565b03611f90575b91611e2c600a8201936020810190614d36565b919093805490600860009301905b848410611e81575050505090611e787f0d0ab4a45afc0276ae825be9eeb4552011b19aad5c92b4bb782f3ca0356fedc5939260405193849384614d8a565b0390a101611d5d565b9091929750611e91888588614627565b3583811015611f6657611ea490826141a7565b508054988b8a60a01c16611f3c57611f33611f2b8f9b8c94611ede73ffffffffffffffffffffffffffffffffffffffff611f2593166150ff565b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001781555460a81c60ff1690565b86613eb0565b503390614ada565b01929190611e3a565b60046040517fc2356312000000000000000000000000000000000000000000000000000000008152fd5b60046040517f63df8171000000000000000000000000000000000000000000000000000000008152fd5b611f9983615097565b611e19565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57600154600160ff8260a01c16611fe381610ade565b036120e55773ffffffffffffffffffffffffffffffffffffffff1633036120bb57600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317905561205b7fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff60015416600155565b6120887fffffffffffffffffffffffff000000000000000000000000000000000000000060015416600155565b6040513381527f3edd90e7770f06fafde38004653b33870066c33bfc923ff6102acd601f85dfbc9080602081015b0390a1005b60046040517fafdcfb92000000000000000000000000000000000000000000000000000000008152fd5b60046040517f5e4f2826000000000000000000000000000000000000000000000000000000008152fd5b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602073ffffffffffffffffffffffffffffffffffffffff60015416604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760043560019081549160029060ff9382858260a81c161461132a577fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675020000000000000000000000000000000000000000001781556121ec6158d0565b612200836000526003602052604060002090565b9361220a85615063565b61223061222b865473ffffffffffffffffffffffffffffffffffffffff1690565b6150ff565b6008850192835491600094855b848110612257576112a0888a6122528a615147565b615292565b80612263879284613eb0565b508054858160501c1661227581612a79565b8061229f575050808361228c612299935460601c90565b9101549030903390615b27565b0161223d565b90919293506122ad81612a79565b600381036122e6575050906122e1826122d4878a955492015464ffffffffff8316906140d0565b903090339060601c615a4d565b612299565b806122f488929b959b612a79565b0361232b5750869161231f82612319610e7689612325960154925464ffffffffff1690565b906140d0565b906140f1565b96612299565b6122e1908261234c888b80979d96015492015464ffffffffff8416906140d0565b913090339060601c615975565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576020604051620151808152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602073ffffffffffffffffffffffffffffffffffffffff60005416604051908152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060405162093a808152f35b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602061ffff60075460a01c16604051908152f35b503461000e5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760606124e06024356124ab81611354565b600435600052600460205260406000209073ffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b546040519079ffffffffffffffffffffffffffffffffffffffffffffffffffff8116825264ffffffffff8160d01c16602083015260f81c15156040820152f35b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760043561255b615885565b600154600260ff8260a81c161461132a577fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff75020000000000000000000000000000000000000000009116176001558060005260036020526040600020906125c2826150b1565b815460d81c62015180810180911161260e575b42106125e4576112a091615302565b60046040517ff4c0ca6e000000000000000000000000000000000000000000000000000000008152fd5b612616613e5f565b6125d5565b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760043560015490600260ff8360a81c161461132a5775020000000000000000000000000000000000000000007fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff7fa1f87f32d0f17fab0242ca800d736293de8988c14b27747e218cf13d5c249f539316176001556126c76158d0565b806126dc816000526003602052604060002090565b6126e5816150cb565b6127cd612706825473ffffffffffffffffffffffffffffffffffffffff1690565b9173ffffffffffffffffffffffffffffffffffffffff831633036128d2575b6128196002820191612812612754845479ffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b936127f560018401916127a261277e612778612771865460f01c90565b61ffff1690565b896145b8565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff61271091160490565b97889779ffffffffffffffffffffffffffffffffffffffffffffffffffff998a9103169b8c96615372565b7fffffffffffff00000000000000000000000000000000000000000000000000008154169055565b5460501c73ffffffffffffffffffffffffffffffffffffffff1690565b9485614bcb565b169081612894575b50506040805191825279ffffffffffffffffffffffffffffffffffffffffffffffffffff929092166020820152a161088675010000000000000000000000000000000000000000007fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff6001541617600155565b6128c16128c99173ffffffffffffffffffffffffffffffffffffffff166000526008602052604060002090565b9182546140f1565b90553880612821565b6128f461222b60005473ffffffffffffffffffffffffffffffffffffffff1690565b612725565b503461000e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57602060405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2168152f35b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576004356129a581611354565b6129ad615885565b60015460ff8160a01c166003811015612a6c575b611757577fffffffffffffffffffffff0000000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff82161774010000000000000000000000000000000000000000176001557fb86c75c9bffca616b2d314cc914f7c3f1d174255b16b941c3f3ededee276d5ef906120b6906040805133815273ffffffffffffffffffffffffffffffffffffffff909216602083015290918291820190565b612a74610aae565b6129c1565b60041115610ae857565b60208082019080835283518092528060408094019401926000905b838210612aad57505050505090565b90919293948360e0600192885164ffffffffff808251168352848201511684830152858101516004811015612b2f575b8287015260608181015160ff169083015260808082015173ffffffffffffffffffffffffffffffffffffffff169083015260a0818101519083015260c090810151908201520196019493920190612a9e565b612b37610aae565b612add565b503461000e576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e576004356000526003908181526040916008836000200190815491612b90836107c3565b93612b9d86519586610766565b83855260009182528082208186015b858410612bc057875180610c2c8982612a83565b84836001928a51612bd081610719565b612c34865464ffffffffff80821684528160281c16858401528d612bfe60ff91828460501c1690860161463f565b612c146060918360581c168286019060ff169052565b1c608083019073ffffffffffffffffffffffffffffffffffffffff169052565b8486015460a0820152600286015460c0820152815201920193019290612bac565b503461000e576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760043560005260038152604090612ca2600983600020016142ea565b8251928284938401908085528351809252808386019401926000905b838210612ccb5786860387f35b8451805164ffffffffff16875283015173ffffffffffffffffffffffffffffffffffffffff1686840152879650948501949382019360019190910190612cbe565b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc90808236011261000e57600480359167ffffffffffffffff831161000e5761022083830194843603011261000e57612d6c84613ce3565b64ffffffffff938482168062015180420111908115613248575b5061321f57612d9760848201613cf0565b91612dac61277160075461ffff9060a01c1690565b61ffff8416036131f657612dc260a48301613cfa565b9473ffffffffffffffffffffffffffffffffffffffff8616613192575b60025460010196612def88600255565b60c4840195612dfe878b613d04565b809150158015613188575b61315f5790612e228a6000526003602052604060002090565b9a8b916000998a9260088c9501945b8681106130bd575050505050505080612e4c60448601613ce3565b961690861681119081156130b2575b5061308a5750938593613026610c2c9894612fd7612f9c606487612f5c61307a9c612e8d8d60e46130759d019061477f565b8b547fffffffffffffffffffffffff00000000000000000000000000000000000000001633178c55612f10612ec4602485016140b5565b8d805490917fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff90911690151560a81b75ff00000000000000000000000000000000000000000016179055565b8b547fffffffffff0000000000ffffffffffffffffffffffffffffffffffffffffffff1660b09190911b7affffffffff0000000000000000000000000000000000000000000016178b55565b612f9660018b0197889064ffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000825416179055565b01613ce3565b84547fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff1660289190911b69ffffffffff000000000016178455565b82547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f09190911b7fffff00000000000000000000000000000000000000000000000000000000000016178255565b907fffff0000000000000000000000000000000000000000ffffffffffffffffffff7dffffffffffffffffffffffffffffffffffffffff0000000000000000000083549260501b169116179055565b6153e2565b6040519081529081906020820190565b6040517f804a1e02000000000000000000000000000000000000000000000000000000008152fd5b606e91501138612e5b565b6130eb9c6130dd6130d8836130d28787613d04565b90613d88565b613dc0565b95606087019e8f5160ff1690565b60ff91821691161061313657613100866149a7565b855164ffffffffff1661311291613e8f565b64ffffffffff8116868601529c5160ff169461312e9087613f0a565b600101612e31565b896040517f5f12e2ee000000000000000000000000000000000000000000000000000000008152fd5b836040517fab13062d000000000000000000000000000000000000000000000000000000008152fd5b5060148111612e09565b6131c9610e106131c28873ffffffffffffffffffffffffffffffffffffffff166000526005602052604060002090565b5460ff1690565b15612ddf576040517ff5993428000000000000000000000000000000000000000000000000000000008152fd5b846040517f4929acd7000000000000000000000000000000000000000000000000000000008152fd5b836040517fce8f4bfd000000000000000000000000000000000000000000000000000000008152fd5b905062093a8042011038612d86565b503461000e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5773ffffffffffffffffffffffffffffffffffffffff6004356132a881611354565b6132b0615885565b16801561330e576020817fc1b5345cce283376356748dc57f2dfa7120431d016fc7ca9ba641bc65f91411d927fffffffffffffffffffffffff00000000000000000000000000000000000000006007541617600755604051908152a1005b60046040517f3106a0c7000000000000000000000000000000000000000000000000000000008152fd5b503461000e5760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57613373600435611354565b61337e602435611354565b60843567ffffffffffffffff80821161000e573660238301121561000e57816004013590811161000e573691016024011161000e576040517ff23a6e61000000000000000000000000000000000000000000000000000000008152602090f35b506020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57600490813567ffffffffffffffff9283821161000e573660238301121561000e578181013593841161000e576024820191602436918660061b01011161000e5760019283546002908160ff8260a81c1614613a23577fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675020000000000000000000000000000000000000000001785556134a36158d0565b600095865b8181106134d4576112a079ffffffffffffffffffffffffffffffffffffffffffffffffffff8916615147565b6134df8183886140fe565b848101359060058210156139fa573590613503826000526003602052604060002090565b9061350d826150e5565b81546135229060b01c64ffffffffff16610e76565b4210156139d15761353961353f916003840161411c565b5061413a565b6135a06135906135823361355d876000526004602052604060002090565b9073ffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b5460d01c64ffffffffff1690565b825164ffffffffff165b90613e8f565b828b0180546135b89060281c64ffffffffff16610e76565b9164ffffffffff92838216116139a857613634906135e43361355d896000526004602052604060002090565b907fff0000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff7effffffffff000000000000000000000000000000000000000000000000000083549260d01b169116179055565b8289015179ffffffffffffffffffffffffffffffffffffffffffffffffffff169c613677825473ffffffffffffffffffffffffffffffffffffffff9060501c1690565b73ffffffffffffffffffffffffffffffffffffffff811661396f5750906136a48e8e989796959493614179565b9d5b60098501938a8554801560001461391d57506136f97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6136ee610e76855164ffffffffff1690565b0164ffffffffff1690565b955b87548e9060a81c60ff166138bc575b9361384c610e76946137fd7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff98956137898c7fc25cd4cec0cbfb9bc40ad8f59ac733efcddf6ed3b7519369c9b9ceb2ee7846019761378461389a9c61377d6137706107b6565b64ffffffffff9095168552565b3390840152565b6141cd565b8c016137b8856137b3835479ffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b614179565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffffffff0000000000000000000000000000000000000000000000000000825416179055565b6138416138198d61355d33916000526004602052604060002090565b6137b8856137b3835479ffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b5164ffffffffff1690565b604080518c815233602082015264ffffffffff929092169082015279ffffffffffffffffffffffffffffffffffffffffffffffffffff919091166060820152608090a15464ffffffffff1690565b01911610156138ac575b5050016134a8565b6138b591614dee565b38806138a4565b5091929394959697989950506138da610e76855464ffffffffff1690565b85871610156138f457908a8f99989796959493928d61370a565b8c6040517f34b3fb3b000000000000000000000000000000000000000000000000000000008152fd5b61395b61394f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6139699301896141a7565b505464ffffffffff1690565b835164ffffffffff1661359a565b956136fb565b9d6139a38e989796959493929f79ffffffffffffffffffffffffffffffffffffffffffffffffffff83169030903390615a4d565b6136a6565b8a6040517fd085f161000000000000000000000000000000000000000000000000000000008152fd5b876040517fb68c78dc000000000000000000000000000000000000000000000000000000008152fd5b866040517f63df8171000000000000000000000000000000000000000000000000000000008152fd5b836040517f1bbee726000000000000000000000000000000000000000000000000000000008152fd5b503461000e57613a5b36611ca4565b906001918254600260ff8260a81c161461132a577fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff167502000000000000000000000000000000000000000000178355613ab36158d0565b60005b818110613b025761088675010000000000000000000000000000000000000000007fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff6001541617600155565b613b0d818385614627565b3590613b23826000526003602052604060002090565b805460079060a01c60ff16613b3781611837565b10613caa57613b543361355d856000526004602052604060002090565b90613b60825460f81c90565b613c80578693613c43613c1e86613bff86613bdf7fc0b7cf12926534c2d86d0abb17d620a3a06e07a84b3b8156a4b21189222b16d2987f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff825416179055565b5479ffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b94015460501c73ffffffffffffffffffffffffffffffffffffffff1690565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff8416903390614bcb565b6040805191825233602083015279ffffffffffffffffffffffffffffffffffffffffffffffffffff9290921691810191909152606090a101613ab6565b60046040517fa85e6f1a000000000000000000000000000000000000000000000000000000008152fd5b60046040517ff525e320000000000000000000000000000000000000000000000000000000008152fd5b64ffffffffff81160361000e57565b35613ced81613cd4565b90565b35613ced816109b1565b35613ced81611354565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561000e570180359067ffffffffffffffff821161000e576020019160e082023603831361000e57565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9160e091811015613d9857020190565b613da0613d58565b020190565b3590600482101561000e57565b359060ff8216820361000e57565b60e08136031261000e5760c06040519160e0830183811067ffffffffffffffff821117613e52575b6040528035613df681613cd4565b83526020810135613e0681613cd4565b6020840152613e1760408201613da5565b6040840152613e2860608201613db2565b6060840152613e3960808201611372565b608084015260a081013560a0840152013560c082015290565b613e5a610688565b613de8565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b91909164ffffffffff80809416911601918211613ea857565b6107b4613e5f565b8054821015613ecd575b6000526003602060002091020190600090565b613ed5613d58565b613eba565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b60c0613f32600292805490680100000000000000008210156140a8575b600182018155613eb0565b93909361409b575b80518454602083015164ffffffffff9092167fffffffffffffffffffffffffffffffffffffffffffff000000000000000000009091161760289190911b69ffffffffff0000000000161784556040810151600481101561408e575b7fffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff6aff0000000000000000000086549260501b16911617845561401c613fdf606083015160ff1690565b85547fffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffff1660589190911b6bff000000000000000000000016178555565b61407d614040608083015173ffffffffffffffffffffffffffffffffffffffff1690565b85546bffffffffffffffffffffffff1660609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016178555565b60a081015160018501550151910155565b614096610aae565b613f95565b6140a3613eda565b613f3a565b6140b0610688565b613f27565b35613ced81610514565b9081156001838004141715613ea857565b81810292918115918404141715613ea857565b9060018201809211613ea857565b91908201809211613ea857565b919081101561410f575b60061b0190565b614117613d58565b614108565b600582101561412d575b0190600090565b614135613d58565b614126565b90604051614147816106b8565b915464ffffffffff8116835260281c79ffffffffffffffffffffffffffffffffffffffffffffffffffff166020830152565b91909179ffffffffffffffffffffffffffffffffffffffffffffffffffff80809416911601918211613ea857565b80548210156141c0575b60005260206000200190600090565b6141c8613d58565b6141b1565b6141f360209180549068010000000000000000821015614265575b6001820181556141a7565b929092614258575b8051835492909101517fffffffffffffff0000000000000000000000000000000000000000000000000090921664ffffffffff9091161760289190911b78ffffffffffffffffffffffffffffffffffffffff000000000016179055565b614260613eda565b6141fb565b61426d610688565b6141e8565b906040516060810181811067ffffffffffffffff8211176142b0575b604052604060018294805460ff81161515855260081c60208501520154910152565b6142b8610688565b61428e565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201918211613ea857565b9081546142f6816107c3565b9260409361430685519182610766565b828152809460208092019260005281600020906000935b85851061432c57505050505050565b6001848192845161433c816106b8565b73ffffffffffffffffffffffffffffffffffffffff875464ffffffffff8116835260281c168382015281520193019401939161431d565b602090805115614381570190565b614389613d58565b0190565b60209181518110156143a2575b60051b010190565b6143aa613d58565b61439a565b906143b9826107c3565b6143c66040519182610766565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06143f482946107c3565b0190602036910137565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8115614438570690565b6144406143fe565b0690565b9064ffffffffff60606144736107b49480549068010000000000000000821015614265576001820181556141a7565b9390936145ab575b805184547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9190911617845561455d61450f6020830151151586549074ff00000000000000000000000000000000000000007fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9160a01b1691161790565b80865560ff60408401511675ff0000000000000000000000000000000000000000007fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff9160a81b1691161790565b9101517fffffffffff0000000000ffffffffffffffffffffffffffffffffffffffffffff909116911660b01b7affffffffff0000000000000000000000000000000000000000000016179055565b6145b3613eda565b61447b565b919079ffffffffffffffffffffffffffffffffffffffffffffffffffff8080941691169283820216928184041490151715613ea857565b9079ffffffffffffffffffffffffffffffffffffffffffffffffffff80911691821561461a57160490565b6146226143fe565b160490565b91908110156146375760051b0190565b6107e5613d58565b600482101561184e5752565b90600581101561410f5760061b0190565b60408136031261000e576020604051916040830183811067ffffffffffffffff8211176146c1575b604052803561469281613cd4565b8352013579ffffffffffffffffffffffffffffffffffffffffffffffffffff8116810361000e57602082015290565b6146c9610688565b614684565b9079ffffffffffffffffffffffffffffffffffffffffffffffffffff8091169182156146f957160690565b6147016143fe565b160690565b91602091614772575b8051835492909101517fff0000000000000000000000000000000000000000000000000000000000000090921664ffffffffff9091161760289190911b7effffffffffffffffffffffffffffffffffffffffffffffffffff000000000016179055565b61477a613eda565b61470f565b60005b6005811061478f57505050565b6147a161479c828561464b565b61465c565b906147b1825164ffffffffff1690565b6020906147da8285015179ffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b918361487b575064ffffffffff1660011480159190614856575b5061482c576148266001925b61482083600361481a886000526003602052604060002090565b0161411c565b90614706565b01614782565b60046040517f0b9752e0000000000000000000000000000000000000000000000000000000008152fd5b79ffffffffffffffffffffffffffffffffffffffffffffffffffff91501615386147f4565b91906148e16148d56148b261479c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff88018b61464b565b9485015179ffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b935164ffffffffff1690565b9064ffffffffff8091169379ffffffffffffffffffffffffffffffffffffffffffffffffffff918261491387876146ce565b16159485159561499a575b851561498b575b8515614942575b5050505050905061482c57614826600192614800565b61495e93955061497d9496614956916145ef565b9516906145ef565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b91161180388080808061492c565b82841684821611159550614925565b848216871115955061491e565b6040810180516149b681612a79565b6149bf81612a79565b614a1a5750600160c08201511490811591614a06575b506149dc57565b60046040517f5f12e2ee000000000000000000000000000000000000000000000000000000008152fd5b5164ffffffffff16600114159050386149d5565b60039051614a2781612a79565b614a3081612a79565b14614a5b575b60c081015115908115614a4a57506149dc57565b5164ffffffffff16159050386149d5565b614aab610e106131c2614a85608085015173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff166000526005602052604060002090565b15614a365760046040517ff5993428000000000000000000000000000000000000000000000000000000008152fd5b9081549060ff8260501c169160601c91614af381612a79565b80614b09575060016107b4930154913090615b27565b80614b15600192612a79565b03614b3957916107b492614b31600260018401549301546140bf565b923090615975565b60026107b493015491828004600114831517614bcb57614b57613e5f565b614bcb565b80549192606083901c9260501c60ff16614b7581612a79565b80614b8d5750509160016107b4930154913090615b27565b80614b9c600192969396612a79565b03614bb757614b316107b494600260018501549401546140d0565b906107b4936002614bc99201546140d0565b915b90919073ffffffffffffffffffffffffffffffffffffffff8116614c175750906107b4915a917f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2615bdd565b803b15614d0c576040517fa9059cbb000000000000000000000000000000000000000000000000000000006020820190815273ffffffffffffffffffffffffffffffffffffffff9094166024820152604481019290925260009283928390614caa81606481015b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282610766565b51925af1614cb6615909565b9015614ce257805180614cc7575050565b81602080610e1093614cdc9501019101615a38565b614ce257565b60046040517ff1568f95000000000000000000000000000000000000000000000000000000008152fd5b60046040517f09ee12d5000000000000000000000000000000000000000000000000000000008152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561000e570180359067ffffffffffffffff821161000e57602001918160051b3603831361000e57565b908152604060208201528260408201527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831161000e5760609260051b809284830137010190565b9081602091031261000e575190565b506040513d6000823e3d90fd5b90614e4790614dfd8382615452565b80547affffffffffffffffffffffffffffffffffffffffffffffffffffff164260d81b7fffffffffff00000000000000000000000000000000000000000000000000000016179055565b6040517f5d3b1d300000000000000000000000000000000000000000000000000000000081527f8af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef60048201527f00000000000000000000000000000000000000000000000000000000000002de67ffffffffffffffff166024820152600360448201526207a12060648201526001608482015260208160a48160007f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e6990973ffffffffffffffffffffffffffffffffffffffff165af190811561502e575b600091615000575b50614f436131c2826000526006602052604060002090565b614fd6577f3d94fecedaa4f90b8bd459797adb95f5bb11426025c5541390d9ccc1ad1b60a191614fab614f80836000526006602052604060002090565b60017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00825416179055565b806001614fc2846000526006602052604060002090565b0155604080519182526020820192909252a1565b60046040517ff9012132000000000000000000000000000000000000000000000000000000008152fd5b615021915060203d8111615027575b6150198183610766565b810190614dd2565b38614f2b565b503d61500f565b615036614de1565b614f23565b60ff6004915460a01c166009811015615056575b03613caa57565b61505e610aae565b61504f565b60ff6001915460a01c1660098110156150565703613caa57565b60ff6007915460a01c1660098110156150565703613caa57565b60ff6006915460a01c1660098110156150565703613caa57565b60ff6003915460a01c1660098110156150565703613caa57565b60ff6005915460a01c1660098110156150565703613caa57565b60ff6002915460a01c1660098110156150565703613caa57565b73ffffffffffffffffffffffffffffffffffffffff16330361511d57565b60046040517f48f5c3ed000000000000000000000000000000000000000000000000000000008152fd5b348111156151795760046040517f8ffff980000000000000000000000000000000000000000000000000000000008152fd5b8034116151835750565b6107b4905a903403337f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2615bdd565b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167405000000000000000000000000000000000000000017905560408051918252600560208301527fc1191e7178b58ad510709587719f39ec315fa79e81ee7ba5c5ef3c894e94a65191a1565b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167408000000000000000000000000000000000000000017905560408051918252600860208301527fc1191e7178b58ad510709587719f39ec315fa79e81ee7ba5c5ef3c894e94a65191a1565b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167402000000000000000000000000000000000000000017905560408051918252600260208301527fc1191e7178b58ad510709587719f39ec315fa79e81ee7ba5c5ef3c894e94a65191a1565b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167407000000000000000000000000000000000000000017905560408051918252600760208301527fc1191e7178b58ad510709587719f39ec315fa79e81ee7ba5c5ef3c894e94a65191a1565b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167406000000000000000000000000000000000000000017905560408051918252600660208301527fc1191e7178b58ad510709587719f39ec315fa79e81ee7ba5c5ef3c894e94a65191a1565b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000017905560408051918252600160208301527fc1191e7178b58ad510709587719f39ec315fa79e81ee7ba5c5ef3c894e94a65191a1565b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167403000000000000000000000000000000000000000017905560408051918252600360208301527fc1191e7178b58ad510709587719f39ec315fa79e81ee7ba5c5ef3c894e94a65191a1565b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167404000000000000000000000000000000000000000017905560408051918252600460208301527fc1191e7178b58ad510709587719f39ec315fa79e81ee7ba5c5ef3c894e94a65191a1565b906155b77fc1191e7178b58ad510709587719f39ec315fa79e81ee7ba5c5ef3c894e94a6519360409360098210156155ba575b80547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1660a083901b74ff00000000000000000000000000000000000000001617905583519283526020830190611841565ba1565b6155c2610aae565b615565565b909291928060081c600160ff81808286161b925b615601575b5050819293506155f36155fc928761438d565b5117918561438d565b529190565b9290939180615610838a61438d565b51161561566d57508185036156375750508060009283945b94939284821683901b926155db565b91909392818501809511615660575b80851615615657575b819293615628565b9181019161564f565b615668613e5f565b615646565b91938193506155e0565b8051918215615711576000925b8084106156e0575082151591826156c2575b505015613ced577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b6156d79192506156d1846142bd565b9061438d565b51143880615696565b6156ea8185615d2f565b9081836156f7828761438d565b511115615705575050615684565b60010194509050615684565b505050600090565b7f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e6990973ffffffffffffffffffffffffffffffffffffffff81163303615836575080600052600660205260ff60406000205416615772575050565b600160406000200154918260005260036020526040600020600360ff825460a01c1661579d81611837565b146157a9575b50505050565b6157c56157fb926157c061582d966157ea946154c2565b614373565b517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b916000526006602052604060002090565b9060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083549260081b169116179055565b388080806157a3565b6040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff919091166024820152604490fd5b73ffffffffffffffffffffffffffffffffffffffff6000541633036158a657565b60046040517f30cd7471000000000000000000000000000000000000000000000000000000008152fd5b60ff60015460b01c166158df57565b60046040517f1309a563000000000000000000000000000000000000000000000000000000008152fd5b3d15615970573d9067ffffffffffffffff8211615963575b6040519161595760207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160184610766565b82523d6000602084013e565b61596b610688565b615921565b606090565b91909392823b15614d0c57600094859485926040519260208401957ff242432a00000000000000000000000000000000000000000000000000000000875273ffffffffffffffffffffffffffffffffffffffff80921660248601521660448401526064830152608482015260a060a48201528160c482015260c481526159fa81610749565b51925af1615a06615909565b5015615a0e57565b60046040517f02f8f11e000000000000000000000000000000000000000000000000000000008152fd5b9081602091031261000e5751613ced81610514565b90929192813b15614d0c576040517f23b872dd000000000000000000000000000000000000000000000000000000006020820190815273ffffffffffffffffffffffffffffffffffffffff9283166024830152949091166044820152606481019290925260009283928390615ac58160848101614c7e565b51925af1615ad1615909565b9015615afd57805180615ae2575050565b81602080610e1093615af79501019101615a38565b615afd57565b60046040517fe5605213000000000000000000000000000000000000000000000000000000008152fd5b90929192813b15614d0c576040517f23b872dd000000000000000000000000000000000000000000000000000000006020820190815273ffffffffffffffffffffffffffffffffffffffff9283166024830152949091166044820152606481019290925260009283928390615b9f8160848101614c7e565b51925af1615bab615909565b5015615bb357565b60046040517fe0f5c508000000000000000000000000000000000000000000000000000000008152fd5b615bf1828495600080809781948294f11590565b615bfb5750505050565b73ffffffffffffffffffffffffffffffffffffffff1691823b156109ae5791615cb693916020936040517fd0e30db0000000000000000000000000000000000000000000000000000000008152818160048188885af18015615d22575b615d09575b506040518096819582947fa9059cbb000000000000000000000000000000000000000000000000000000008452600484016020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b03925af18015615cfc575b615cce575b8080806157a3565b615cee9060203d8111615cf5575b615ce68183610766565b810190615a38565b5038615cc6565b503d615cdc565b615d04614de1565b615cc1565b80615d16615d1c92610735565b80610404565b38615c5d565b615d2a614de1565b615c58565b90808216911860011c8101809111615d445790565b613ced613e5f56fea2646970667358221220333d426aac2099c9c3169823ea4ce62867fd4773c40055754f9c9bbe95597e4464736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef00000000000000000000000000000000000000000000000000000000000002de000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909000000000000000000000000b5a9e5a319c7fda551a30be592c77394bf935c6f0000000000000000000000001838de7d4e4e42c8eb7b204a91e28e9fad14f5360000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _weth (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [1] : _keyHash (bytes32): 0x8af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef
Arg [2] : _subscriptionId (uint64): 734
Arg [3] : _vrfCoordinator (address): 0x271682DEB8C4E0901D1a1550aD2e64D568E69909
Arg [4] : _owner (address): 0xB5a9e5a319c7fDa551a30BE592c77394bF935c6f
Arg [5] : _protocolFeeRecipient (address): 0x1838De7d4e4e42c8eB7b204A91e28E9fad14F536
Arg [6] : _protocolFeeBp (uint16): 0
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [1] : 8af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef
Arg [2] : 00000000000000000000000000000000000000000000000000000000000002de
Arg [3] : 000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909
Arg [4] : 000000000000000000000000b5a9e5a319c7fda551a30be592c77394bf935c6f
Arg [5] : 0000000000000000000000001838de7d4e4e42c8eb7b204a91e28e9fad14f536
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
7852:29143:0:-:0;;;;;;;;;-1:-1:-1;7852:29143:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;9779:39;7852:29143;;;;;;;;;;;;;;;;;;;;9887:58;7852:29143;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;926:61:6;;:::i;:::-;-1:-1:-1;27525:9:0;;;;;;7852:29143;;;;;;;;;;;;;;;;;-1:-1:-1;7852:29143:0;;;;;;;;;;;;;27680:46;;;;7852:29143;27680:46;7852:29143;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;27514:9;27570:13;7852:29143;27570:13;7852:29143;27570:13;;;;:::i;:::-;7852:29143;;;;:::i;:::-;;-1:-1:-1;7852:29143:0;27552:17;7852:29143;;27552:44;7852:29143;;-1:-1:-1;7852:29143:0;;;;;;;;;;;;;;;27552:44;7852:29143;27514:9;;7852:29143;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;:::i;:::-;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;:::o;:::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;926:61:6;;:::i;:::-;1497:15;7852:29143:0;;;;;;;;;;;;;1526:44:6;;1522:111;;7852:29143:0;;1497:15:6;7852:29143:0;;:::i;:::-;1647:45:6;1643:97;;7852:29143:0;;;1497:15:6;7852:29143:0;;1497:15:6;7852:29143:0;1788:25:6;;;;7852:29143:0;;1643:97:6;7852:29143:0;;1497:15:6;7852:29143:0;1643:97:6;;;1522:111;7852:29143:0;;;1593:29:6;;;;7852:29143:0;;;:::i;:::-;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;:::i;:::-;926:61:6;;:::i;:::-;7852:29143:0;;;29272:40;10275:5;29272:40;;29268:100;;29422:36;7852:29143;;;;;29377:30;7852:29143;;;;;;;;29377:30;7852:29143;;;;;;29422:36;7852:29143;29268:100;7852:29143;;;29335:22;;;;7852:29143;;;;;;;;;;;;;-1:-1:-1;7852:29143:0;;;:::o;:::-;;;:::i;:::-;;;;;;;;;;;;;;790:29:6;7852:29143:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;-1:-1:-1;7852:29143:0;;;;;;;;;;;-1:-1:-1;7852:29143:0;28666:7;7852:29143;;28666:7;7852:29143;-1:-1:-1;7852:29143:0;28666:32;7852:29143;;;;;;;:::i;:::-;;-1:-1:-1;;7852:29143:0;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;7852:29143:0;;-1:-1:-1;7852:29143:0;;;;;;;;;;;;;;;;;;;;;;;;;926:61:6;;:::i;:::-;1237:7:8;7852:29143:0;;;;;;27835:32;7852:29143;;;;1237:7:8;7852:29143:0;;;;;;1576:9:8;1572:58;;7852:29143:0;;1237:7:8;7852:29143:0;2104:20:8;7852:29143:0;;;2113:10:8;7852:29143:0;;2104:20:8;7852:29143:0;1572:58:8;7852:29143:0;;;1608:11:8;;;;27835:32:0;7852:29143;;756:72:8;;;:::i;:::-;7852:29143:0;;1237:7:8;7852:29143:0;1859:18:8;7852:29143:0;;;1866:10:8;7852:29143:0;;1859:18:8;7852:29143:0;;;;;;;;;;;;;;;20153:29;7852:29143;;;;20153:18;7852:29143;;;;;;;20153:29;7852:29143;:::i;:::-;20196:25;7852:29143;;;;;;;;20196:25;;7852:29143;20196:25;20192:94;;20315:26;;;;;7852:29143;20375:17;20511:18;20375:17;;7852:29143;;20375:7;7852:29143;;;;;;;20375:17;20432:32;;;;:::i;:::-;20511:18;;:::i;:::-;20566:13;;;7852:29143;;;20664:15;20634:69;7852:29143;20657:23;20664:15;;;:::i;:::-;20657:23;;:::i;:::-;-1:-1:-1;7852:29143:0;;;;;;;;;;;;20634:69;7852:29143;20739:14;;;7852:29143;:::i;:::-;;;;20854:16;20838:52;20846:43;:25;20854:16;;;:::i;:::-;20846:25;;:::i;:::-;;7852:29143;;;;;20838:52;7852:29143;20941:43;20955:28;7852:29143;20566:13;7852:29143;20955:28;:::i;:::-;20941:43;:::i;:::-;21037:27;;;;:::i;:::-;21079:9;-1:-1:-1;21090:16:0;;;;;;21307:26;;;;;:::i;:::-;21348:9;-1:-1:-1;21359:15:0;;;;;;-1:-1:-1;;;21558:28:0;;7852:29143;;;21602:9;21938:14;-1:-1:-1;21938:14:0;;21597:863;21613:16;;;;;;7852:29143;21602:9;21684:21;;;;;:::i;:::-;21670:36;;;;:::i;:::-;21759:164;;;;;:::i;:::-;21720:203;;22025:51;;;;;:::i;:::-;22017:60;;;;:::i;:::-;;:72;7852:29143;;;;20678:1;7852:29143;22165:60;;;;;:::i;:::-;7852:29143;;;;:::i;:::-;;;;;;;-1:-1:-1;21975:324:0;;;7852:29143;;;21975:324;;;7852:29143;;;21975:324;;;7852:29143;21938:375;;;;:::i;:::-;7852:29143;;22359:28;;;7852:29143;;;22359:28;;;;;;;;7852:29143;22359:28;7852:29143;22359:28;:::i;:::-;7852:29143;22349:39;;22432:3;21602:9;;;;21348;21425;;21392:65;21425:9;;;;;;21392:65;7852:29143;21425:9;20678:1;21425:9;;;:::i;21392:65::-;;;:::i;:::-;7852:29143;;21348:9;;;;;;;21079;21152:10;21124:56;21152:28;:10;;;;;;20678:1;21152:10;;;:::i;21124:56::-;;;;;:::i;:::-;7852:29143;;21079:9;;;;;;;20192:94;7852:29143;;;20244:31;;;;7852:29143;;;;;;;;;;;;;;;9436:3;7852:29143;;;;;;;;;;;;;;;;926:61:6;;:::i;:::-;2010:29;7852:29143:0;1991:15:6;7852:29143:0;;;;;;;;;;;1991:48:6;1987:113;;7852:29143:0;;;;;;;;1497:15:6;7852:29143:0;;1497:15:6;7852:29143:0;;;;;;;;2170:20:6;;7852:29143:0;;2170:20:6;7852:29143:0;;1987:113:6;7852:29143:0;;;2062:27:6;;;;7852:29143:0;;;:::i;:::-;;;;;;;;;;;;;;;;;763:7:7;7852:29143:0;774:1:7;7852:29143:0;;;;;763:12:7;759:66;;7852:29143:0;;;;763:7:7;7852:29143:0;756:72:8;;:::i;:::-;7852:29143:0;-1:-1:-1;7852:29143:0;24378:7;7852:29143;;;-1:-1:-1;7852:29143:0;;;;774:1:7;7852:29143:0;;;;;;;;:::i;:::-;24419:34;;24464:221;;;;7852:29143;24514:15;7852:29143;;;;24494:35;24490:103;;24730:57;24464:221;;24730:57;;;24739:23;24730:57;;:::i;:::-;867:11:7;7852:29143:0;;763:7:7;7852:29143:0;;;763:7:7;7852:29143:0;;24730:57;24765:22;24730:57;;:::i;24490:103::-;7852:29143;;;24556:22;;;;24464:221;24653:20;24730:57;24653:20;;;;:::i;:::-;24464:221;;759:66:7;7852:29143:0;;;798:16:7;;;;7852:29143:0;;;;;;;:::o;:::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;:::i;:::-;;-1:-1:-1;7852:29143:0;10613:68;7852:29143;;;;-1:-1:-1;7852:29143:0;;;;;;;;;;;;;;;;;;;;;;;10275:5;7852:29143;;;;;;;;;;;;;;;;8464:27;7852:29143;;;;;;;;;;;;;;;;;;;;;;9666:33;7852:29143;;;;;;;;;;;;;;;;;763:7:7;7852:29143:0;;;774:1:7;7852:29143:0;;;;;763:12:7;759:66;;7852:29143:0;;;;;;756:72:8;;:::i;:::-;7852:29143:0;-1:-1:-1;7852:29143:0;25403:7;7852:29143;;25530:22;7852:29143;-1:-1:-1;7852:29143:0;25460:23;;;;:::i;:::-;25530:22;;:::i;:::-;;25586:13;;7852:29143;;;;;;-1:-1:-1;25676:15:0;;;;;;867:11:7;7852:29143:0;;763:7:7;7852:29143:0;;;763:7:7;7852:29143:0;;25665:9;25731:16;25827:27;25731:16;;;;;:::i;:::-;7852:29143;;;;;;25827:27;;:::i;:::-;7852:29143;25665:9;;7852:29143;;;;;;;;;;;;;;;8389:6;7852:29143;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;-1:-1:-1;7852:29143:0;8959:49;7852:29143;;;;;-1:-1:-1;7852:29143:0;;;;;;;;;;;;;;;;;;;;;;;;926:61:6;;:::i;:::-;3651:15;7852:29143:0;;;;;;;;;;;;;3647:108:6;;7852:29143:0;;;;3651:15:6;7852:29143:0;3828:31:6;;;;7852:29143:0;;3647:108:6;7852:29143:0;;;3717:27:6;;;;7852:29143:0;;;:::i;:::-;;;;;;;;;;;;;;;;;1237:7:8;7852:29143:0;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7852:29143:0;10069:63;7852:29143;;;;-1:-1:-1;7852:29143:0;10069:63;7852:29143;;10069:63;;7852:29143;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7852:29143:0;;;:::o;:::-;;;;;;;;;:::o;:::-;;;:::i;:::-;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;-1:-1:-1;7852:29143:0;8588:41;7852:29143;;;-1:-1:-1;7852:29143:0;;;;;8588:41;;;;7852:29143;8588:41;;7852:29143;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;10346:35;7852:29143;;;;;;;;;;;;;;;;;;;;;;;9292:2;7852:29143;;;;;;;;;;;;;;;;;;9592:1;7852:29143;;;;;;;;;;;;;;;;;;10814:1;7852:29143;;;;;;;;;;;;;;;;;;;;:::i;:::-;926:61:6;;:::i;:::-;23175:13:0;7852:29143;-1:-1:-1;7852:29143:0;;;;;;23009:33;7852:29143;;;;;;;;;;;;23153:20;7852:29143;;23175:13;;:::i;:::-;7852:29143;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7852:29143:0;28029:7;7852:29143;;;;28029:25;7852:29143;-1:-1:-1;7852:29143:0;28029:25;7852:29143;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;-1:-1:-1;7852:29143:0;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;:::i;:::-;763:7:7;7852:29143:0;;;;;;774:1:7;7852:29143:0;;;;;763:12:7;759:66;;7852:29143:0;;;;;;756:72:8;;:::i;:::-;-1:-1:-1;22708:15:0;;;;;;867:11:7;7852:29143:0;;763:7:7;7852:29143:0;;;763:7:7;7852:29143:0;;22697:9;7852:29143;;;;;;;;;;;;;;;;;;;;;;;;;33275:17;;;7852:29143;;20375:7;7852:29143;;;;;;;33275:17;7852:29143;;;;;;;;;;;;;;;:::i;:::-;33351:28;33347:111;;22697:9;33495:14;33554:33;33495:14;;;33554:33;;;;;;:::i;:::-;7852:29143;;;;;33701:9;34158:13;-1:-1:-1;34158:13:0;;33696:647;33712:15;;;;;;7852:29143;;;;;34358:38;;7852:29143;;;;34358:38;;;;;:::i;:::-;;;;7852:29143;22697:9;;33701;33767:16;;;;;;;;;;:::i;:::-;7852:29143;33802:27;;;;33798:87;;33923:20;;;;:::i;:::-;7852:29143;;;;;;;;;33957:81;;34204:68;34158:32;7852:29143;;;;34067:18;7852:29143;;;;34067:18;:::i;:::-;7852:29143;;;;;;;;;;;;;;;;34158:32;;:::i;:::-;34245:10;;34204:68;;:::i;:::-;7852:29143;33701:9;;;;;33957:81;7852:29143;;;34002:21;;;;33798:87;7852:29143;;;33856:14;;;;33347:111;33425:21;;;:::i;:::-;33347:111;;7852:29143;;;;;;;;;;;;2427:15:6;7852:29143:0;2427:15:6;7852:29143:0;;;;;;;;:::i;:::-;2427:44:6;2423:105;;7852:29143:0;;2542:10:6;:28;2538:87;;7852:29143:0;;;;;2542:10:6;7852:29143:0;;;;;1497:15:6;7852:29143:0;;1497:15:6;7852:29143:0;;;;;1497:15:6;7852:29143:0;;1497:15:6;7852:29143:0;;;;;2542:10:6;7852:29143:0;;2732:20:6;;7852:29143:0;;;;2732:20:6;;;;7852:29143:0;2538:87:6;7852:29143:0;;;2593:21:6;;;;2423:105;7852:29143:0;;;2494:23:6;;;;7852:29143:0;;;;;;;;;;;;;;705:29:6;7852:29143:0;;;;;;;;;;;;;;;;;;;763:7:7;7852:29143:0;;;774:1:7;;7852:29143:0;;;;;;;;;763:12:7;759:66;;7852:29143:0;;;;;;756:72:8;;:::i;:::-;14652:17:0;;7852:29143;;20375:7;7852:29143;;;;;;;14652:17;14710:20;;;;:::i;:::-;14757:12;7852:29143;;;;;;;;14757:12;:::i;:::-;14806:13;;;7852:29143;;;14874:24;-1:-1:-1;14913:9:0;;14924:15;;;;;;16089:17;16026:16;;;;;:::i;:::-;16089:17;:::i;14913:9::-;14979;;;;;;:::i;:::-;7852:29143;;;;;;;;;;;:::i;:::-;15057:29;;;7852:29143;;;;;15180:13;7852:29143;;;;;;;15180:13;;7852:29143;15173:4;;15153:10;;15180:13;;:::i;:::-;7852:29143;14913:9;;15053:860;7852:29143;;;;;;;;:::i;:::-;14652:7;15219:28;;14652:7;;7852:29143;;;15421:38;7852:29143;15421:38;7852:29143;;;;15421:17;;7852:29143;;;;15421:38;;:::i;:::-;15394:4;;15354:10;;7852:29143;;;15421:38;:::i;:::-;15053:860;;15215:698;7852:29143;;;;;;;;:::i;:::-;15502:26;774:1:7;;15569:17:0;;;:38;:17;:38;7852:29143;15569:17;15548:60;15569:17;;7852:29143;;;;;;;15569:38;;;:::i;:::-;15548:60;;:::i;:::-;15498:415;15053:860;;15498:415;15842:38;15807:13;;15842:38;15807:13;;;;;;;7852:29143;15842:17;;7852:29143;;;;15842:38;;:::i;:::-;15780:4;;15740:10;;7852:29143;;;15842:38;:::i;7852:29143::-;;;;;;;;;;;;;;;8210:14;7852:29143;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8265:15;7852:29143;;;;;;;;;;;;;;;;;10453:27;7852:29143;;;;;;;;;;;;;;;;;;;;;;;8790:88;7852:29143;;;;;:::i;:::-;;;-1:-1:-1;7852:29143:0;;;;;-1:-1:-1;7852:29143:0;;;;;;;;;;;;;8790:88;7852:29143;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;926:61:6;;:::i;:::-;763:7:7;7852:29143:0;774:1:7;7852:29143:0;;;;;763:12:7;759:66;;7852:29143:0;;;;;763:7:7;7852:29143:0;;-1:-1:-1;7852:29143:0;24966:7;7852:29143;;;-1:-1:-1;7852:29143:0;25024:20;;;;:::i;:::-;7852:29143;;;;8210:14;7852:29143;;;;;;;;25060:15;:42;25056:110;;25211:23;;;:::i;25056:110::-;7852:29143;;;25125:30;;;;7852:29143;;;:::i;:::-;;;;;;;;;;;;;;;;;763:7:7;7852:29143:0;;774:1:7;7852:29143:0;;;;;763:12:7;759:66;;7852:29143:0;;24182:36;7852:29143;;;763:7:7;7852:29143:0;756:72:8;;:::i;:::-;23352:17:0;;;7852:29143;;20375:7;7852:29143;;;;;;;23352:17;23409:18;;;:::i;:::-;23848:21;7852:29143;;;;;;;;;;;;23487:10;:25;23483:78;;7852:29143;23974:68;774:1:7;23595:20:0;;7852:29143;;;;;;;;;;23673:20;23881:24;763:7:7;23673:20:0;;7852:29143;23648:81;23649:45;23665:29;7852:29143;;;;;;;;;;;;23665:29;23649:45;;:::i;:::-;7852:29143;;;;;;;23648:81;7852:29143;;;;;;;;;23848:21;;;;:::i;:::-;7852:29143;;;;;;;23881:24;7852:29143;;;;;;;;23974:68;;;:::i;:::-;7852:29143;24057:17;;24053:114;;7852:29143;-1:-1:-1;;7852:29143:0;;;;;;;;;;;;;;;24182:36;867:11:7;7852:29143:0;;763:7:7;7852:29143:0;;;763:7:7;7852:29143:0;;24053:114;24090:50;:66;:50;7852:29143;;;;24090:33;7852:29143;;;;;;;24090:50;7852:29143;;;24090:66;:::i;:::-;7852:29143;;24053:114;;;;23483:78;23544:5;7852:29143;-1:-1:-1;7852:29143:0;;;;;23544:5;23483:78;;7852:29143;;;;;;;;;;;;;;;;8140:29;7852:29143;;;;;;;;;;;;;;;;;;;;;:::i;:::-;926:61:6;;:::i;:::-;3027:15;7852:29143:0;;;;;;;;;;;;;3023:108:6;;7852:29143:0;;;;;;;;3027:15:6;7852:29143:0;3415:56:6;;;;7852:29143:0;;;3441:10:6;7852:29143:0;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;-1:-1:-1;7852:29143:0;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;-1:-1:-1;7852:29143:0;28212:7;7852:29143;;;;;;28212:24;7852:29143;-1:-1:-1;7852:29143:0;28212:24;7852:29143;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;-1:-1:-1;7852:29143:0;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7852:29143:0;28397:7;7852:29143;;;;;28397:25;7852:29143;-1:-1:-1;7852:29143:0;28397:25;7852:29143;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7852:29143:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7852:29143:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12253:17;;;:::i;:::-;7852:29143;;;;;12295:15;8210:14;12295:15;7852:29143;12284:49;:103;;;;;7852:29143;12280:160;;;12479:20;;;;;:::i;:::-;7852:29143;12513:36;7852:29143;12536:13;7852:29143;;;;;;;;12513:36;7852:29143;;;12513:36;12509:96;;12641:22;;;;;:::i;:::-;7852:29143;;;;12673:157;;7852:29143;12875:14;7852:29143;;;12875:14;;;;7852:29143;;12875:14;12932:13;;;;;;;;:::i;:::-;12966:16;;;;:69;;;;7852:29143;12962:127;;13123:17;;;7852:29143;;20375:7;7852:29143;;;;;;;13123:17;13150:29;;;-1:-1:-1;13189:22:0;;13226:9;13637:13;13226:9;13637:13;;13221:512;13237:15;;;;;;13767:21;;;;;;;;;;;;;:::i;:::-;7852:29143;;;;;13802:39;;:104;;;;;13221:512;13798:163;;;14011:21;;;;14319:42;7852:29143;14011:21;;14236:73;14274:35;;14011:21;14148:30;14456:20;14011:21;;;;14371:40;14011:21;;;;:::i;:::-;7852:29143;;;;14059:10;7852:29143;;;14079:59;14110:28;;;;;:::i;:::-;14079:59;7852:29143;;;;;;;;;;;;;;;;;;;14079:59;7852:29143;;;;;;;;;;;;;;;14148:30;14188:38;7852:29143;14188:21;;:38;;7852:29143;;;;;;;;;;;14188:38;14274:35;;:::i;:::-;7852:29143;;;;;;;;;;;;;;;14236:73;7852:29143;;;;;;;;;;;;;;;14319:42;7852:29143;;;;;;;;;;;;;;;14371:40;14456:20;:::i;:::-;13767:21;7852:29143;;;;;;;;;;;;13798:163;13767:21;7852:29143;13929:21;;;;13802:104;9436:3;13845:61;;;13802:104;;;13226:9;7852:29143;13291:13;13270:37;13291:16;:13;;;;;:::i;:::-;:16;;:::i;:::-;13270:37;:::i;:::-;13325:15;;;;7852:29143;;;;;;;;;;;;;;13325:34;13321:94;;13443:5;;;:::i;:::-;7852:29143;;;;13464:44;;;:::i;:::-;7852:29143;;;13522:28;;;7852:29143;13522:28;7852:29143;;;13637:25;;;;;:::i;:::-;7852:29143;;13226:9;;13321:94;7852:29143;;;13386:14;;;;12962:127;7852:29143;;;13058:20;;;;12966:69;12986:49;9292:2;12986:49;;12966:69;;12673:157;12726:35;12727:34;;;7852:29143;;;;12727:17;7852:29143;;;;;;;12727:34;7852:29143;;;;;12726:35;12722:98;12673:157;12722:98;7852:29143;;12788:17;;;;12509:96;7852:29143;;;12572:22;;;;12280:160;7852:29143;;;12410:19;;;;12284:103;12295:15;;8265;12295;7852:29143;-1:-1:-1;12284:103:0;;;7852:29143;;;;;;;;;;;;;;;;;;:::i;:::-;926:61:6;;:::i;:::-;7852:29143:0;28889:35;;28885:102;;7852:29143;;29055:50;7852:29143;;28996:44;7852:29143;;;28996:44;7852:29143;;;;;;29055:50;7852:29143;28885:102;7852:29143;;;28947:29;;;;7852:29143;;;;;;;;;;;;;;;;:::i;:::-;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;763:7:7;7852:29143:0;;;774:1:7;7852:29143:0;;;;;;;763:12:7;759:66;;7852:29143:0;;;;;;756:72:8;;:::i;:::-;-1:-1:-1;16684:9:0;;16695:16;;;;;;19174:51;7852:29143;;;19174:51;:::i;16684:9::-;16760:10;;;;;:::i;:::-;16789:24;;;7852:29143;16789:54;10814:1;16789:54;;;16785:114;;7852:29143;16984:17;;;7852:29143;;20375:7;7852:29143;;;;;;;16984:17;17046;;;;:::i;:::-;7852:29143;;17083:36;;7852:29143;;;;;;17083:36;:15;:36;;17079:101;;17231:47;7852:29143;17231:21;16984:7;17231:21;;:47;:::i;:::-;7852:29143;;:::i;:::-;17329:104;:59;:46;17364:10;17329:34;;7852:29143;;;;;;;;;;17329:34;7852:29143;;;;;;;;;;;;17329:46;7852:29143;;;;;;;17329:59;7852:29143;;;;;17329:104;;:::i;:::-;17480:35;;;7852:29143;;17451:64;;7852:29143;;;;;;17451:64;7852:29143;;;;;;17451:64;17447:147;;17607:88;17364:10;17607:46;17364:10;17607:34;;7852:29143;;;;;;;;;;17607:46;7852:29143;;;;;;;;;;;;;;;17607:88;17726:19;;;7852:29143;;;;;;;;;;;;;;;;;;;;17820:25;;;;;;;;;;;;:::i;:::-;17760:222;;18063:14;;;7852:29143;;;;18102:23;;18098:336;18102:23;;;7852:29143;18165:54;7852:29143;18172:46;7852:29143;;;;;;;18172:46;7852:29143;;;;;18165:54;18098:336;;7852:29143;;;;;;;;18448:185;;18098:336;7852:29143;;;;18752:29;7852:29143;;;18647:91;7852:29143;18882:66;7852:29143;18667:70;18988:41;7852:29143;18667:70;7852:29143;;:::i;:::-;;;;;;;;18667:70;17364:10;18667:70;;;7852:29143;;18667:70;18647:91;:::i;:::-;18752:20;;:29;7852:29143;;;;;;;;;18752:29;:::i;:::-;7852:29143;;;;;;;;;;18752:29;18796:66;:46;17364:10;18796:34;17364:10;18796:34;7852:29143;;;;;;;;;;18796:46;:66;7852:29143;;;;;;;;18796:66;7852:29143;;;;;;;;;;;;17364:10;7852:29143;;;;;;;;;;;;;;;;;;;;;;;;18882:66;7852:29143;;;;;18988:41;7852:29143;;;18967:62;;18963:131;;18098:336;7852:29143;;;16684:9;;18963:131;19072:6;;;:::i;:::-;18963:131;;;;18448:185;7852:29143;;;;;;;;;;;;18504:42;7852:29143;;;;;;;18504:42;7852:29143;;;18504:42;;18500:119;;18448:185;;;;;;;;;;;;;;18500:119;7852:29143;;;18577:23;;;;18098:336;7852:29143;18298:54;7852:29143;18298:121;7852:29143;;18298:54;;:::i;:::-;7852:29143;;;;;;;;;;;;;18298:121;18098:336;;;17760:222;7852:29143;17884:83;7852:29143;;;;;;;;;;;;17954:4;;17364:10;;17884:83;;:::i;:::-;17760:222;;17447:147;7852:29143;;;17542:37;;;;17079:101;7852:29143;;;17146:19;;;;16785:114;7852:29143;;;16870:14;;;;759:66:7;7852:29143:0;;;798:16:7;;;;7852:29143:0;;;;;;;;:::i;:::-;763:7:7;;7852:29143:0;;;774:1:7;7852:29143:0;;;;;763:12:7;759:66;;7852:29143:0;;;;;;756:72:8;;:::i;:::-;-1:-1:-1;26217:9:0;;;;;;867:11:7;7852:29143:0;;763:7:7;7852:29143:0;;;763:7:7;7852:29143:0;;26206:9;26263:12;;;;;:::i;:::-;7852:29143;26313:17;;;7852:29143;;20375:7;7852:29143;;;;;;;26313:17;7852:29143;;26365:23;;7852:29143;;;;;;;:::i;:::-;26349:39;26345:100;;26492:46;26527:10;26492:34;;7852:29143;;;;;;;;;;26492:46;7852:29143;;;;;;;;;26553:77;;26644:21;;26731:71;7852:29143;26644:21;7852:29143;26644:21;;26822:47;26644:21;7852:29143;;;;;;;;;26644:21;7852:29143;;;;;;26755:22;;7852:29143;;;;;;;;;;;26527:10;;26731:71;;:::i;:::-;7852:29143;;;;;;26527:10;7852:29143;;;;;;;;;;;;;;;;;;26822:47;7852:29143;26206:9;;26553:77;7852:29143;;;26598:17;;;;26345:100;7852:29143;;;26415:15;;;;7852:29143;;;;;;;:::o;:::-;;;;;:::i;:::-;;:::o;:::-;;;;;:::i;:::-;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;:::i;:::-;;;;;;;;;-1:-1:-1;7852:29143:0;;;-1:-1:-1;7852:29143:0;;;;;-1:-1:-1;7852:29143:0;:::o;:::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;:::i;:::-;;;;;;:::i;:::-;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;763:7:7;7852:29143:0;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;:::o;:::-;;20678:1;7852:29143;;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;:::o;:::-;;;:::i;:::-;;;;;;;;;;;;;;;:::o;:::-;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;-1:-1:-1;7852:29143:0;;-1:-1:-1;7852:29143:0;;;-1:-1:-1;7852:29143:0;:::o;:::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;:::i;:::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;:::i;:::-;;;;;;;;;;;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;7852:29143:0;;-1:-1:-1;7852:29143:0;;-1:-1:-1;7852:29143:0;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;:::o;:::-;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;:::o;:::-;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;:::o;:::-;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;:::o;:::-;;;:::i;:::-;;;;;;;;:::o;:::-;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;:::o;:::-;;;:::i;:::-;;;;;;;;;;;;;;;;;:::o;:::-;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;:::i;:::-;;;29597:1284;-1:-1:-1;29777:30:0;10814:1;29777:30;;;;29597:1284;;;:::o;29766:9::-;29825:54;29862:17;;;;:::i;:::-;29825:54;:::i;:::-;7852:29143;;;;;;;;;29972:19;;7852:29143;29972:19;;;7852:29143;;;;;;30010:6;;;;-1:-1:-1;7852:29143:0;;;30040:17;;;;;:31;;30006:733;30036:107;;;30753:51;7852:29143;30006:733;;30753:35;:17;:7;:17;;7852:29143;;20375:7;7852:29143;;;;;;;30753:17;:32;:35;:::i;:::-;:51;;:::i;:::-;7852:29143;29766:9;;30036:107;30102:22;7852:29143;;30102:22;;;;30040:31;7852:29143;;;;30061:10;30040:31;;;30006:733;7852:29143;;;;30181:78;30222:37;7852:29143;;;30222:37;;:::i;30181:78::-;30297:23;;;7852:29143;;;;;;;;;;;;;;;;;;;;30438:20;;;;;;:::i;:::-;7852:29143;30438:25;;;;:81;;;30006:733;30438:123;;;;30006:733;30438:198;;;;30006:733;30413:312;;;;;;;;;30753:51;7852:29143;30006:733;;;30438:198;30608:28;30585:20;;;:51;:20;;;;;:::i;:::-;7852:29143;;30608:28;;:::i;:::-;7852:29143;;;;30585:51;7852:29143;;30585:51;30438:198;;;;;;;;:123;7852:29143;;;;;;30543:18;;;-1:-1:-1;30438:123:0;;:81;7852:29143;;;30487:32;;;;-1:-1:-1;30438:81:0;;30934:581;31005:15;;;7852:29143;;;;;:::i;:::-;;;;:::i;:::-;31005:35;;31060:17;31081:1;31060:17;;;7852:29143;31060:22;;;;:49;;;31001:508;31056:109;;;30934:581::o;31056:109::-;31136:14;31005:15;7852:29143;31136:14;;;;31060:49;7852:29143;;;31081:1;31086:23;;;-1:-1:-1;31060:49:0;;;31001:508;31218:15;7852:29143;;;;;:::i;:::-;;;;:::i;:::-;31199:34;31195:181;;31001:508;31394:17;;;7852:29143;31394:22;:49;;;;;31390:109;;;30934:581::o;31394:49::-;7852:29143;;;31420:23;;-1:-1:-1;31394:49:0;;;31195:181;31257:38;31258:37;;7852:29143;31276:18;;;7852:29143;;;;;;;;;;12727:17;7852:29143;;;;;;;31257:38;31253:109;31195:181;31253:109;31326:17;31005:15;7852:29143;31326:17;;;;31702:767;;7852:29143;;;;;;;;;;;;;;;:::i;:::-;31936:29;;;32048:13;763:7:7;32048:13:0;;;7852:29143;32030:4;;32048:13;;:::i;31932:531::-;7852:29143;;763:7:7;7852:29143:0;;:::i;:::-;32083:30;763:7:7;;32266:13:0;32297:30;32266:13;32297:30;:17;763:7:7;32266:13:0;;7852:29143;32297:17;;7852:29143;32297:30;:::i;:::-;32216:4;;32297:30;;:::i;32079:384::-;32421:17;:30;:17;;7852:29143;;;;;763:7:7;7852:29143:0;;;;32421:30;7852:29143;;;:::i;:::-;32421:30;:::i;31702:767::-;7852:29143;;31702:767;;7852:29143;;;;;;;;;;;;:::i;:::-;31936:29;;;32048:13;;;;;;;7852:29143;32030:4;;32048:13;;:::i;31932:531::-;7852:29143;;32096:17;7852:29143;;;;;:::i;:::-;32083:30;32096:17;;32297:30;;32266:13;32297:17;32096;32266:13;;7852:29143;32297:17;;7852:29143;32297:30;:::i;32079:384::-;32421:17;:30;:17;;:30;:17;;7852:29143;32421:30;:::i;:::-;;32652:353;;;;7852:29143;;;;;32891:9;;;;;32866:4;;32891:9;:::i;32786:213::-;1523:20:18;;:25;1519:77;;7852:29143:0;;1655:45:18;;;;;;;7852:29143:0;;;;1655:45:18;;;7852:29143:0;;;;;;;;32810:1;;;;;;1655:45:18;7852:29143:0;;;;1655:45:18;;;;;;;;;:::i;:::-;1641:60;;;;;;:::i;:::-;1716:7;;1712:64;;7852:29143:0;;1790:15:18;1786:135;;32786:213:0;;32652:353::o;1786:135:18:-;1826:24;1655:45;1826:24;;;1825:25;1826:24;;;;;;:::i;1825:25::-;1821:90;;32652:353:0:o;1821:90:18:-;1655:45;7852:29143:0;;1877:19:18;;;;1519:77;1571:14;7852:29143:0;;1571:14:18;;;;7852:29143:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;34543:692;;34690:40;34543:692;34659:20;;;;:::i;:::-;7852:29143;;;;34714:15;7852:29143;;;;;;;;34690:40;7852:29143;;;34761:182;;34809:8;34761:182;;;7852:29143;34831:15;7852:29143;;;;;;;;;;;;;;;;;;;;;34761:182;7852:29143;;;-1:-1:-1;34761:15:0;7852:29143;;34761:182;;;;;;;34543:692;34690:14;34761:182;;;34543:692;34958:29;:36;:29;;7852:29143;;20153:18;7852:29143;;;;;;;34958:36;34954:106;;35188:40;35070:29;:43;:29;;7852:29143;;20153:18;7852:29143;;;;;;;35070:29;34931:1;7852:29143;;;;;;;;35070:43;35123:29;34931:1;35123:29;;7852:29143;;20153:18;7852:29143;;;;;;;35123:29;:38;7852:29143;;;;;;;;;;;;;;35188:40;34543:692::o;34954:106::-;34761:182;7852:29143;;35017:32;;;;34761:182;;;;;;;;;;;;;;;:::i;:::-;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;;;35368:180;7852:29143;;35368:180;7852:29143;;;;;;;;;;35368:180;35470:23;35466:76;;35368:180::o;7852:29143::-;;;:::i;:::-;;;35368:180;7852:29143;763:7:7;35368:180:0;7852:29143;;;;;;;;;;35470:23;35466:76;;35368:180::o;:::-;7852:29143;25460:23;35368:180;7852:29143;;;;;;;;;;35470:23;35466:76;;35368:180::o;:::-;7852:29143;33425:21;35368:180;7852:29143;;;;;;;;;;35470:23;35466:76;;35368:180::o;:::-;7852:29143;24966:7;35368:180;7852:29143;;;;;;;;;;35470:23;35466:76;;35368:180::o;:::-;7852:29143;23409:18;35368:180;7852:29143;;;;;;;;;;35470:23;35466:76;;35368:180::o;:::-;7852:29143;774:1:7;35368:180:0;7852:29143;;;;;;;;;;35470:23;35466:76;;35368:180::o;35612:143::-;7852:29143;;35680:10;:20;35676:73;;35612:143::o;35676:73::-;35723:15;7852:29143;;35723:15;;;;35857:448;35967:9;35948:28;;35967:9;;;35999:34;7852:29143;;35999:34;;;;35944:355;35967:9;;36054:28;36050:249;;35944:355;35857:448::o;36050:249::-;36265:9;;;35967;;7852:29143;36175:10;36153:4;36265:9;:::i;36487:217::-;7852:29143;;;;;;;;;;;;;;20511:18;7852:29143;;;;36660:37;;;36487:217::o;:::-;7852:29143;;;;;;;;;;;;;;25530:22;7852:29143;;;;36660:37;;;36487:217::o;:::-;7852:29143;;;;;;;;;;;;;;774:1:7;7852:29143:0;;;;36660:37;;;36487:217::o;:::-;7852:29143;;;;;;;;;;;;;;25211:23;7852:29143;;;;36660:37;;;36487:217::o;:::-;7852:29143;;;;;;;;;;;;;;23848:21;7852:29143;;;;36660:37;;;36487:217::o;:::-;7852:29143;;;;;;;;;;;;;;-1:-1:-1;7852:29143:0;;;;36660:37;;;36487:217::o;:::-;7852:29143;;;;;;;;;;;;;;34659:20;7852:29143;;;;36660:37;;;36487:217::o;:::-;7852:29143;;;;;;;;;;;;;;19755:32;7852:29143;;;;36660:37;;;36487:217::o;:::-;;7852:29143;36660:37;36487:217;7852:29143;36487:217;7852:29143;;;;;;36487:217;7852:29143;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;36660:37;36487:217::o;7852:29143::-;;;:::i;:::-;;;445:886:1;;;;;7852:29143:0;713:1:1;7852:29143:0;739:1:1;7852:29143:0;745:19:1;;;;;7852:29143:0;775:449:1;739:1;;;775:449;1234:36;;;;;;;;;;;:::i;:::-;7852:29143:0;1234:36:1;;;;:::i;:::-;7852:29143:0;1281:43:1;445:886;:::o;775:449::-;782:28;;;;;;;;;:::i;:::-;7852:29143:0;782:35:1;:40;;;-1:-1:-1;842:33:1;;;;;895:10;;;-1:-1:-1;923:16:1;;838:328;;775:449;1193:19;775:449;1193:19;;;7852:29143:0;;;;775:449:1;;838:328;7852:29143:0;;;;;;;;;;;;838:328:1;978:17;;7852:29143:0;1017:23:1;1013:139;;838:328;;;;;;1013:139;7852:29143:0;;;;1013:139:1;;7852:29143:0;;;:::i;:::-;;;782:40:1;;;;;;;;737:983:3;7852:29143:0;;848:17:3;;;844:56;;864:1;935:27;980:10;;;;;;1554:7;;;;:36;;;;973:464;-1:-1:-1;;1550:164:3;;;7852:29143:0;;1634:14:3;:::o;1554:36::-;1565:14;1571:7;;;;;;:::i;:::-;1565:14;;:::i;:::-;7852:29143:0;1565:25:3;1554:36;;;;973:464;1020:23;;;;:::i;:::-;1006:37;;1260:10;;;;;:::i;:::-;7852:29143:0;1260:20:3;;;;1300:10;;973:464;;1256:171;1393:1;7852:29143:0;;-1:-1:-1;7852:29143:0;-1:-1:-1;973:464:3;;844:56;881:8;;;864:1;881:8;:::o;6618:256:4:-;6731:14;7852:29143:0;;;6717:10:4;:28;6713:109;;7852:29143:0;;-1:-1:-1;7852:29143:0;19478:18;7852:29143;;;;-1:-1:-1;7852:29143:0;;;19474:518;;6618:256:4;;:::o;19474:518:0:-;19550:39;7852:29143;-1:-1:-1;7852:29143:0;19550:39;7852:29143;;;-1:-1:-1;7852:29143:0;19627:7;7852:29143;;;-1:-1:-1;7852:29143:0;19627:7;7852:29143;;;;;;;;;:::i;:::-;19663:37;19659:323;;19474:518;;;6618:256:4;;:::o;19659:323:0:-;19951:15;19899:30;19755:32;;19899:68;19755:32;19943:24;19755:32;;:::i;:::-;19951:15;:::i;:::-;7852:29143;;;;;19943:24;19899:30;7852:29143;;20153:18;7852:29143;;;;;;;19899:30;7852:29143;;;;;;;;;;;;;;;19899:68;19659:323;;;;;;6713:109:4;7852:29143:0;;6762:53:4;;;6717:10;6762:53;;;7852:29143:0;;;;;;;;;;;;6762:53:4;3872:94:6;7852:29143:0;3935:5:6;7852:29143:0;;3921:10:6;:19;3917:42;;3872:94::o;3917:42::-;3949:10;7852:29143:0;;3949:10:6;;;;1319:123:8;7852:29143:0;1237:7:8;7852:29143:0;;;;1380:56:8;;1319:123::o;1380:56::-;1415:10;7852:29143:0;;1415:10:8;;;;7852:29143:0;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;7852:29143:0;;;;:::o;:::-;;;:::i;:::-;;;;;;:::o;797:474:17:-;;;;;986:22;;:27;982:79;;1012:1;7852:29143:0;;;;;;;1105:74:17;;;;;;;;7852:29143:0;;;;1105:74:17;;;7852:29143:0;;;;;;;;;;;;;;;;;;;;;;;;;1105:74:17;;;;;:::i;:::-;1089:91;;;;;;:::i;:::-;;1195:7;1191:74;;797:474::o;1191:74::-;1105;7852:29143:0;;1225:29:17;;;;7852:29143:0;;;;;;;;;;;;;:::i;693:540:18:-;;;;;811:20;;:25;807:77;;7852:29143:0;;943:55:18;;;;;;;7852:29143:0;;;;943:55:18;;;7852:29143:0;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;943:55:18;7852:29143:0;;;;943:55:18;7852:29143:0;943:55:18;929:70;;;;;;:::i;:::-;1014:7;;1010:68;;7852:29143:0;;1092:15:18;1088:139;;693:540;;:::o;1088:139::-;1128:24;943:55;1128:24;;;1127:25;1128:24;;;;;;:::i;1127:25::-;1123:94;;693:540::o;1123:94::-;943:55;7852:29143:0;;1179:23:18;;;;708:385:19;;;;;830:22;;:27;826:79;;7852:29143:0;;949:57:19;;;;;;;7852:29143:0;;;;949:57:19;;;7852:29143:0;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;949:57:19;7852:29143:0;;;;949:57:19;7852:29143:0;949:57:19;933:74;;;;;;:::i;:::-;;1022:7;1018:69;;708:385::o;1018:69::-;949:57;7852:29143:0;;1052:24:19;;;;808:415:20;1096:7;808:415;;;-1:-1:-1;998:84:20;;;;;;;;1096:7;;7852:29143:0;1096:7:20;1092:125;;808:415;;;;:::o;1092:125::-;7852:29143:0;;1119:38:20;;;;;;7852:29143:0;1171:35:20;7852:29143:0;;1171:35:20;7852:29143:0;;;;1119:38:20;;;;;;;;;;;;;;1092:125;1119:38;;1092:125;7852:29143:0;;;1171:35:20;;;;;;7852:29143:0;1171:35:20;;1119:38;1171:35;;7852:29143:0;;;;;;;;;;;;;;;;;1171:35:20;;;;;;;;;1092:125;1171:35;;1092:125;;;;;;1171:35;;;;;;;;;;;;;;:::i;:::-;;;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;1119:38;;;;;;:::i;:::-;;;:::i;:::-;;;;;;;:::i;:::-;;;608:153:21;;734:5;;;744;;7852:29143:0;;;;;;;;;608:153:21;:::o;7852:29143:0:-;;;:::i
Swarm Source
ipfs://333d426aac2099c9c3169823ea4ce62867fd4773c40055754f9c9bbe95597e44
Loading...
Loading
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.