Overview
ETH Balance
0.5700865 ETH
Eth Value
$1,886.24 (@ $3,308.70/ETH)More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 621 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Mint To | 19729195 | 69 days ago | IN | 0.003777 ETH | 0.00151009 | ||||
Mint To | 19723541 | 70 days ago | IN | 0.010777 ETH | 0.00172878 | ||||
Mint To | 19156790 | 149 days ago | IN | 0.005777 ETH | 0.00256507 | ||||
Mint To | 19152517 | 150 days ago | IN | 0.000777 ETH | 0.00202772 | ||||
Mint To | 19133529 | 153 days ago | IN | 0.030777 ETH | 0.0057076 | ||||
Mint To | 19130795 | 153 days ago | IN | 0.001777 ETH | 0.00387454 | ||||
Mint To | 19117349 | 155 days ago | IN | 0.000777 ETH | 0.00167792 | ||||
Mint To | 19116801 | 155 days ago | IN | 0.000777 ETH | 0.00226089 | ||||
Mint To | 19107370 | 156 days ago | IN | 0.004662 ETH | 0.00193093 | ||||
Mint To | 19098633 | 158 days ago | IN | 0.000777 ETH | 0.00256202 | ||||
Mint To | 19074732 | 161 days ago | IN | 0.001554 ETH | 0.0015024 | ||||
Mint To | 19073842 | 161 days ago | IN | 0.001777 ETH | 0.00243392 | ||||
Mint To | 19058417 | 163 days ago | IN | 0.000777 ETH | 0.00219345 | ||||
Mint To | 19058167 | 163 days ago | IN | 0.000777 ETH | 0.00194995 | ||||
Mint To | 19040166 | 166 days ago | IN | 0.001777 ETH | 0.00349141 | ||||
Mint To | 19023025 | 168 days ago | IN | 0.001554 ETH | 0.00519388 | ||||
Mint To | 19010818 | 170 days ago | IN | 0.000777 ETH | 0.0028613 | ||||
Mint To | 18996868 | 172 days ago | IN | 0.000777 ETH | 0.00254406 | ||||
Mint To | 18975415 | 175 days ago | IN | 0.000777 ETH | 0.00371905 | ||||
Mint To | 18975383 | 175 days ago | IN | 0.000777 ETH | 0.0036058 | ||||
Mint To | 18971858 | 175 days ago | IN | 0.000777 ETH | 0.00236015 | ||||
Mint To | 18967742 | 176 days ago | IN | 0.000777 ETH | 0.00248183 | ||||
Mint To | 18967485 | 176 days ago | IN | 0.005777 ETH | 0.00285125 | ||||
Mint To | 18964756 | 176 days ago | IN | 0.030777 ETH | 0.00344252 | ||||
Mint To | 18915715 | 183 days ago | IN | 0.000777 ETH | 0.00202584 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
19813521 | 57 days ago | 0.00025 ETH | ||||
19729195 | 69 days ago | 0.003 ETH | ||||
19723541 | 70 days ago | 0.0095 ETH | ||||
19156790 | 149 days ago | 0.005 ETH | ||||
19152517 | 150 days ago | 0.000555 ETH | ||||
19133529 | 153 days ago | 0.03 ETH | ||||
19130795 | 153 days ago | 0.001 ETH | ||||
19117349 | 155 days ago | 0.000555 ETH | ||||
19116801 | 155 days ago | 0.000555 ETH | ||||
19107370 | 156 days ago | 0.00333 ETH | ||||
19098633 | 158 days ago | 0.000555 ETH | ||||
19074732 | 161 days ago | 0.00111 ETH | ||||
19073842 | 161 days ago | 0.001 ETH | ||||
19058417 | 163 days ago | 0.000555 ETH | ||||
19058167 | 163 days ago | 0.000555 ETH | ||||
19040166 | 166 days ago | 0.001 ETH | ||||
19023025 | 168 days ago | 0.00111 ETH | ||||
19010818 | 170 days ago | 0.000555 ETH | ||||
18996868 | 172 days ago | 0.000555 ETH | ||||
18975415 | 175 days ago | 0.000555 ETH | ||||
18975383 | 175 days ago | 0.000555 ETH | ||||
18971858 | 175 days ago | 0.000555 ETH | ||||
18967742 | 176 days ago | 0.000555 ETH | ||||
18967485 | 176 days ago | 0.005 ETH | ||||
18964756 | 176 days ago | 0.03 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
SuperMinter
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import { Ownable, OwnableRoles } from "solady/auth/OwnableRoles.sol"; import { ISoundEditionV2 } from "@core/interfaces/ISoundEditionV2.sol"; import { ISuperMinter } from "@modules/interfaces/ISuperMinter.sol"; import { IERC165 } from "openzeppelin/utils/introspection/IERC165.sol"; import { SafeTransferLib } from "solady/utils/SafeTransferLib.sol"; import { EIP712 } from "solady/utils/EIP712.sol"; import { MerkleProofLib } from "solady/utils/MerkleProofLib.sol"; import { LibBitmap } from "solady/utils/LibBitmap.sol"; import { SignatureCheckerLib } from "solady/utils/SignatureCheckerLib.sol"; import { LibZip } from "solady/utils/LibZip.sol"; import { LibMap } from "solady/utils/LibMap.sol"; import { DelegateCashLib } from "@modules/utils/DelegateCashLib.sol"; import { LibOps } from "@core/utils/LibOps.sol"; import { LibMulticaller } from "multicaller/LibMulticaller.sol"; /** * @title SuperMinter * @dev The `SuperMinter` class is a generalized minter. */ contract SuperMinter is ISuperMinter, EIP712 { using LibBitmap for *; using MerkleProofLib for *; using LibMap for *; // ============================================================= // STRUCTS // ============================================================= /** * @dev A struct to hold the mint data in storage. */ struct MintData { // The platform address. address platform; // The price per token. uint96 price; // The start time of the mint. uint32 startTime; // The end time of the mint. uint32 endTime; // The maximum number of tokens an account can mint in this mint. uint32 maxMintablePerAccount; // The maximum tokens mintable. uint32 maxMintable; // The total number of tokens minted. uint32 minted; // The affiliate fee BPS. uint16 affiliateFeeBPS; // The offset to the next mint data in the linked list. uint16 next; // The head of the mint data linked list. // Only stored in the 0-th mint data per edition. uint16 head; // The total number of mint data. // Only stored in the 0-th mint data per edition. uint16 numMintData; // The total number of mints for the edition-tier. // Only stored in the 0-th mint data per edition-tier. uint8 nextScheduleNum; // The mode of the mint. uint8 mode; // The packed boolean flags. uint8 flags; // The affiliate Merkle root, if any. bytes32 affiliateMerkleRoot; // The Merkle root hash, required if `mode` is `VERIFY_MERKLE`. bytes32 merkleRoot; // The signer address, required if `mode` is `VERIFY_SIGNATURE`. address signer; } // ============================================================= // CONSTANTS // ============================================================= /** * @dev The GA tier. Which is 0. */ uint8 public constant GA_TIER = 0; /** * @dev For EIP-712 signature digest calculation. */ bytes32 public constant MINT_TO_TYPEHASH = // prettier-ignore keccak256( "MintTo(" "address edition," "uint8 tier," "uint8 scheduleNum," "address to," "uint32 signedQuantity," "uint32 signedClaimTicket," "uint96 signedPrice," "uint32 signedDeadline," "address affiliate" ")" ); /** * @dev For EIP-712 signature digest calculation. */ bytes32 public constant DOMAIN_TYPEHASH = _DOMAIN_TYPEHASH; /** * @dev The default value for options. */ uint8 public constant DEFAULT = 0; /** * @dev The Merkle drop mint mode. */ uint8 public constant VERIFY_MERKLE = 1; /** * @dev The Signature mint mint mode. */ uint8 public constant VERIFY_SIGNATURE = 2; /** * @dev The denominator of all BPS calculations. */ uint16 public constant BPS_DENOMINATOR = LibOps.BPS_DENOMINATOR; /** * @dev The maximum affiliate fee BPS. */ uint16 public constant MAX_AFFILIATE_FEE_BPS = 1000; /** * @dev The maximum platform per-mint fee BPS. */ uint16 public constant MAX_PLATFORM_PER_MINT_FEE_BPS = 1000; /** * @dev The maximum platform per-mint flat fee. */ uint96 public constant MAX_PLATFORM_PER_MINT_FLAT_FEE = 0.1 ether; /** * @dev The maximum platform per-transaction flat fee. */ uint96 public constant MAX_PLATFORM_PER_TX_FLAT_FEE = 0.1 ether; /** * @dev The boolean flag on whether the mint has been created. */ uint8 internal constant _MINT_CREATED_FLAG = 1 << 0; /** * @dev The boolean flag on whether the mint is paused. */ uint8 internal constant _MINT_PAUSED_FLAG = 1 << 1; /** * @dev The boolean flag on whether the signer is the platform's signer. */ uint8 internal constant _USE_PLATFORM_SIGNER_FLAG = 1 << 2; /** * @dev The index for the per-platform default fee config. * We use 256, as the tier is uint8, which ranges from 0 to 255. */ uint16 internal constant _DEFAULT_FEE_CONFIG_INDEX = 256; // ============================================================= // STORAGE // ============================================================= /** * @dev A mapping of `platform` => `feesAccrued`. */ mapping(address => uint256) public platformFeesAccrued; /** * @dev A mapping of `platform` => `feeRecipient`. */ mapping(address => address) public platformFeeAddress; /** * @dev A mapping of `affiliate` => `feesAccrued`. */ mapping(address => uint256) public affiliateFeesAccrued; /** * @dev A mapping of `platform` => `price`. */ mapping(address => uint96) public gaPrice; /** * @dev A mapping of `platform` => `platformSigner`. */ mapping(address => address) public platformSigner; /** * @dev A mapping of `mintId` => `mintData`. */ mapping(uint256 => MintData) internal _mintData; /** * @dev A mapping of `platformTierId` => `platformFeeConfig`. */ mapping(uint256 => PlatformFeeConfig) internal _platformFeeConfigs; /** * @dev A mapping of `to` => `mintId` => `numberMinted`. */ mapping(address => LibMap.Uint32Map) internal _numberMinted; /** * @dev A mapping of `mintId` => `signedClaimedTicket` => `claimed`. */ mapping(uint256 => LibBitmap.Bitmap) internal _claimsBitmaps; // ============================================================= // PUBLIC / EXTERNAL WRITE FUNCTIONS // ============================================================= /** * @inheritdoc ISuperMinter */ function createEditionMint(MintCreation memory c) public returns (uint8 scheduleNum) { _requireOnlyEditionOwnerOrAdmin(c.edition); _validateAffiliateFeeBPS(c.affiliateFeeBPS); uint8 mode = c.mode; if (mode == DEFAULT) { c.signer = address(0); c.merkleRoot = bytes32(0); } else if (mode == VERIFY_MERKLE) { _validateMerkleRoot(c.merkleRoot); c.signer = address(0); } else if (mode == VERIFY_SIGNATURE) { _validateSigner(c.signer); c.merkleRoot = bytes32(0); c.maxMintablePerAccount = type(uint32).max; } else { revert InvalidMode(); } // If GA, overwrite any immutable variables as required. if (c.tier == GA_TIER) { c.endTime = type(uint32).max; c.maxMintablePerAccount = type(uint32).max; // We allow the `price` to be the minimum price if the `mode` is `VERIFY_SIGNATURE`. // Otherwise, the actual default price is the live value of `gaPrice[platform]`, // and we'll simply set it to zero to avoid a SLOAD. if (mode != VERIFY_SIGNATURE) c.price = 0; // Set `maxMintable` to the maximum only if `mode` is `DEFAULT`. if (mode == DEFAULT) c.maxMintable = type(uint32).max; } _validateTimeRange(c.startTime, c.endTime); _validateMaxMintablePerAccount(c.maxMintablePerAccount); _validateMaxMintable(c.maxMintable); unchecked { MintData storage tierHead = _mintData[LibOps.packId(c.edition, c.tier, 0)]; MintData storage editionHead = _mintData[LibOps.packId(c.edition, 0)]; scheduleNum = tierHead.nextScheduleNum; uint256 n = scheduleNum; if (++n >= 1 << 8) LibOps.revertOverflow(); tierHead.nextScheduleNum = uint8(n); n = editionHead.numMintData; if (++n >= 1 << 16) LibOps.revertOverflow(); editionHead.numMintData = uint16(n); uint256 mintId = LibOps.packId(c.edition, c.tier, scheduleNum); bool usePlatformSigner = c.signer == address(1); MintData storage d = _mintData[mintId]; d.platform = c.platform; d.price = c.price; d.startTime = c.startTime; d.endTime = c.endTime; d.maxMintablePerAccount = c.maxMintablePerAccount; d.maxMintable = c.maxMintable; d.affiliateFeeBPS = c.affiliateFeeBPS; d.mode = c.mode; d.flags = _MINT_CREATED_FLAG | LibOps.toFlag(usePlatformSigner, _USE_PLATFORM_SIGNER_FLAG); d.next = editionHead.head; editionHead.head = uint16((uint256(c.tier) << 8) | uint256(scheduleNum)); // Skip writing zeros, to avoid cold SSTOREs. if (c.affiliateMerkleRoot != bytes32(0)) d.affiliateMerkleRoot = c.affiliateMerkleRoot; if (c.merkleRoot != bytes32(0)) d.merkleRoot = c.merkleRoot; if (c.signer != address(0)) { if (!usePlatformSigner) d.signer = c.signer; // Only write if it is not the platform signer. } emit MintCreated(c.edition, c.tier, scheduleNum, c); } } /** * @inheritdoc ISuperMinter */ function mintTo(MintTo calldata p) public payable { MintData storage d = _getMintData(LibOps.packId(p.edition, p.tier, p.scheduleNum)); /* ------------------- CHECKS AND UPDATES ------------------- */ // Check if the mint is open. if (LibOps.or(block.timestamp < d.startTime, block.timestamp > d.endTime)) revert MintNotOpen(block.timestamp, d.startTime, d.endTime); if (_isPaused(d)) revert MintPaused(); // Check if the mint is not paused. // Perform the sub workflows depending on the mint mode. uint8 mode = d.mode; if (mode == VERIFY_MERKLE) _verifyMerkle(d, p); else if (mode == VERIFY_SIGNATURE) _verifyAndClaimSignature(d, p); _incrementMinted(mode, d, p); /* ----------- AFFILIATE AND PLATFORM FEES LOGIC ------------ */ TotalPriceAndFees memory f = _totalPriceAndFees(p.tier, d, p.quantity, p.signedPrice); uint256 remaining; // The fee sent to the Sound Edition (i.e. artist fee). bool affiliated; unchecked { if (msg.value != f.total) revert WrongPayment(msg.value, f.total); // Require exact payment. remaining = f.total - f.platformFee; // `platformFee <= total`; platformFeesAccrued[d.platform] += f.platformFee; // Accrue the platform fee. if (affiliated = _isAffiliatedWithProof(d, p.affiliate, p.affiliateProof)) { remaining -= f.affiliateFee; // `affiliateFee <= remaining`. affiliateFeesAccrued[p.affiliate] += f.affiliateFee; // Accrue the affiliate fee. } else { // Proof may be invalid, revert to prevent unintended skipping of affiliate fee. if (p.affiliate != address(0)) revert InvalidAffiliate(); f.affiliateFee = 0; // Set the affiliate fee to zero if not affiliated. } } /* ------------------------- MINT --------------------------- */ ISoundEditionV2 edition = ISoundEditionV2(p.edition); MintedLogData memory l; l.quantity = p.quantity; l.fromTokenId = edition.mint{ value: remaining }(p.tier, p.to, p.quantity); l.allowlisted = p.allowlisted; l.allowlistedQuantity = p.allowlistedQuantity; l.signedClaimTicket = p.signedClaimTicket; l.affiliate = p.affiliate; l.affiliated = affiliated; l.requiredEtherValue = f.total; l.unitPrice = f.unitPrice; l.platformFee = f.platformFee; l.platformFlatFee = f.platformFlatFee; l.affiliateFee = f.affiliateFee; emit Minted(p.edition, p.tier, p.scheduleNum, p.to, l, p.attributionId); } // Per edition mint parameter setters: // ----------------------------------- // These functions can only be called by the owner or admin of the edition. /** * @inheritdoc ISuperMinter */ function setPrice( address edition, uint8 tier, uint8 scheduleNum, uint96 price ) public onlyEditionOwnerOrAdmin(edition) { uint256 mintId = LibOps.packId(edition, tier, scheduleNum); MintData storage d = _getMintData(mintId); // If the tier is GA and the `mode` is `VERIFY_SIGNATURE`, we'll use `gaPrice[platform]`. if (tier == GA_TIER && d.mode != VERIFY_SIGNATURE) revert NotConfigurable(); d.price = price; emit PriceSet(edition, tier, scheduleNum, price); } /** * @inheritdoc ISuperMinter */ function setPaused( address edition, uint8 tier, uint8 scheduleNum, bool paused ) public onlyEditionOwnerOrAdmin(edition) { uint256 mintId = LibOps.packId(edition, tier, scheduleNum); MintData storage d = _getMintData(mintId); d.flags = LibOps.setFlagTo(d.flags, _MINT_PAUSED_FLAG, paused); emit PausedSet(edition, tier, scheduleNum, paused); } /** * @inheritdoc ISuperMinter */ function setTimeRange( address edition, uint8 tier, uint8 scheduleNum, uint32 startTime, uint32 endTime ) public onlyEditionOwnerOrAdmin(edition) { uint256 mintId = LibOps.packId(edition, tier, scheduleNum); MintData storage d = _getMintData(mintId); // For GA tier, `endTime` will always be `type(uint32).max`. if (tier == GA_TIER && endTime != type(uint32).max) revert NotConfigurable(); _validateTimeRange(startTime, endTime); d.startTime = startTime; d.endTime = endTime; emit TimeRangeSet(edition, tier, scheduleNum, startTime, endTime); } /** * @inheritdoc ISuperMinter */ function setStartTime( address edition, uint8 tier, uint8 scheduleNum, uint32 startTime ) public { uint256 mintId = LibOps.packId(edition, tier, scheduleNum); setTimeRange(edition, tier, scheduleNum, startTime, _mintData[mintId].endTime); } /** * @inheritdoc ISuperMinter */ function setAffiliateFee( address edition, uint8 tier, uint8 scheduleNum, uint16 bps ) public onlyEditionOwnerOrAdmin(edition) { uint256 mintId = LibOps.packId(edition, tier, scheduleNum); MintData storage d = _getMintData(mintId); _validateAffiliateFeeBPS(bps); d.affiliateFeeBPS = bps; emit AffiliateFeeSet(edition, tier, scheduleNum, bps); } /** * @inheritdoc ISuperMinter */ function setAffiliateMerkleRoot( address edition, uint8 tier, uint8 scheduleNum, bytes32 root ) public onlyEditionOwnerOrAdmin(edition) { uint256 mintId = LibOps.packId(edition, tier, scheduleNum); MintData storage d = _getMintData(mintId); d.affiliateMerkleRoot = root; emit AffiliateMerkleRootSet(edition, tier, scheduleNum, root); } /** * @inheritdoc ISuperMinter */ function setMaxMintablePerAccount( address edition, uint8 tier, uint8 scheduleNum, uint32 value ) public onlyEditionOwnerOrAdmin(edition) { uint256 mintId = LibOps.packId(edition, tier, scheduleNum); MintData storage d = _getMintData(mintId); // GA tier will have `type(uint32).max`. if (tier == GA_TIER) revert NotConfigurable(); // Signature mints will have `type(uint32).max`. if (d.mode == VERIFY_SIGNATURE) revert NotConfigurable(); _validateMaxMintablePerAccount(value); d.maxMintablePerAccount = value; emit MaxMintablePerAccountSet(edition, tier, scheduleNum, value); } /** * @inheritdoc ISuperMinter */ function setMaxMintable( address edition, uint8 tier, uint8 scheduleNum, uint32 value ) public onlyEditionOwnerOrAdmin(edition) { uint256 mintId = LibOps.packId(edition, tier, scheduleNum); MintData storage d = _getMintData(mintId); // We allow edits for GA tier, if the `mode` is not `DEFAULT`. if (tier == GA_TIER && d.mode == DEFAULT) revert NotConfigurable(); _validateMaxMintable(value); d.maxMintable = value; emit MaxMintableSet(edition, tier, scheduleNum, value); } /** * @inheritdoc ISuperMinter */ function setMerkleRoot( address edition, uint8 tier, uint8 scheduleNum, bytes32 merkleRoot ) public onlyEditionOwnerOrAdmin(edition) { uint256 mintId = LibOps.packId(edition, tier, scheduleNum); MintData storage d = _getMintData(mintId); if (d.mode != VERIFY_MERKLE) revert NotConfigurable(); _validateMerkleRoot(merkleRoot); d.merkleRoot = merkleRoot; emit MerkleRootSet(edition, tier, scheduleNum, merkleRoot); } /** * @inheritdoc ISuperMinter */ function setSigner( address edition, uint8 tier, uint8 scheduleNum, address signer ) public onlyEditionOwnerOrAdmin(edition) { uint256 mintId = LibOps.packId(edition, tier, scheduleNum); MintData storage d = _getMintData(mintId); if (d.mode != VERIFY_SIGNATURE) revert NotConfigurable(); _validateSigner(signer); bool usePlatformSigner = signer == address(1); d.flags = LibOps.setFlagTo(d.flags, _USE_PLATFORM_SIGNER_FLAG, usePlatformSigner); if (!usePlatformSigner) d.signer = signer; emit SignerSet(edition, tier, scheduleNum, signer); } // Withdrawal functions: // --------------------- // These functions can be called by anyone. /** * @inheritdoc ISuperMinter */ function withdrawForAffiliate(address affiliate) public { uint256 accrued = affiliateFeesAccrued[affiliate]; if (accrued != 0) { affiliateFeesAccrued[affiliate] = 0; SafeTransferLib.forceSafeTransferETH(affiliate, accrued); emit AffiliateFeesWithdrawn(affiliate, accrued); } } /** * @inheritdoc ISuperMinter */ function withdrawForPlatform(address platform) public { address recipient = platformFeeAddress[platform]; _validatePlatformFeeAddress(recipient); uint256 accrued = platformFeesAccrued[platform]; if (accrued != 0) { platformFeesAccrued[platform] = 0; SafeTransferLib.forceSafeTransferETH(recipient, accrued); emit PlatformFeesWithdrawn(platform, accrued); } } // Platform fee functions: // ----------------------- // These functions enable any caller to set their own platform fees. /** * @inheritdoc ISuperMinter */ function setPlatformFeeAddress(address recipient) public { address sender = LibMulticaller.sender(); _validatePlatformFeeAddress(recipient); platformFeeAddress[sender] = recipient; emit PlatformFeeAddressSet(sender, recipient); } /** * @inheritdoc ISuperMinter */ function setPlatformFeeConfig(uint8 tier, PlatformFeeConfig memory c) public { address sender = LibMulticaller.sender(); _validatePlatformFeeConfig(c); _platformFeeConfigs[LibOps.packId(sender, tier)] = c; emit PlatformFeeConfigSet(sender, tier, c); } /** * @inheritdoc ISuperMinter */ function setDefaultPlatformFeeConfig(PlatformFeeConfig memory c) public { address sender = LibMulticaller.sender(); _validatePlatformFeeConfig(c); _platformFeeConfigs[LibOps.packId(sender, _DEFAULT_FEE_CONFIG_INDEX)] = c; emit DefaultPlatformFeeConfigSet(sender, c); } /** * @inheritdoc ISuperMinter */ function setGAPrice(uint96 price) public { address sender = LibMulticaller.sender(); gaPrice[sender] = price; emit GAPriceSet(sender, price); } /** * @inheritdoc ISuperMinter */ function setPlatformSigner(address signer) public { address sender = LibMulticaller.sender(); platformSigner[sender] = signer; emit PlatformSignerSet(sender, signer); } // Misc functions: // --------------- /** * @dev For calldata compression. */ fallback() external payable { LibZip.cdFallback(); } /** * @dev For calldata compression. */ receive() external payable { LibZip.cdFallback(); } // ============================================================= // PUBLIC / EXTERNAL VIEW FUNCTIONS // ============================================================= /** * @inheritdoc ISuperMinter */ function computeMintToDigest(MintTo calldata p) public view returns (bytes32) { // prettier-ignore return _hashTypedData(keccak256(abi.encode( MINT_TO_TYPEHASH, p.edition, p.tier, p.scheduleNum, p.to, p.signedQuantity, p.signedClaimTicket, p.signedPrice, p.signedDeadline, p.affiliate ))); } /** * @inheritdoc ISuperMinter */ function totalPriceAndFees( address edition, uint8 tier, uint8 scheduleNum, uint32 quantity ) public view returns (TotalPriceAndFees memory) { return totalPriceAndFeesWithSignedPrice(edition, tier, scheduleNum, quantity, 0); } /** * @inheritdoc ISuperMinter */ function totalPriceAndFeesWithSignedPrice( address edition, uint8 tier, uint8 scheduleNum, uint32 quantity, uint96 signedPrice ) public view returns (TotalPriceAndFees memory) { uint256 mintId = LibOps.packId(edition, tier, scheduleNum); return _totalPriceAndFees(tier, _getMintData(mintId), quantity, signedPrice); } /** * @inheritdoc ISuperMinter */ function nextScheduleNum(address edition, uint8 tier) public view returns (uint8) { return _mintData[LibOps.packId(edition, tier, 0)].nextScheduleNum; } /** * @inheritdoc ISuperMinter */ function numberMinted( address edition, uint8 tier, uint8 scheduleNum, address collector ) external view returns (uint32) { uint256 mintId = LibOps.packId(edition, tier, scheduleNum); return _numberMinted[collector].get(mintId); } /** * @inheritdoc ISuperMinter */ function isAffiliatedWithProof( address edition, uint8 tier, uint8 scheduleNum, address affiliate, bytes32[] calldata affiliateProof ) public view virtual returns (bool) { uint256 mintId = LibOps.packId(edition, tier, scheduleNum); return _isAffiliatedWithProof(_getMintData(mintId), affiliate, affiliateProof); } /** * @inheritdoc ISuperMinter */ function isAffiliated( address edition, uint8 tier, uint8 scheduleNum, address affiliate ) public view virtual returns (bool) { return isAffiliatedWithProof(edition, tier, scheduleNum, affiliate, MerkleProofLib.emptyProof()); } /** * @inheritdoc ISuperMinter */ function checkClaimTickets( address edition, uint8 tier, uint8 scheduleNum, uint32[] calldata claimTickets ) public view returns (bool[] memory claimed) { uint256 mintId = LibOps.packId(edition, tier, scheduleNum); LibBitmap.Bitmap storage bitmap = _claimsBitmaps[mintId]; claimed = new bool[](claimTickets.length); unchecked { for (uint256 i; i != claimTickets.length; i++) { claimed[i] = bitmap.get(claimTickets[i]); } } } /** * @inheritdoc ISuperMinter */ function platformFeeConfig(address platform, uint8 tier) public view returns (PlatformFeeConfig memory) { return _platformFeeConfigs[LibOps.packId(platform, tier)]; } /** * @inheritdoc ISuperMinter */ function defaultPlatformFeeConfig(address platform) public view returns (PlatformFeeConfig memory) { return _platformFeeConfigs[LibOps.packId(platform, _DEFAULT_FEE_CONFIG_INDEX)]; } /** * @inheritdoc ISuperMinter */ function effectivePlatformFeeConfig(address platform, uint8 tier) public view returns (PlatformFeeConfig memory) { PlatformFeeConfig memory c = _platformFeeConfigs[LibOps.packId(platform, tier)]; if (!c.active) c = _platformFeeConfigs[LibOps.packId(platform, _DEFAULT_FEE_CONFIG_INDEX)]; if (!c.active) delete c; // Set all values to zero. return c; } /** * @inheritdoc ISuperMinter */ function mintInfoList(address edition) public view returns (MintInfo[] memory a) { unchecked { MintData storage editionHead = _mintData[LibOps.packId(edition, 0)]; uint256 n = editionHead.numMintData; // Linked-list length. uint16 p = editionHead.head; // Current linked-list pointer. a = new MintInfo[](n); // Traverse the linked-list and fill the array in reverse. // Front: earliest added mint schedule. Back: latest added mint schedule. while (n != 0) { MintData storage d = _mintData[LibOps.packId(edition, p)]; a[--n] = mintInfo(edition, uint8(p >> 8), uint8(p)); p = d.next; } } } /** * @inheritdoc ISuperMinter */ function mintInfo( address edition, uint8 tier, uint8 scheduleNum ) public view returns (MintInfo memory info) { uint256 mintId = LibOps.packId(edition, tier, scheduleNum); MintData storage d = _getMintData(mintId); info.edition = edition; info.tier = tier; info.scheduleNum = scheduleNum; info.platform = d.platform; info.price = tier == GA_TIER && d.mode != VERIFY_SIGNATURE ? gaPrice[d.platform] : d.price; info.startTime = d.startTime; info.endTime = d.endTime; info.maxMintablePerAccount = d.maxMintablePerAccount; info.maxMintable = d.maxMintable; info.minted = d.minted; info.affiliateFeeBPS = d.affiliateFeeBPS; info.mode = d.mode; info.paused = _isPaused(d); info.affiliateMerkleRoot = d.affiliateMerkleRoot; info.merkleRoot = d.merkleRoot; info.signer = _effectiveSigner(d); info.usePlatformSigner = _usePlatformSigner(d); } /** * @inheritdoc ISuperMinter */ function name() external pure returns (string memory name_) { (name_, ) = _domainNameAndVersion(); } /** * @inheritdoc ISuperMinter */ function version() external pure returns (string memory version_) { (, version_) = _domainNameAndVersion(); } /** * @inheritdoc IERC165 */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return LibOps.or(interfaceId == type(ISuperMinter).interfaceId, interfaceId == this.supportsInterface.selector); } // ============================================================= // INTERNAL / PRIVATE HELPERS // ============================================================= // Validations: // ------------ /** * @dev Guards a function to make it callable only by the edition's owner or admin. * @param edition The edition address. */ modifier onlyEditionOwnerOrAdmin(address edition) { _requireOnlyEditionOwnerOrAdmin(edition); _; } /** * @dev Requires that the caller is the owner or admin of `edition`. * @param edition The edition address. */ function _requireOnlyEditionOwnerOrAdmin(address edition) internal view { address sender = LibMulticaller.sender(); if (sender != OwnableRoles(edition).owner()) if (!OwnableRoles(edition).hasAnyRole(sender, LibOps.ADMIN_ROLE)) LibOps.revertUnauthorized(); } /** * @dev Validates that `startTime <= endTime`. * @param startTime The start time of the mint. * @param endTime The end time of the mint. */ function _validateTimeRange(uint32 startTime, uint32 endTime) internal pure { if (startTime > endTime) revert InvalidTimeRange(); } /** * @dev Validates that the max mintable amount per account is not zero. * @param value The max mintable amount. */ function _validateMaxMintablePerAccount(uint32 value) internal pure { if (value == 0) revert MaxMintablePerAccountIsZero(); } /** * @dev Validates that the max mintable per schedule. * @param value The max mintable amount. */ function _validateMaxMintable(uint32 value) internal pure { if (value == 0) revert MaxMintableIsZero(); } /** * @dev Validates that the Merkle root is not empty. * @param merkleRoot The Merkle root. */ function _validateMerkleRoot(bytes32 merkleRoot) internal pure { if (merkleRoot == bytes32(0)) revert MerkleRootIsEmpty(); } /** * @dev Validates that the signer is not the zero address. * @param signer The signer. */ function _validateSigner(address signer) internal pure { if (signer == address(0)) revert SignerIsZeroAddress(); } /** * @dev Validates that the affiliate fee BPS does not exceed the max threshold. * @param bps The affiliate fee BPS. */ function _validateAffiliateFeeBPS(uint16 bps) internal pure { if (bps > MAX_AFFILIATE_FEE_BPS) revert InvalidAffiliateFeeBPS(); } /** * @dev Validates the platform fee configuration. * @param c The platform fee configuration. */ function _validatePlatformFeeConfig(PlatformFeeConfig memory c) internal pure { if ( LibOps.or( c.perTxFlat > MAX_PLATFORM_PER_TX_FLAT_FEE, c.perMintFlat > MAX_PLATFORM_PER_MINT_FLAT_FEE, c.perMintBPS > MAX_PLATFORM_PER_MINT_FEE_BPS ) ) revert InvalidPlatformFeeConfig(); } /** * @dev Validates that the platform fee address is not the zero address. * @param a The platform fee address. */ function _validatePlatformFeeAddress(address a) internal pure { if (a == address(0)) revert PlatformFeeAddressIsZero(); } // EIP-712: // -------- /** * @dev Override for EIP-712. * @return name_ The EIP-712 name. * @return version_ The EIP-712 version. */ function _domainNameAndVersion() internal pure virtual override returns (string memory name_, string memory version_) { name_ = "SuperMinter"; version_ = "1"; } // Minting: // -------- /** * @dev Increments the number minted in the mint and the number minted by the collector. * @param mode The mint mode. * @param d The mint data storage pointer. * @param p The mint-to parameters. */ function _incrementMinted( uint8 mode, MintData storage d, MintTo calldata p ) internal { unchecked { // Increment the number minted in the mint. uint256 n = uint256(d.minted) + uint256(p.quantity); // The next `minted`. if (n > d.maxMintable) revert ExceedsMintSupply(); d.minted = uint32(n); // Increment the number minted by the collector. uint256 mintId = LibOps.packId(p.edition, p.tier, p.scheduleNum); if (mode == VERIFY_MERKLE) { LibMap.Uint32Map storage m = _numberMinted[p.allowlisted]; n = uint256(m.get(mintId)) + uint256(p.quantity); // Check that `n` does not exceed either the default limit, // or the limit in the Merkle leaf if a non-zero value is provided. if (LibOps.or(n > d.maxMintablePerAccount, n > p.allowlistedQuantity)) revert ExceedsMaxPerAccount(); m.set(mintId, uint32(n)); } else { LibMap.Uint32Map storage m = _numberMinted[p.to]; n = uint256(m.get(mintId)) + uint256(p.quantity); if (n > d.maxMintablePerAccount) revert ExceedsMaxPerAccount(); m.set(mintId, uint32(n)); } } } /** * @dev Verify the signature, and mark the signed claim ticket as claimed. * @param d The mint data storage pointer. * @param p The mint-to parameters. */ function _verifyAndClaimSignature(MintData storage d, MintTo calldata p) internal { if (p.quantity > p.signedQuantity) revert ExceedsSignedQuantity(); address signer = _effectiveSigner(d); if (!SignatureCheckerLib.isValidSignatureNowCalldata(signer, computeMintToDigest(p), p.signature)) revert InvalidSignature(); if (block.timestamp > p.signedDeadline) revert SignatureExpired(); uint256 mintId = LibOps.packId(p.edition, p.tier, p.scheduleNum); if (!_claimsBitmaps[mintId].toggle(p.signedClaimTicket)) revert SignatureAlreadyUsed(); } /** * @dev Verify the Merkle proof. * @param d The mint data storage pointer. * @param p The mint-to parameters. */ function _verifyMerkle(MintData storage d, MintTo calldata p) internal view { uint32 allowlistedQuantity = p.allowlistedQuantity; address allowlisted = p.allowlisted; // Revert if `allowlisted` is the zero address to prevent libraries // that fill up partial Merkle trees with empty leafs from screwing things up. if (allowlisted == address(0)) revert InvalidMerkleProof(); // If `allowlistedQuantity` is the max limit, we've got to check two cases for backwards compatibility. if (allowlistedQuantity == type(uint32).max) { // Revert if neither `keccak256(abi.encodePacked(allowlisted))` nor // `keccak256(abi.encodePacked(allowlisted, uint32(0)))` are in the Merkle tree. if ( !p.allowlistProof.verifyCalldata(d.merkleRoot, _leaf(allowlisted)) && !p.allowlistProof.verifyCalldata(d.merkleRoot, _leaf(allowlisted, type(uint32).max)) ) revert InvalidMerkleProof(); } else { // Revert if `keccak256(abi.encodePacked(allowlisted, uint32(allowlistedQuantity)))` // is not in the Merkle tree. if (!p.allowlistProof.verifyCalldata(d.merkleRoot, _leaf(allowlisted, allowlistedQuantity))) revert InvalidMerkleProof(); } // To mint, either the sender or `to` must be equal to `allowlisted`, address sender = LibMulticaller.sender(); if (!LibOps.or(sender == allowlisted, p.to == allowlisted)) { // or the sender must be a delegate of `allowlisted`. if (!DelegateCashLib.checkDelegateForAll(sender, allowlisted)) revert CallerNotDelegated(); } } /** * @dev Returns the total price and fees for the mint. * @param tier The tier. * @param d The mint data storage pointer. * @param quantity How many tokens to mint. * @param signedPrice The signed price. Only for `VERIFY_SIGNATURE`. * @return f A struct containing the total price and fees. */ function _totalPriceAndFees( uint8 tier, MintData storage d, uint32 quantity, uint96 signedPrice ) internal view returns (TotalPriceAndFees memory f) { unchecked { PlatformFeeConfig memory c = effectivePlatformFeeConfig(d.platform, tier); // The actual unit price per token. uint256 unitPrice; // For signature mints, even if it is GA tier, we will use the signed price. if (d.mode == VERIFY_SIGNATURE) { if (signedPrice < d.price) revert SignedPriceTooLow(); // Enforce the price floor. unitPrice = signedPrice; } else if (tier == GA_TIER) { unitPrice = gaPrice[d.platform]; // Else if GA tier, use `gaPrice[platform]`. } else { unitPrice = d.price; // Else, use the `price`. } f.unitPrice = unitPrice; // The artist will receive the remaining after all BPS fees are deducted from sub total. // The minter will have to pay the sub total plus any flat fees. f.subTotal = unitPrice * uint256(quantity); // Sum the total flat fees for mints, and the transaction flat fee. f.platformTxFlatFee = c.perTxFlat; f.platformMintFlatFee = c.perMintFlat * uint256(quantity); f.platformFlatFee = f.platformMintFlatFee + f.platformTxFlatFee; // BPS fees are to be deducted from the sub total. f.platformMintBPSFee = LibOps.rawMulDiv(f.subTotal, c.perMintBPS, BPS_DENOMINATOR); // The platform fee includes BPS fees deducted from sub total, // and flat fees added to sub total. f.platformFee = f.platformMintBPSFee + f.platformFlatFee; // Affiliate fee is to be deducted from the sub total. // Will be conditionally set to zero during mint if not affiliated. f.affiliateFee = LibOps.rawMulDiv(f.subTotal, d.affiliateFeeBPS, BPS_DENOMINATOR); // The total is the final value which the minter has to pay. It includes all fees. f.total = f.subTotal + f.platformFlatFee; } } /** * @dev Returns whether the affiliate is affiliated for the mint * @param d The mint data storage pointer. * @param affiliate The affiliate address. * @param affiliateProof The Merkle proof for the affiliate. * @return The result. */ function _isAffiliatedWithProof( MintData storage d, address affiliate, bytes32[] calldata affiliateProof ) internal view virtual returns (bool) { bytes32 root = d.affiliateMerkleRoot; // If the root is empty, then use the default logic. if (root == bytes32(0)) return affiliate != address(0); // Otherwise, check if the affiliate is in the Merkle tree. // The check that that affiliate is not a zero address is to prevent libraries // that fill up partial Merkle trees with empty leafs from screwing things up. return LibOps.and(affiliate != address(0), affiliateProof.verifyCalldata(root, _leaf(affiliate))); } // Utilities: // ---------- /** * @dev Equivalent to `keccak256(abi.encodePacked(allowlisted))`. * @param allowlisted The allowlisted address. * @return result The leaf in the Merkle tree. */ function _leaf(address allowlisted) internal pure returns (bytes32 result) { assembly { mstore(0x00, allowlisted) result := keccak256(0x0c, 0x14) } } /** * @dev Equivalent to `keccak256(abi.encodePacked(allowlisted, allowlistedQuantity))`. * @param allowlisted The allowlisted address. * @param allowlistedQuantity Number of mints allowlisted. * @return result The leaf in the Merkle tree. */ function _leaf(address allowlisted, uint32 allowlistedQuantity) internal pure returns (bytes32 result) { assembly { mstore(0x04, allowlistedQuantity) mstore(0x00, allowlisted) result := keccak256(0x0c, 0x18) } } /** * @dev Retrieves the mint data from storage, reverting if the mint does not exist. * @param mintId The mint ID. * @return d The storage pointer to the mint data. */ function _getMintData(uint256 mintId) internal view returns (MintData storage d) { d = _mintData[mintId]; if (d.flags & _MINT_CREATED_FLAG == 0) revert MintDoesNotExist(); } /** * @dev Returns whether the mint is paused. * @param d The storage pointer to the mint data. * @return Whether the mint is paused. */ function _isPaused(MintData storage d) internal view returns (bool) { return d.flags & _MINT_PAUSED_FLAG != 0; } /** * @dev Returns the effective signer. * @param d The storage pointer to the mint data. * @return The effective signer. */ function _effectiveSigner(MintData storage d) internal view returns (address) { return _usePlatformSigner(d) ? platformSigner[d.platform] : d.signer; } /** * @dev Returns whether the platform signer is to be used instead. * @param d The storage pointer to the mint data. * @return Whether the platform signer is to be used instead. */ function _usePlatformSigner(MintData storage d) internal view returns (bool) { return d.flags & _USE_PLATFORM_SIGNER_FLAG != 0; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import {Ownable} from "./Ownable.sol"; /// @notice Simple single owner and multiroles authorization mixin. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol) /// @dev While the ownable portion follows [EIP-173](https://eips.ethereum.org/EIPS/eip-173) /// for compatibility, the nomenclature for the 2-step ownership handover and roles /// may be unique to this codebase. abstract contract OwnableRoles is Ownable { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* EVENTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The `user`'s roles is updated to `roles`. /// Each bit of `roles` represents whether the role is set. event RolesUpdated(address indexed user, uint256 indexed roles); /// @dev `keccak256(bytes("RolesUpdated(address,uint256)"))`. uint256 private constant _ROLES_UPDATED_EVENT_SIGNATURE = 0x715ad5ce61fc9595c7b415289d59cf203f23a94fa06f04af7e489a0a76e1fe26; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* STORAGE */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The role slot of `user` is given by: /// ``` /// mstore(0x00, or(shl(96, user), _ROLE_SLOT_SEED)) /// let roleSlot := keccak256(0x00, 0x20) /// ``` /// This automatically ignores the upper bits of the `user` in case /// they are not clean, as well as keep the `keccak256` under 32-bytes. /// /// Note: This is equal to `_OWNER_SLOT_NOT` in for gas efficiency. uint256 private constant _ROLE_SLOT_SEED = 0x8b78c6d8; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Overwrite the roles directly without authorization guard. function _setRoles(address user, uint256 roles) internal virtual { /// @solidity memory-safe-assembly assembly { mstore(0x0c, _ROLE_SLOT_SEED) mstore(0x00, user) // Store the new value. sstore(keccak256(0x0c, 0x20), roles) // Emit the {RolesUpdated} event. log3(0, 0, _ROLES_UPDATED_EVENT_SIGNATURE, shr(96, mload(0x0c)), roles) } } /// @dev Updates the roles directly without authorization guard. /// If `on` is true, each set bit of `roles` will be turned on, /// otherwise, each set bit of `roles` will be turned off. function _updateRoles(address user, uint256 roles, bool on) internal virtual { /// @solidity memory-safe-assembly assembly { mstore(0x0c, _ROLE_SLOT_SEED) mstore(0x00, user) let roleSlot := keccak256(0x0c, 0x20) // Load the current value. let current := sload(roleSlot) // Compute the updated roles if `on` is true. let updated := or(current, roles) // Compute the updated roles if `on` is false. // Use `and` to compute the intersection of `current` and `roles`, // `xor` it with `current` to flip the bits in the intersection. if iszero(on) { updated := xor(current, and(current, roles)) } // Then, store the new value. sstore(roleSlot, updated) // Emit the {RolesUpdated} event. log3(0, 0, _ROLES_UPDATED_EVENT_SIGNATURE, shr(96, mload(0x0c)), updated) } } /// @dev Grants the roles directly without authorization guard. /// Each bit of `roles` represents the role to turn on. function _grantRoles(address user, uint256 roles) internal virtual { _updateRoles(user, roles, true); } /// @dev Removes the roles directly without authorization guard. /// Each bit of `roles` represents the role to turn off. function _removeRoles(address user, uint256 roles) internal virtual { _updateRoles(user, roles, false); } /// @dev Throws if the sender does not have any of the `roles`. function _checkRoles(uint256 roles) internal view virtual { /// @solidity memory-safe-assembly assembly { // Compute the role slot. mstore(0x0c, _ROLE_SLOT_SEED) mstore(0x00, caller()) // Load the stored value, and if the `and` intersection // of the value and `roles` is zero, revert. if iszero(and(sload(keccak256(0x0c, 0x20)), roles)) { mstore(0x00, 0x82b42900) // `Unauthorized()`. revert(0x1c, 0x04) } } } /// @dev Throws if the sender is not the owner, /// and does not have any of the `roles`. /// Checks for ownership first, then lazily checks for roles. function _checkOwnerOrRoles(uint256 roles) internal view virtual { /// @solidity memory-safe-assembly assembly { // If the caller is not the stored owner. // Note: `_ROLE_SLOT_SEED` is equal to `_OWNER_SLOT_NOT`. if iszero(eq(caller(), sload(not(_ROLE_SLOT_SEED)))) { // Compute the role slot. mstore(0x0c, _ROLE_SLOT_SEED) mstore(0x00, caller()) // Load the stored value, and if the `and` intersection // of the value and `roles` is zero, revert. if iszero(and(sload(keccak256(0x0c, 0x20)), roles)) { mstore(0x00, 0x82b42900) // `Unauthorized()`. revert(0x1c, 0x04) } } } } /// @dev Throws if the sender does not have any of the `roles`, /// and is not the owner. /// Checks for roles first, then lazily checks for ownership. function _checkRolesOrOwner(uint256 roles) internal view virtual { /// @solidity memory-safe-assembly assembly { // Compute the role slot. mstore(0x0c, _ROLE_SLOT_SEED) mstore(0x00, caller()) // Load the stored value, and if the `and` intersection // of the value and `roles` is zero, revert. if iszero(and(sload(keccak256(0x0c, 0x20)), roles)) { // If the caller is not the stored owner. // Note: `_ROLE_SLOT_SEED` is equal to `_OWNER_SLOT_NOT`. if iszero(eq(caller(), sload(not(_ROLE_SLOT_SEED)))) { mstore(0x00, 0x82b42900) // `Unauthorized()`. revert(0x1c, 0x04) } } } } /// @dev Convenience function to return a `roles` bitmap from an array of `ordinals`. /// This is meant for frontends like Etherscan, and is therefore not fully optimized. /// Not recommended to be called on-chain. /// Made internal to conserve bytecode. Wrap it in a public function if needed. function _rolesFromOrdinals(uint8[] memory ordinals) internal pure returns (uint256 roles) { /// @solidity memory-safe-assembly assembly { for { let i := shl(5, mload(ordinals)) } i { i := sub(i, 0x20) } { // We don't need to mask the values of `ordinals`, as Solidity // cleans dirty upper bits when storing variables into memory. roles := or(shl(mload(add(ordinals, i)), 1), roles) } } } /// @dev Convenience function to return an array of `ordinals` from the `roles` bitmap. /// This is meant for frontends like Etherscan, and is therefore not fully optimized. /// Not recommended to be called on-chain. /// Made internal to conserve bytecode. Wrap it in a public function if needed. function _ordinalsFromRoles(uint256 roles) internal pure returns (uint8[] memory ordinals) { /// @solidity memory-safe-assembly assembly { // Grab the pointer to the free memory. ordinals := mload(0x40) let ptr := add(ordinals, 0x20) let o := 0 // The absence of lookup tables, De Bruijn, etc., here is intentional for // smaller bytecode, as this function is not meant to be called on-chain. for { let t := roles } 1 {} { mstore(ptr, o) // `shr` 5 is equivalent to multiplying by 0x20. // Push back into the ordinals array if the bit is set. ptr := add(ptr, shl(5, and(t, 1))) o := add(o, 1) t := shr(o, roles) if iszero(t) { break } } // Store the length of `ordinals`. mstore(ordinals, shr(5, sub(ptr, add(ordinals, 0x20)))) // Allocate the memory. mstore(0x40, ptr) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* PUBLIC UPDATE FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Allows the owner to grant `user` `roles`. /// If the `user` already has a role, then it will be an no-op for the role. function grantRoles(address user, uint256 roles) public payable virtual onlyOwner { _grantRoles(user, roles); } /// @dev Allows the owner to remove `user` `roles`. /// If the `user` does not have a role, then it will be an no-op for the role. function revokeRoles(address user, uint256 roles) public payable virtual onlyOwner { _removeRoles(user, roles); } /// @dev Allow the caller to remove their own roles. /// If the caller does not have a role, then it will be an no-op for the role. function renounceRoles(uint256 roles) public payable virtual { _removeRoles(msg.sender, roles); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* PUBLIC READ FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the roles of `user`. function rolesOf(address user) public view virtual returns (uint256 roles) { /// @solidity memory-safe-assembly assembly { // Compute the role slot. mstore(0x0c, _ROLE_SLOT_SEED) mstore(0x00, user) // Load the stored value. roles := sload(keccak256(0x0c, 0x20)) } } /// @dev Returns whether `user` has any of `roles`. function hasAnyRole(address user, uint256 roles) public view virtual returns (bool) { return rolesOf(user) & roles != 0; } /// @dev Returns whether `user` has all of `roles`. function hasAllRoles(address user, uint256 roles) public view virtual returns (bool) { return rolesOf(user) & roles == roles; } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* MODIFIERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Marks a function as only callable by an account with `roles`. modifier onlyRoles(uint256 roles) virtual { _checkRoles(roles); _; } /// @dev Marks a function as only callable by the owner or by an account /// with `roles`. Checks for ownership first, then lazily checks for roles. modifier onlyOwnerOrRoles(uint256 roles) virtual { _checkOwnerOrRoles(roles); _; } /// @dev Marks a function as only callable by an account with `roles` /// or the owner. Checks for roles first, then lazily checks for ownership. modifier onlyRolesOrOwner(uint256 roles) virtual { _checkRolesOrOwner(roles); _; } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ROLE CONSTANTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ // IYKYK uint256 internal constant _ROLE_0 = 1 << 0; uint256 internal constant _ROLE_1 = 1 << 1; uint256 internal constant _ROLE_2 = 1 << 2; uint256 internal constant _ROLE_3 = 1 << 3; uint256 internal constant _ROLE_4 = 1 << 4; uint256 internal constant _ROLE_5 = 1 << 5; uint256 internal constant _ROLE_6 = 1 << 6; uint256 internal constant _ROLE_7 = 1 << 7; uint256 internal constant _ROLE_8 = 1 << 8; uint256 internal constant _ROLE_9 = 1 << 9; uint256 internal constant _ROLE_10 = 1 << 10; uint256 internal constant _ROLE_11 = 1 << 11; uint256 internal constant _ROLE_12 = 1 << 12; uint256 internal constant _ROLE_13 = 1 << 13; uint256 internal constant _ROLE_14 = 1 << 14; uint256 internal constant _ROLE_15 = 1 << 15; uint256 internal constant _ROLE_16 = 1 << 16; uint256 internal constant _ROLE_17 = 1 << 17; uint256 internal constant _ROLE_18 = 1 << 18; uint256 internal constant _ROLE_19 = 1 << 19; uint256 internal constant _ROLE_20 = 1 << 20; uint256 internal constant _ROLE_21 = 1 << 21; uint256 internal constant _ROLE_22 = 1 << 22; uint256 internal constant _ROLE_23 = 1 << 23; uint256 internal constant _ROLE_24 = 1 << 24; uint256 internal constant _ROLE_25 = 1 << 25; uint256 internal constant _ROLE_26 = 1 << 26; uint256 internal constant _ROLE_27 = 1 << 27; uint256 internal constant _ROLE_28 = 1 << 28; uint256 internal constant _ROLE_29 = 1 << 29; uint256 internal constant _ROLE_30 = 1 << 30; uint256 internal constant _ROLE_31 = 1 << 31; uint256 internal constant _ROLE_32 = 1 << 32; uint256 internal constant _ROLE_33 = 1 << 33; uint256 internal constant _ROLE_34 = 1 << 34; uint256 internal constant _ROLE_35 = 1 << 35; uint256 internal constant _ROLE_36 = 1 << 36; uint256 internal constant _ROLE_37 = 1 << 37; uint256 internal constant _ROLE_38 = 1 << 38; uint256 internal constant _ROLE_39 = 1 << 39; uint256 internal constant _ROLE_40 = 1 << 40; uint256 internal constant _ROLE_41 = 1 << 41; uint256 internal constant _ROLE_42 = 1 << 42; uint256 internal constant _ROLE_43 = 1 << 43; uint256 internal constant _ROLE_44 = 1 << 44; uint256 internal constant _ROLE_45 = 1 << 45; uint256 internal constant _ROLE_46 = 1 << 46; uint256 internal constant _ROLE_47 = 1 << 47; uint256 internal constant _ROLE_48 = 1 << 48; uint256 internal constant _ROLE_49 = 1 << 49; uint256 internal constant _ROLE_50 = 1 << 50; uint256 internal constant _ROLE_51 = 1 << 51; uint256 internal constant _ROLE_52 = 1 << 52; uint256 internal constant _ROLE_53 = 1 << 53; uint256 internal constant _ROLE_54 = 1 << 54; uint256 internal constant _ROLE_55 = 1 << 55; uint256 internal constant _ROLE_56 = 1 << 56; uint256 internal constant _ROLE_57 = 1 << 57; uint256 internal constant _ROLE_58 = 1 << 58; uint256 internal constant _ROLE_59 = 1 << 59; uint256 internal constant _ROLE_60 = 1 << 60; uint256 internal constant _ROLE_61 = 1 << 61; uint256 internal constant _ROLE_62 = 1 << 62; uint256 internal constant _ROLE_63 = 1 << 63; uint256 internal constant _ROLE_64 = 1 << 64; uint256 internal constant _ROLE_65 = 1 << 65; uint256 internal constant _ROLE_66 = 1 << 66; uint256 internal constant _ROLE_67 = 1 << 67; uint256 internal constant _ROLE_68 = 1 << 68; uint256 internal constant _ROLE_69 = 1 << 69; uint256 internal constant _ROLE_70 = 1 << 70; uint256 internal constant _ROLE_71 = 1 << 71; uint256 internal constant _ROLE_72 = 1 << 72; uint256 internal constant _ROLE_73 = 1 << 73; uint256 internal constant _ROLE_74 = 1 << 74; uint256 internal constant _ROLE_75 = 1 << 75; uint256 internal constant _ROLE_76 = 1 << 76; uint256 internal constant _ROLE_77 = 1 << 77; uint256 internal constant _ROLE_78 = 1 << 78; uint256 internal constant _ROLE_79 = 1 << 79; uint256 internal constant _ROLE_80 = 1 << 80; uint256 internal constant _ROLE_81 = 1 << 81; uint256 internal constant _ROLE_82 = 1 << 82; uint256 internal constant _ROLE_83 = 1 << 83; uint256 internal constant _ROLE_84 = 1 << 84; uint256 internal constant _ROLE_85 = 1 << 85; uint256 internal constant _ROLE_86 = 1 << 86; uint256 internal constant _ROLE_87 = 1 << 87; uint256 internal constant _ROLE_88 = 1 << 88; uint256 internal constant _ROLE_89 = 1 << 89; uint256 internal constant _ROLE_90 = 1 << 90; uint256 internal constant _ROLE_91 = 1 << 91; uint256 internal constant _ROLE_92 = 1 << 92; uint256 internal constant _ROLE_93 = 1 << 93; uint256 internal constant _ROLE_94 = 1 << 94; uint256 internal constant _ROLE_95 = 1 << 95; uint256 internal constant _ROLE_96 = 1 << 96; uint256 internal constant _ROLE_97 = 1 << 97; uint256 internal constant _ROLE_98 = 1 << 98; uint256 internal constant _ROLE_99 = 1 << 99; uint256 internal constant _ROLE_100 = 1 << 100; uint256 internal constant _ROLE_101 = 1 << 101; uint256 internal constant _ROLE_102 = 1 << 102; uint256 internal constant _ROLE_103 = 1 << 103; uint256 internal constant _ROLE_104 = 1 << 104; uint256 internal constant _ROLE_105 = 1 << 105; uint256 internal constant _ROLE_106 = 1 << 106; uint256 internal constant _ROLE_107 = 1 << 107; uint256 internal constant _ROLE_108 = 1 << 108; uint256 internal constant _ROLE_109 = 1 << 109; uint256 internal constant _ROLE_110 = 1 << 110; uint256 internal constant _ROLE_111 = 1 << 111; uint256 internal constant _ROLE_112 = 1 << 112; uint256 internal constant _ROLE_113 = 1 << 113; uint256 internal constant _ROLE_114 = 1 << 114; uint256 internal constant _ROLE_115 = 1 << 115; uint256 internal constant _ROLE_116 = 1 << 116; uint256 internal constant _ROLE_117 = 1 << 117; uint256 internal constant _ROLE_118 = 1 << 118; uint256 internal constant _ROLE_119 = 1 << 119; uint256 internal constant _ROLE_120 = 1 << 120; uint256 internal constant _ROLE_121 = 1 << 121; uint256 internal constant _ROLE_122 = 1 << 122; uint256 internal constant _ROLE_123 = 1 << 123; uint256 internal constant _ROLE_124 = 1 << 124; uint256 internal constant _ROLE_125 = 1 << 125; uint256 internal constant _ROLE_126 = 1 << 126; uint256 internal constant _ROLE_127 = 1 << 127; uint256 internal constant _ROLE_128 = 1 << 128; uint256 internal constant _ROLE_129 = 1 << 129; uint256 internal constant _ROLE_130 = 1 << 130; uint256 internal constant _ROLE_131 = 1 << 131; uint256 internal constant _ROLE_132 = 1 << 132; uint256 internal constant _ROLE_133 = 1 << 133; uint256 internal constant _ROLE_134 = 1 << 134; uint256 internal constant _ROLE_135 = 1 << 135; uint256 internal constant _ROLE_136 = 1 << 136; uint256 internal constant _ROLE_137 = 1 << 137; uint256 internal constant _ROLE_138 = 1 << 138; uint256 internal constant _ROLE_139 = 1 << 139; uint256 internal constant _ROLE_140 = 1 << 140; uint256 internal constant _ROLE_141 = 1 << 141; uint256 internal constant _ROLE_142 = 1 << 142; uint256 internal constant _ROLE_143 = 1 << 143; uint256 internal constant _ROLE_144 = 1 << 144; uint256 internal constant _ROLE_145 = 1 << 145; uint256 internal constant _ROLE_146 = 1 << 146; uint256 internal constant _ROLE_147 = 1 << 147; uint256 internal constant _ROLE_148 = 1 << 148; uint256 internal constant _ROLE_149 = 1 << 149; uint256 internal constant _ROLE_150 = 1 << 150; uint256 internal constant _ROLE_151 = 1 << 151; uint256 internal constant _ROLE_152 = 1 << 152; uint256 internal constant _ROLE_153 = 1 << 153; uint256 internal constant _ROLE_154 = 1 << 154; uint256 internal constant _ROLE_155 = 1 << 155; uint256 internal constant _ROLE_156 = 1 << 156; uint256 internal constant _ROLE_157 = 1 << 157; uint256 internal constant _ROLE_158 = 1 << 158; uint256 internal constant _ROLE_159 = 1 << 159; uint256 internal constant _ROLE_160 = 1 << 160; uint256 internal constant _ROLE_161 = 1 << 161; uint256 internal constant _ROLE_162 = 1 << 162; uint256 internal constant _ROLE_163 = 1 << 163; uint256 internal constant _ROLE_164 = 1 << 164; uint256 internal constant _ROLE_165 = 1 << 165; uint256 internal constant _ROLE_166 = 1 << 166; uint256 internal constant _ROLE_167 = 1 << 167; uint256 internal constant _ROLE_168 = 1 << 168; uint256 internal constant _ROLE_169 = 1 << 169; uint256 internal constant _ROLE_170 = 1 << 170; uint256 internal constant _ROLE_171 = 1 << 171; uint256 internal constant _ROLE_172 = 1 << 172; uint256 internal constant _ROLE_173 = 1 << 173; uint256 internal constant _ROLE_174 = 1 << 174; uint256 internal constant _ROLE_175 = 1 << 175; uint256 internal constant _ROLE_176 = 1 << 176; uint256 internal constant _ROLE_177 = 1 << 177; uint256 internal constant _ROLE_178 = 1 << 178; uint256 internal constant _ROLE_179 = 1 << 179; uint256 internal constant _ROLE_180 = 1 << 180; uint256 internal constant _ROLE_181 = 1 << 181; uint256 internal constant _ROLE_182 = 1 << 182; uint256 internal constant _ROLE_183 = 1 << 183; uint256 internal constant _ROLE_184 = 1 << 184; uint256 internal constant _ROLE_185 = 1 << 185; uint256 internal constant _ROLE_186 = 1 << 186; uint256 internal constant _ROLE_187 = 1 << 187; uint256 internal constant _ROLE_188 = 1 << 188; uint256 internal constant _ROLE_189 = 1 << 189; uint256 internal constant _ROLE_190 = 1 << 190; uint256 internal constant _ROLE_191 = 1 << 191; uint256 internal constant _ROLE_192 = 1 << 192; uint256 internal constant _ROLE_193 = 1 << 193; uint256 internal constant _ROLE_194 = 1 << 194; uint256 internal constant _ROLE_195 = 1 << 195; uint256 internal constant _ROLE_196 = 1 << 196; uint256 internal constant _ROLE_197 = 1 << 197; uint256 internal constant _ROLE_198 = 1 << 198; uint256 internal constant _ROLE_199 = 1 << 199; uint256 internal constant _ROLE_200 = 1 << 200; uint256 internal constant _ROLE_201 = 1 << 201; uint256 internal constant _ROLE_202 = 1 << 202; uint256 internal constant _ROLE_203 = 1 << 203; uint256 internal constant _ROLE_204 = 1 << 204; uint256 internal constant _ROLE_205 = 1 << 205; uint256 internal constant _ROLE_206 = 1 << 206; uint256 internal constant _ROLE_207 = 1 << 207; uint256 internal constant _ROLE_208 = 1 << 208; uint256 internal constant _ROLE_209 = 1 << 209; uint256 internal constant _ROLE_210 = 1 << 210; uint256 internal constant _ROLE_211 = 1 << 211; uint256 internal constant _ROLE_212 = 1 << 212; uint256 internal constant _ROLE_213 = 1 << 213; uint256 internal constant _ROLE_214 = 1 << 214; uint256 internal constant _ROLE_215 = 1 << 215; uint256 internal constant _ROLE_216 = 1 << 216; uint256 internal constant _ROLE_217 = 1 << 217; uint256 internal constant _ROLE_218 = 1 << 218; uint256 internal constant _ROLE_219 = 1 << 219; uint256 internal constant _ROLE_220 = 1 << 220; uint256 internal constant _ROLE_221 = 1 << 221; uint256 internal constant _ROLE_222 = 1 << 222; uint256 internal constant _ROLE_223 = 1 << 223; uint256 internal constant _ROLE_224 = 1 << 224; uint256 internal constant _ROLE_225 = 1 << 225; uint256 internal constant _ROLE_226 = 1 << 226; uint256 internal constant _ROLE_227 = 1 << 227; uint256 internal constant _ROLE_228 = 1 << 228; uint256 internal constant _ROLE_229 = 1 << 229; uint256 internal constant _ROLE_230 = 1 << 230; uint256 internal constant _ROLE_231 = 1 << 231; uint256 internal constant _ROLE_232 = 1 << 232; uint256 internal constant _ROLE_233 = 1 << 233; uint256 internal constant _ROLE_234 = 1 << 234; uint256 internal constant _ROLE_235 = 1 << 235; uint256 internal constant _ROLE_236 = 1 << 236; uint256 internal constant _ROLE_237 = 1 << 237; uint256 internal constant _ROLE_238 = 1 << 238; uint256 internal constant _ROLE_239 = 1 << 239; uint256 internal constant _ROLE_240 = 1 << 240; uint256 internal constant _ROLE_241 = 1 << 241; uint256 internal constant _ROLE_242 = 1 << 242; uint256 internal constant _ROLE_243 = 1 << 243; uint256 internal constant _ROLE_244 = 1 << 244; uint256 internal constant _ROLE_245 = 1 << 245; uint256 internal constant _ROLE_246 = 1 << 246; uint256 internal constant _ROLE_247 = 1 << 247; uint256 internal constant _ROLE_248 = 1 << 248; uint256 internal constant _ROLE_249 = 1 << 249; uint256 internal constant _ROLE_250 = 1 << 250; uint256 internal constant _ROLE_251 = 1 << 251; uint256 internal constant _ROLE_252 = 1 << 252; uint256 internal constant _ROLE_253 = 1 << 253; uint256 internal constant _ROLE_254 = 1 << 254; uint256 internal constant _ROLE_255 = 1 << 255; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import { IERC721AUpgradeable } from "chiru-labs/ERC721A-Upgradeable/IERC721AUpgradeable.sol"; import { IERC2981Upgradeable } from "openzeppelin-upgradeable/interfaces/IERC2981Upgradeable.sol"; import { IERC165Upgradeable } from "openzeppelin-upgradeable/utils/introspection/IERC165Upgradeable.sol"; import { IMetadataModule } from "./IMetadataModule.sol"; /** * @title ISoundEditionV2 * @notice The interface for Sound edition contracts. */ interface ISoundEditionV2 is IERC721AUpgradeable, IERC2981Upgradeable { // ============================================================= // STRUCTS // ============================================================= /** * @dev The information pertaining to a tier. */ struct TierInfo { // The tier. uint8 tier; // The current max mintable amount. uint32 maxMintable; // The lower bound of the maximum number of tokens that can be minted for the tier. uint32 maxMintableLower; // The upper bound of the maximum number of tokens that can be minted for the tier. uint32 maxMintableUpper; // The timestamp (in seconds since unix epoch) after which the // max amount of tokens mintable for the tier will drop from // `maxMintableUpper` to `maxMintableLower`. uint32 cutoffTime; // The total number of tokens minted for the tier. uint32 minted; // The mint randomness for the tier. uint256 mintRandomness; // Whether the tier mints have concluded. bool mintConcluded; // Whether the tier has mint randomness enabled. bool mintRandomnessEnabled; // Whether the tier is frozen. bool isFrozen; } /** * @dev A struct containing the arguments for creating a tier. */ struct TierCreation { // The tier. uint8 tier; // The lower bound of the maximum number of tokens that can be minted for the tier. uint32 maxMintableLower; // The upper bound of the maximum number of tokens that can be minted for the tier. uint32 maxMintableUpper; // The timestamp (in seconds since unix epoch) after which the // max amount of tokens mintable for the tier will drop from // `maxMintableUpper` to `maxMintableLower`. uint32 cutoffTime; // Whether the tier has mint randomness enabled. bool mintRandomnessEnabled; // Whether the tier is frozen. bool isFrozen; } /** * @dev The information pertaining to this edition. */ struct EditionInfo { // Base URI for the metadata. string baseURI; // Contract URI for OpenSea storefront. string contractURI; // Name of the collection. string name; // Symbol of the collection. string symbol; // Address that receives primary and secondary royalties. address fundingRecipient; // Address of the metadata module. Optional. address metadataModule; // Whether the metadata is frozen. bool isMetadataFrozen; // Whether the ability to create tiers is frozen. bool isCreateTierFrozen; // The royalty BPS (basis points). uint16 royaltyBPS; // Next token ID to be minted. uint256 nextTokenId; // Total number of tokens burned. uint256 totalBurned; // Total number of tokens minted. uint256 totalMinted; // Total number of tokens currently in existence. uint256 totalSupply; // An array of tier info. From lowest (0-indexed) to highest. TierInfo[] tierInfo; } /** * @dev A struct containing the arguments for initialization. */ struct EditionInitialization { // Name of the collection. string name; // Symbol of the collection. string symbol; // Address of the metadata module. Optional. address metadataModule; // Base URI for the metadata. string baseURI; // Contract URI for OpenSea storefront. string contractURI; // Address that receives primary and secondary royalties. address fundingRecipient; // The royalty BPS (basis points). uint16 royaltyBPS; // Whether the metadata is frozen. bool isMetadataFrozen; // Whether the ability to create tiers is frozen. bool isCreateTierFrozen; // An array of tier creation structs. From lowest (0-indexed) to highest. TierCreation[] tierCreations; } // ============================================================= // EVENTS // ============================================================= /** * @dev Emitted when the metadata module is set. * @param metadataModule the address of the metadata module. */ event MetadataModuleSet(address metadataModule); /** * @dev Emitted when the `baseURI` is set. * @param baseURI the base URI of the edition. */ event BaseURISet(string baseURI); /** * @dev Emitted when the `contractURI` is set. * @param contractURI The contract URI of the edition. */ event ContractURISet(string contractURI); /** * @dev Emitted when the metadata is frozen (e.g.: `baseURI` can no longer be changed). * @param metadataModule The address of the metadata module. * @param baseURI The base URI of the edition. * @param contractURI The contract URI of the edition. */ event MetadataFrozen(address metadataModule, string baseURI, string contractURI); /** * @dev Emitted when the ability to create tier is removed. */ event CreateTierFrozen(); /** * @dev Emitted when the `fundingRecipient` is set. * @param recipient The address of the funding recipient. */ event FundingRecipientSet(address recipient); /** * @dev Emitted when the `royaltyBPS` is set. * @param bps The new royalty, measured in basis points. */ event RoyaltySet(uint16 bps); /** * @dev Emitted when the tier's maximum mintable token quantity range is set. * @param tier The tier. * @param lower The lower limit of the maximum number of tokens that can be minted. * @param upper The upper limit of the maximum number of tokens that can be minted. */ event MaxMintableRangeSet(uint8 tier, uint32 lower, uint32 upper); /** * @dev Emitted when the tier's cutoff time set. * @param tier The tier. * @param cutoff The timestamp. */ event CutoffTimeSet(uint8 tier, uint32 cutoff); /** * @dev Emitted when the `mintRandomnessEnabled` for the tier is set. * @param tier The tier. * @param enabled The boolean value. */ event MintRandomnessEnabledSet(uint8 tier, bool enabled); /** * @dev Emitted upon initialization. * @param init The initialization data. */ event SoundEditionInitialized(EditionInitialization init); /** * @dev Emitted when a tier is created. * @param creation The tier creation data. */ event TierCreated(TierCreation creation); /** * @dev Emitted when a tier is frozen. * @param tier The tier. */ event TierFrozen(uint8 tier); /** * @dev Emitted upon ETH withdrawal. * @param recipient The recipient of the withdrawal. * @param amount The amount withdrawn. * @param caller The account that initiated the withdrawal. */ event ETHWithdrawn(address recipient, uint256 amount, address caller); /** * @dev Emitted upon ERC20 withdrawal. * @param recipient The recipient of the withdrawal. * @param tokens The addresses of the ERC20 tokens. * @param amounts The amount of each token withdrawn. * @param caller The account that initiated the withdrawal. */ event ERC20Withdrawn(address recipient, address[] tokens, uint256[] amounts, address caller); /** * @dev Emitted upon a mint. * @param tier The tier. * @param to The address to mint to. * @param quantity The number of minted. * @param fromTokenId The first token ID minted. */ event Minted(uint8 tier, address to, uint256 quantity, uint256 fromTokenId); /** * @dev Emitted upon an airdrop. * @param tier The tier. * @param to The recipients of the airdrop. * @param quantity The number of tokens airdropped to each address in `to`. * @param fromTokenId The first token ID minted to the first address in `to`. */ event Airdropped(uint8 tier, address[] to, uint256 quantity, uint256 fromTokenId); /** * @dev EIP-4906 event to signal marketplaces to refresh the metadata. * @param fromTokenId The starting token ID. * @param toTokenId The ending token ID. */ event BatchMetadataUpdate(uint256 fromTokenId, uint256 toTokenId); // ============================================================= // ERRORS // ============================================================= /** * @dev The edition's metadata is frozen (e.g.: `baseURI` can no longer be changed). */ error MetadataIsFrozen(); /** * @dev The ability to create tiers is frozen. */ error CreateTierIsFrozen(); /** * @dev The given `royaltyBPS` is invalid. */ error InvalidRoyaltyBPS(); /** * @dev A minimum of one tier must be provided to initialize a Sound Edition. */ error ZeroTiersProvided(); /** * @dev The requested quantity exceeds the edition's remaining mintable token quantity. */ error ExceedsAvailableSupply(); /** * @dev The given `fundingRecipient` address is invalid. */ error InvalidFundingRecipient(); /** * @dev The `maxMintableLower` must not be greater than `maxMintableUpper`. */ error InvalidMaxMintableRange(); /** * @dev The mint has already concluded. */ error MintHasConcluded(); /** * @dev The mint has not concluded. */ error MintNotConcluded(); /** * @dev Cannot perform the operation after a token has been minted. */ error MintsAlreadyExist(); /** * @dev Cannot perform the operation after a token has been minted in the tier. */ error TierMintsAlreadyExist(); /** * @dev The token IDs must be in strictly ascending order. */ error TokenIdsNotStrictlyAscending(); /** * @dev The tier does not exist. */ error TierDoesNotExist(); /** * @dev The tier already exists. */ error TierAlreadyExists(); /** * @dev The tier is frozen. */ error TierIsFrozen(); /** * @dev One of more of the tokens do not have the correct token tier. */ error InvalidTokenTier(); /** * @dev Please wait for a while before you burn. */ error CannotBurnImmediately(); /** * @dev The token for the tier query doesn't exist. */ error TierQueryForNonexistentToken(); // ============================================================= // PUBLIC / EXTERNAL WRITE FUNCTIONS // ============================================================= /** * @dev Initializes the contract. * @param init The initialization struct. */ function initialize(EditionInitialization calldata init) external; /** * @dev Mints `quantity` tokens to addrress `to` * Each token will be assigned a token ID that is consecutively increasing. * * Calling conditions: * - The caller must be the owner of the contract, or have either the * `ADMIN_ROLE`, `MINTER_ROLE`, which can be granted via {grantRole}. * Multiple minters, such as different minter contracts, * can be authorized simultaneously. * * @param tier The tier. * @param to Address to mint to. * @param quantity Number of tokens to mint. * @return fromTokenId The first token ID minted. */ function mint( uint8 tier, address to, uint256 quantity ) external payable returns (uint256 fromTokenId); /** * @dev Mints `quantity` tokens to each of the addresses in `to`. * * Calling conditions: * - The caller must be the owner of the contract, or have the * `ADMIN_ROLE`, which can be granted via {grantRole}. * * @param tier The tier. * @param to Address to mint to. * @param quantity Number of tokens to mint. * @return fromTokenId The first token ID minted. */ function airdrop( uint8 tier, address[] calldata to, uint256 quantity ) external payable returns (uint256 fromTokenId); /** * @dev Withdraws collected ETH royalties to the fundingRecipient. */ function withdrawETH() external; /** * @dev Withdraws collected ERC20 royalties to the fundingRecipient. * @param tokens array of ERC20 tokens to withdraw */ function withdrawERC20(address[] calldata tokens) external; /** * @dev Sets metadata module. * * Calling conditions: * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`. * * @param metadataModule Address of metadata module. */ function setMetadataModule(address metadataModule) external; /** * @dev Sets global base URI. * * Calling conditions: * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`. * * @param baseURI The base URI to be set. */ function setBaseURI(string memory baseURI) external; /** * @dev Sets contract URI. * * Calling conditions: * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`. * * @param contractURI The contract URI to be set. */ function setContractURI(string memory contractURI) external; /** * @dev Freezes metadata by preventing any more changes to base URI. * * Calling conditions: * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`. */ function freezeMetadata() external; /** * @dev Freezes the max tier by preventing any more tiers from being added, * * Calling conditions: * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`. */ function freezeCreateTier() external; /** * @dev Sets funding recipient address. * * Calling conditions: * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`. * * @param fundingRecipient Address to be set as the new funding recipient. */ function setFundingRecipient(address fundingRecipient) external; /** * @dev Creates a new split wallet via the SplitMain contract, then sets it as the `fundingRecipient`. * * Calling conditions: * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`. * * @param splitMain The address of the SplitMain contract. * @param splitData The calldata to forward to the SplitMain contract to create a split. * @return split The address of the new split contract. */ function createSplit(address splitMain, bytes calldata splitData) external returns (address split); /** * @dev Sets royalty amount in bps (basis points). * * Calling conditions: * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`. * * @param bps The new royalty basis points to be set. */ function setRoyalty(uint16 bps) external; /** * @dev Freezes the tier. * * Calling conditions: * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`. * * @param tier The tier. */ function freezeTier(uint8 tier) external; /** * @dev Sets the edition max mintable range. * * Calling conditions: * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`. * * @param tier The tier. * @param lower The lower limit of the maximum number of tokens that can be minted. * @param upper The upper limit of the maximum number of tokens that can be minted. */ function setMaxMintableRange( uint8 tier, uint32 lower, uint32 upper ) external; /** * @dev Sets the timestamp after which, the `editionMaxMintable` drops * from `editionMaxMintableUpper` to `editionMaxMintableLower. * * Calling conditions: * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`. * * @param tier The tier. * @param cutoffTime The timestamp. */ function setCutoffTime(uint8 tier, uint32 cutoffTime) external; /** * @dev Sets whether the `mintRandomness` is enabled. * * Calling conditions: * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`. * * @param tier The tier. * @param enabled The boolean value. */ function setMintRandomnessEnabled(uint8 tier, bool enabled) external; /** * @dev Adds a new tier. * * Calling conditions: * - The caller must be the owner of the contract, or have the `ADMIN_ROLE`. * * @param creation The tier creation data. */ function createTier(TierCreation calldata creation) external; /** * @dev Emits an event to signal to marketplaces to refresh all the metadata. */ function emitAllMetadataUpdate() external; // ============================================================= // PUBLIC / EXTERNAL VIEW FUNCTIONS // ============================================================= /** * @dev Returns the edition info. * @return info The latest value. */ function editionInfo() external view returns (EditionInfo memory info); /** * @dev Returns the tier info. * @param tier The tier. * @return info The latest value. */ function tierInfo(uint8 tier) external view returns (TierInfo memory info); /** * @dev Returns the GA tier, which is 0. * @return The constant value. */ function GA_TIER() external pure returns (uint8); /** * @dev Basis points denominator used in fee calculations. * @return The constant value. */ function BPS_DENOMINATOR() external pure returns (uint16); /** * @dev Returns the minter role flag. * Note: This constant will always be 2 for past and future sound protocol contracts. * @return The constant value. */ function MINTER_ROLE() external view returns (uint256); /** * @dev Returns the admin role flag. * Note: This constant will always be 1 for past and future sound protocol contracts. * @return The constant value. */ function ADMIN_ROLE() external view returns (uint256); /** * @dev Returns the tier of the `tokenId`. * @param tokenId The token ID. * @return The latest value. */ function tokenTier(uint256 tokenId) external view returns (uint8); /** * @dev Returns the tier of the `tokenId`. * Note: Will NOT revert if any `tokenId` does not exist. * If the token has not been minted, the tier will be zero. * If the token is burned, the tier will be the tier before it was burned. * @param tokenId The token ID. * @return The latest value. */ function explicitTokenTier(uint256 tokenId) external view returns (uint8); /** * @dev Returns the tiers of the `tokenIds`. * Note: Will NOT revert if any `tokenId` does not exist. * If the token has not been minted, the tier will be zero. * If the token is burned, the tier will be the tier before it was burned. * @param tokenIds The token IDs. * @return The latest values. */ function tokenTiers(uint256[] calldata tokenIds) external view returns (uint8[] memory); /** * @dev Returns an array of all the token IDs in the tier. * @param tier The tier. * @return tokenIds The array of token IDs in the tier. */ function tierTokenIds(uint8 tier) external view returns (uint256[] memory tokenIds); /** * @dev Returns an array of all the token IDs in the tier, within the range [start, stop). * @param tier The tier. * @param start The start of the range. Inclusive. * @param stop The end of the range. Exclusive. * @return tokenIds The array of token IDs in the tier. */ function tierTokenIdsIn( uint8 tier, uint256 start, uint256 stop ) external view returns (uint256[] memory tokenIds); /** * @dev Returns the index of `tokenId` in it's tier token ID array. * @param tokenId The token ID to find. * @return The index of `tokenId`. If not found, returns `type(uint256).max`. */ function tierTokenIdIndex(uint256 tokenId) external view returns (uint256); /** * @dev Returns the maximum amount of tokens mintable for the tier. * @param tier The tier. * @return The configured value. */ function maxMintable(uint8 tier) external view returns (uint32); /** * @dev Returns the upper bound for the maximum tokens that can be minted for the tier. * @param tier The tier. * @return The configured value. */ function maxMintableUpper(uint8 tier) external view returns (uint32); /** * @dev Returns the lower bound for the maximum tokens that can be minted for the tier. * @param tier The tier. * @return The configured value. */ function maxMintableLower(uint8 tier) external view returns (uint32); /** * @dev Returns the timestamp after which `maxMintable` drops from * `maxMintableUpper` to `maxMintableLower`. * @param tier The tier. * @return The configured value. */ function cutoffTime(uint8 tier) external view returns (uint32); /** * @dev Returns the number of tokens minted for the tier. * @param tier The tier. * @return The latest value. */ function tierMinted(uint8 tier) external view returns (uint32); /** * @dev Returns the mint randomness for the tier. * @param tier The tier. * @return The latest value. */ function mintRandomness(uint8 tier) external view returns (uint256); /** * @dev Returns the one-of-one token ID for the tier. * @param tier The tier. * @return The latest value. */ function mintRandomnessOneOfOne(uint8 tier) external view returns (uint32); /** * @dev Returns whether the `mintRandomness` has been enabled. * @return The configured value. */ function mintRandomnessEnabled(uint8 tier) external view returns (bool); /** * @dev Returns whether the mint has been concluded for the tier. * @param tier The tier. * @return The latest value. */ function mintConcluded(uint8 tier) external view returns (bool); /** * @dev Returns the base token URI for the collection. * @return The configured value. */ function baseURI() external view returns (string memory); /** * @dev Returns the contract URI to be used by Opensea. * See: https://docs.opensea.io/docs/contract-level-metadata * @return The configured value. */ function contractURI() external view returns (string memory); /** * @dev Returns the address of the funding recipient. * @return The configured value. */ function fundingRecipient() external view returns (address); /** * @dev Returns the address of the metadata module. * @return The configured value. */ function metadataModule() external view returns (address); /** * @dev Returns the royalty basis points. * @return The configured value. */ function royaltyBPS() external view returns (uint16); /** * @dev Returns whether the tier is frozen. * @return The configured value. */ function isFrozen(uint8 tier) external view returns (bool); /** * @dev Returns whether the metadata module is frozen. * @return The configured value. */ function isMetadataFrozen() external view returns (bool); /** * @dev Returns whether the ability to create tiers is frozen. * @return The configured value. */ function isCreateTierFrozen() external view returns (bool); /** * @dev Returns the next token ID to be minted. * @return The latest value. */ function nextTokenId() external view returns (uint256); /** * @dev Returns the number of tokens minted by `owner`. * @param owner Address to query for number minted. * @return The latest value. */ function numberMinted(address owner) external view returns (uint256); /** * @dev Returns the number of tokens burned by `owner`. * @param owner Address to query for number burned. * @return The latest value. */ function numberBurned(address owner) external view returns (uint256); /** * @dev Returns the total amount of tokens minted. * @return The latest value. */ function totalMinted() external view returns (uint256); /** * @dev Returns the total amount of tokens burned. * @return The latest value. */ function totalBurned() external view returns (uint256); /** * @dev Returns the token URI of `tokenId`, but without reverting if * the token does not exist. * @return The latest value. */ function explicitTokenURI(uint256 tokenId) external view returns (string memory); /** * @dev Informs other contracts which interfaces this contract supports. * Required by https://eips.ethereum.org/EIPS/eip-165 * @param interfaceId The interface id to check. * @return Whether the `interfaceId` is supported. */ function supportsInterface(bytes4 interfaceId) external view override(IERC721AUpgradeable, IERC165Upgradeable) returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import { IERC165 } from "openzeppelin/utils/introspection/IERC165.sol"; /** * @title ISuperMinter * @notice The interface for the generalized minter. */ interface ISuperMinter is IERC165 { // ============================================================= // STRUCTS // ============================================================= /** * @dev A struct containing the arguments to create a mint. */ struct MintCreation { // The edition address. address edition; // The base price per token. // For `VERIFY_SIGNATURE`, this will be the minimum limit of the signed price. // Will be 0 if the `tier` is `GA_TIER`. uint96 price; // The start time of the mint. uint32 startTime; // The end time of the mint. uint32 endTime; // The maximum number of tokens an account can mint in this mint. uint32 maxMintablePerAccount; // The maximum number of tokens mintable. uint32 maxMintable; // The affiliate fee BPS. uint16 affiliateFeeBPS; // The affiliate Merkle root, if any. bytes32 affiliateMerkleRoot; // The tier of the mint. uint8 tier; // The address of the platform. address platform; // The mode of the mint. Options: `DEFAULT`, `VERIFY_MERKLE`, `VERIFY_SIGNATURE`. uint8 mode; // The signer address, required if `mode` is `VERIFY_SIGNATURE`. // If set to `address(1)`, the platform signer will be used instead. address signer; // The Merkle root hash, required if `mode` is `VERIFY_MERKLE`. bytes32 merkleRoot; } /** * @dev A struct containing the arguments for mint-to. */ struct MintTo { // The mint ID. address edition; // The tier of the mint. uint8 tier; // The edition-tier schedule number. uint8 scheduleNum; // The address to mint to. address to; // The number of tokens to mint. uint32 quantity; // The allowlisted address. Used if `mode` is `VERIFY_MERKLE`. address allowlisted; // The allowlisted quantity. Used if `mode` is `VERIFY_MERKLE`. // A default zero value means no limit. uint32 allowlistedQuantity; // The allowlist Merkle proof. bytes32[] allowlistProof; // The signed price. Used if `mode` is `VERIFY_SIGNATURE`. uint96 signedPrice; // The signed quantity. Used if `mode` is `VERIFY_SIGNATURE`. uint32 signedQuantity; // The signed claimed ticket. Used if `mode` is `VERIFY_SIGNATURE`. uint32 signedClaimTicket; // The expiry timestamp for the signature. Used if `mode` is `VERIFY_SIGNATURE`. uint32 signedDeadline; // The signature by the signer. Used if `mode` is `VERIFY_SIGNATURE`. bytes signature; // The affiliate address. Optional. address affiliate; // The Merkle proof for the affiliate. bytes32[] affiliateProof; // The attribution ID, optional. uint256 attributionId; } /** * @dev A struct containing the total prices and fees. */ struct TotalPriceAndFees { // The required Ether value. // `subTotal + platformFlatFee`. uint256 total; // The total price before any additive fees. uint256 subTotal; // The price per token. uint256 unitPrice; // The total platform fees. // `platformFlatFee + platformMintBPSFee`. uint256 platformFee; // The total platform flat fees. // `platformTxFlatFee + platformMintFlatFee`. uint256 platformFlatFee; // The platform per-transaction flat fees. uint256 platformTxFlatFee; // The total platform per-token flat fees. uint256 platformMintFlatFee; // The total platform per-token BPS fees. uint256 platformMintBPSFee; // The total affiliate fees. uint256 affiliateFee; } /** * @dev A struct containing the log data for the `Minted` event. */ struct MintedLogData { // The number of tokens minted. uint32 quantity; // The starting token ID minted. uint256 fromTokenId; // The allowlisted address. address allowlisted; // The allowlisted quantity. uint32 allowlistedQuantity; // The signed quantity. uint32 signedQuantity; // The signed claim ticket. uint32 signedClaimTicket; // The affiliate address. address affiliate; // Whether the affiliate address is affiliated. bool affiliated; // The total price paid, inclusive of all fees. uint256 requiredEtherValue; // The price per token. uint256 unitPrice; // The total platform fees. uint256 platformFee; // The total platform flat fees. uint256 platformFlatFee; // The total affiliate fees. uint256 affiliateFee; } /** * @dev A struct to hold the fee configuration for a platform and a tier. */ struct PlatformFeeConfig { // The per-transaction flat fee. uint96 perTxFlat; // The per-token flat fee. uint96 perMintFlat; // The per-token fee BPS. uint16 perMintBPS; // Whether the fees are active. bool active; } /** * @dev A struct containing the mint information. */ struct MintInfo { // The mint ID. address edition; // The tier of the mint. uint8 tier; // The edition-tier schedule number. uint8 scheduleNum; // The platform address. address platform; // The base price per token. // For `VERIFY_SIGNATURE` this will be the minimum limit of the signed price. // If the `tier` is `GA_TIER`, and the `mode` is NOT `VERIFY_SIGNATURE`, // this value will be the GA price instead. uint96 price; // The start time of the mint. uint32 startTime; // The end time of the mint. uint32 endTime; // The maximum number of tokens an account can mint in this mint. uint32 maxMintablePerAccount; // The maximum number of tokens mintable. uint32 maxMintable; // The total number of tokens minted. uint32 minted; // The affiliate fee BPS. uint16 affiliateFeeBPS; // The mode of the mint. uint8 mode; // Whether the mint is paused. bool paused; // Whether the mint already has mints. bool hasMints; // The affiliate Merkle root, if any. bytes32 affiliateMerkleRoot; // The Merkle root hash, required if `mode` is `VERIFY_MERKLE`. bytes32 merkleRoot; // The signer address, required if `mode` is `VERIFY_SIGNATURE`. // This value will be the platform signer instead if it is configured to be `address(1)`. address signer; // Whether the platform signer is being used instead // (i.e. `signer` configured to be `address(1)`). bool usePlatformSigner; } // ============================================================= // EVENTS // ============================================================= /** * @dev Emitted when a new mint is created. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param creation The mint creation struct. */ event MintCreated(address indexed edition, uint8 tier, uint8 scheduleNum, MintCreation creation); /** * @dev Emitted when a mint is paused or un-paused. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param paused Whether the mint is paused. */ event PausedSet(address indexed edition, uint8 tier, uint8 scheduleNum, bool paused); /** * @dev Emitted when the time range of a mint is updated. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param startTime The start time. * @param endTime The end time. */ event TimeRangeSet(address indexed edition, uint8 tier, uint8 scheduleNum, uint32 startTime, uint32 endTime); /** * @dev Emitted when the base per-token price of a mint is updated. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param price The base per-token price. */ event PriceSet(address indexed edition, uint8 tier, uint8 scheduleNum, uint96 price); /** * @dev Emitted when the max mintable per account for a mint is updated. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param value The max mintable per account. */ event MaxMintablePerAccountSet(address indexed edition, uint8 tier, uint8 scheduleNum, uint32 value); /** * @dev Emitted when the max mintable for a mint is updated. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param value The max mintable for the mint. */ event MaxMintableSet(address indexed edition, uint8 tier, uint8 scheduleNum, uint32 value); /** * @dev Emitted when the Merkle root of a mint is updated. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param merkleRoot The Merkle root of the mint. */ event MerkleRootSet(address indexed edition, uint8 tier, uint8 scheduleNum, bytes32 merkleRoot); /** * @dev Emitted when the signer of a mint is updated. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param signer The signer of the mint. */ event SignerSet(address indexed edition, uint8 tier, uint8 scheduleNum, address signer); /** * @dev Emitted when the affiliate fee BPS for a mint is updated. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param bps The affiliate fee BPS. */ event AffiliateFeeSet(address indexed edition, uint8 tier, uint8 scheduleNum, uint16 bps); /** * @dev Emitted when the affiliate Merkle root for a mint is updated. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param root The affiliate Merkle root hash. */ event AffiliateMerkleRootSet(address indexed edition, uint8 tier, uint8 scheduleNum, bytes32 root); /** * @dev Emitted when tokens are minted. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param to The recipient of the tokens minted. * @param data The mint-to log data. * @param attributionId The optional attribution ID. */ event Minted( address indexed edition, uint8 tier, uint8 scheduleNum, address indexed to, MintedLogData data, uint256 indexed attributionId ); /** * @dev Emitted when the platform fee configuration for `tier` is updated. * @param platform The platform address. * @param tier The tier of the mint. * @param config The platform fee configuration. */ event PlatformFeeConfigSet(address indexed platform, uint8 tier, PlatformFeeConfig config); /** * @dev Emitted when the default platform fee configuration is updated. * @param platform The platform address. * @param config The platform fee configuration. */ event DefaultPlatformFeeConfigSet(address indexed platform, PlatformFeeConfig config); /** * @dev Emitted when affiliate fees are withdrawn. * @param affiliate The recipient of the fees. * @param accrued The amount of Ether accrued and withdrawn. */ event AffiliateFeesWithdrawn(address indexed affiliate, uint256 accrued); /** * @dev Emitted when platform fees are withdrawn. * @param platform The platform address. * @param accrued The amount of Ether accrued and withdrawn. */ event PlatformFeesWithdrawn(address indexed platform, uint256 accrued); /** * @dev Emitted when the platform fee recipient address is updated. * @param platform The platform address. * @param recipient The platform fee recipient address. */ event PlatformFeeAddressSet(address indexed platform, address recipient); /** * @dev Emitted when the per-token price for the GA tier is set. * @param platform The platform address. * @param price The price per token for the GA tier. */ event GAPriceSet(address indexed platform, uint96 price); /** * @dev Emitted when the signer for a platform is set. * @param platform The platform address. * @param signer The signer for the platform. */ event PlatformSignerSet(address indexed platform, address signer); // ============================================================= // ERRORS // ============================================================= /** * @dev Exact payment required. * @param paid The amount of Ether paid. * @param required The amount of Ether required. */ error WrongPayment(uint256 paid, uint256 required); /** * @dev The mint is not opened. * @param blockTimestamp The current block timestamp. * @param startTime The opening time of the mint. * @param endTime The closing time of the mint. */ error MintNotOpen(uint256 blockTimestamp, uint32 startTime, uint32 endTime); /** * @dev The mint is paused. */ error MintPaused(); /** * @dev Cannot perform the operation when any mints exist. */ error MintsAlreadyExist(); /** * @dev The time range is invalid. */ error InvalidTimeRange(); /** * @dev The max mintable range is invalid. */ error InvalidMaxMintableRange(); /** * @dev The affiliate fee BPS cannot exceed the limit. */ error InvalidAffiliateFeeBPS(); /** * @dev The affiliate fee BPS cannot exceed the limit. */ error InvalidPlatformFeeBPS(); /** * @dev The affiliate fee BPS cannot exceed the limit. */ error InvalidPlatformFlatFee(); /** * @dev Cannot mint more than the maximum limit per account. */ error ExceedsMaxPerAccount(); /** * @dev Cannot mint more than the maximum supply. */ error ExceedsMintSupply(); /** * @dev Cannot mint more than the signed quantity. */ error ExceedsSignedQuantity(); /** * @dev The signature is invalid. */ error InvalidSignature(); /** * @dev The signature has expired. */ error SignatureExpired(); /** * @dev The signature claim ticket has already been used. */ error SignatureAlreadyUsed(); /** * @dev The signer cannot be the zero address. */ error SignerIsZeroAddress(); /** * @dev The Merkle root cannot be empty. */ error MerkleRootIsEmpty(); /** * @dev The Merkle proof is invalid. */ error InvalidMerkleProof(); /** * @dev The caller has not been delegated via delegate cash. */ error CallerNotDelegated(); /** * @dev The max mintable amount per account cannot be zero. */ error MaxMintablePerAccountIsZero(); /** * @dev The max mintable value cannot be zero. */ error MaxMintableIsZero(); /** * @dev The plaform fee address cannot be the zero address. */ error PlatformFeeAddressIsZero(); /** * @dev The mint does not exist. */ error MintDoesNotExist(); /** * @dev The affiliate provided is invalid. */ error InvalidAffiliate(); /** * @dev The mint mode provided is invalid. */ error InvalidMode(); /** * @dev The signed price is too low. */ error SignedPriceTooLow(); /** * @dev The platform fee configuration provided is invalid. */ error InvalidPlatformFeeConfig(); /** * @dev The parameter cannot be configured. */ error NotConfigurable(); // ============================================================= // PUBLIC / EXTERNAL WRITE FUNCTIONS // ============================================================= /** * @dev Creates a mint. * @param c The mint creation struct. * @return scheduleNum The mint ID. */ function createEditionMint(MintCreation calldata c) external returns (uint8 scheduleNum); /** * @dev Performs a mint. * @param p The mint-to parameters. */ function mintTo(MintTo calldata p) external payable; /** * @dev Sets the price of the mint. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param price The price per token. */ function setPrice( address edition, uint8 tier, uint8 scheduleNum, uint96 price ) external; /** * @dev Pause or unpase the the mint. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param paused Whether to pause the mint. */ function setPaused( address edition, uint8 tier, uint8 scheduleNum, bool paused ) external; /** * @dev Sets the time range for the the mint. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param startTime The mint start time. * @param endTime The mint end time. */ function setTimeRange( address edition, uint8 tier, uint8 scheduleNum, uint32 startTime, uint32 endTime ) external; /** * @dev Sets the start time for the the mint. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param startTime The mint start time. */ function setStartTime( address edition, uint8 tier, uint8 scheduleNum, uint32 startTime ) external; /** * @dev Sets the affiliate fee BPS for the mint. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param bps The fee BPS. */ function setAffiliateFee( address edition, uint8 tier, uint8 scheduleNum, uint16 bps ) external; /** * @dev Sets the affiliate Merkle root for the mint. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param root The affiliate Merkle root. */ function setAffiliateMerkleRoot( address edition, uint8 tier, uint8 scheduleNum, bytes32 root ) external; /** * @dev Sets the max mintable per account. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param value The max mintable per account. */ function setMaxMintablePerAccount( address edition, uint8 tier, uint8 scheduleNum, uint32 value ) external; /** * @dev Sets the max mintable for the mint. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param value The max mintable for the mint. */ function setMaxMintable( address edition, uint8 tier, uint8 scheduleNum, uint32 value ) external; /** * @dev Sets the mode for the mint. The mint mode must be `VERIFY_MERKLE`. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param merkleRoot The Merkle root of the mint. */ function setMerkleRoot( address edition, uint8 tier, uint8 scheduleNum, bytes32 merkleRoot ) external; /** * @dev Sets the signer for the mint. The mint mode must be `VERIFY_SIGNATURE`. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param signer The signer of the mint. */ function setSigner( address edition, uint8 tier, uint8 scheduleNum, address signer ) external; /** * @dev Withdraws all accrued fees of the affiliate, to the affiliate. * @param affiliate The affiliate address. */ function withdrawForAffiliate(address affiliate) external; /** * @dev Withdraws all accrued fees of the platform, to the their fee address. * @param platform The platform address. */ function withdrawForPlatform(address platform) external; /** * @dev Allows the caller, as a platform, to set their fee address * @param recipient The platform fee address of the caller. */ function setPlatformFeeAddress(address recipient) external; /** * @dev Allows the caller, as a platform, to set their per-tier fee configuration. * @param tier The tier of the mint. * @param c The platform fee configuration struct. */ function setPlatformFeeConfig(uint8 tier, PlatformFeeConfig memory c) external; /** * @dev Allows the caller, as a platform, to set their default fee configuration. * @param c The platform fee configuration struct. */ function setDefaultPlatformFeeConfig(PlatformFeeConfig memory c) external; /** * @dev Allows the platform to set the price for the GA tier. * @param price The price per token for the GA tier. */ function setGAPrice(uint96 price) external; /** * @dev Allows the platform to set their signer. * @param signer The signer for the platform. */ function setPlatformSigner(address signer) external; // ============================================================= // PUBLIC / EXTERNAL VIEW FUNCTIONS // ============================================================= /** * @dev Returns the GA tier. Which is 0. * @return The constant value. */ function GA_TIER() external pure returns (uint8); /** * @dev The EIP-712 typehash for signed mints. * @return The constant value. */ function MINT_TO_TYPEHASH() external pure returns (bytes32); /** * @dev The default mint mode. * @return The constant value. */ function DEFAULT() external pure returns (uint8); /** * @dev The mint mode for Merkle drops. * @return The constant value. */ function VERIFY_MERKLE() external pure returns (uint8); /** * @dev The mint mode for Merkle drops. * @return The constant value. */ function VERIFY_SIGNATURE() external pure returns (uint8); /** * @dev The denominator used in BPS fee calculations. * @return The constant value. */ function BPS_DENOMINATOR() external pure returns (uint16); /** * @dev The maximum affiliate fee BPS. * @return The constant value. */ function MAX_AFFILIATE_FEE_BPS() external pure returns (uint16); /** * @dev The maximum per-mint platform fee BPS. * @return The constant value. */ function MAX_PLATFORM_PER_MINT_FEE_BPS() external pure returns (uint16); /** * @dev The maximum platform per-mint flat fee. * @return The constant value. */ function MAX_PLATFORM_PER_MINT_FLAT_FEE() external pure returns (uint96); /** * @dev The maximum platform per-transaction flat fee. * @return The constant value. */ function MAX_PLATFORM_PER_TX_FLAT_FEE() external pure returns (uint96); /** * @dev Returns the amount of fees accrued by the platform. * @param platform The platform address. * @return The latest value. */ function platformFeesAccrued(address platform) external view returns (uint256); /** * @dev Returns the fee recipient for the platform. * @param platform The platform address. * @return The configured value. */ function platformFeeAddress(address platform) external view returns (address); /** * @dev Returns the amount of fees accrued by the affiliate. * @param affiliate The affiliate address. * @return The latest value. */ function affiliateFeesAccrued(address affiliate) external view returns (uint256); /** * @dev Returns the EIP-712 digest of the mint-to data for signature mints. * @param p The mint-to parameters. * @return The computed value. */ function computeMintToDigest(MintTo calldata p) external view returns (bytes32); /** * @dev Returns the total price and fees for the mint. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param quantity How many tokens to mint. * @return A struct containing the total price and fees. */ function totalPriceAndFees( address edition, uint8 tier, uint8 scheduleNum, uint32 quantity ) external view returns (TotalPriceAndFees memory); /** * @dev Returns the total price and fees for the mint. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param quantity How many tokens to mint. * @param signedPrice The signed price. * @return A struct containing the total price and fees. */ function totalPriceAndFeesWithSignedPrice( address edition, uint8 tier, uint8 scheduleNum, uint32 quantity, uint96 signedPrice ) external view returns (TotalPriceAndFees memory); /** * @dev Returns the GA price for the platform. * @param platform The platform address. * @return The configured value. */ function gaPrice(address platform) external view returns (uint96); /** * @dev Returns the signer for the platform. * @param platform The platform address. * @return The configured value. */ function platformSigner(address platform) external view returns (address); /** * @dev Returns the next mint schedule number for the edition-tier. * @param edition The Sound Edition address. * @param tier The tier. * @return The next schedule number for the edition-tier. */ function nextScheduleNum(address edition, uint8 tier) external view returns (uint8); /** * @dev Returns the number of tokens minted by `collector` for the mint. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param collector The address which tokens are minted to, * or in the case of `VERIFY_MERKLE`, is the allowlisted address. * @return The number of tokens minted. */ function numberMinted( address edition, uint8 tier, uint8 scheduleNum, address collector ) external view returns (uint32); /** * @dev Returns whether the affiliate is affiliated for the mint * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param affiliate The affiliate address. * @param affiliateProof The Merkle proof for the affiliate. * @return The result. */ function isAffiliatedWithProof( address edition, uint8 tier, uint8 scheduleNum, address affiliate, bytes32[] calldata affiliateProof ) external view returns (bool); /** * @dev Returns whether the affiliate is affiliated for the mint. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param affiliate The affiliate address. * @return A boolean on whether the affiliate is affiliated for the mint. */ function isAffiliated( address edition, uint8 tier, uint8 scheduleNum, address affiliate ) external view returns (bool); /** * @dev Returns whether the claim tickets have been used. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @param claimTickets An array of claim tickets. * @return An array of bools, where true means that a ticket has been used. */ function checkClaimTickets( address edition, uint8 tier, uint8 scheduleNum, uint32[] calldata claimTickets ) external view returns (bool[] memory); /** * @dev Returns the platform fee configuration for the tier. * @param platform The platform address. * @param tier The tier of the mint. * @return The platform fee configuration struct. */ function platformFeeConfig(address platform, uint8 tier) external view returns (PlatformFeeConfig memory); /** * @dev Returns the default platform fee configuration. * @param platform The platform address. * @return The platform fee configuration struct. */ function defaultPlatformFeeConfig(address platform) external view returns (PlatformFeeConfig memory); /** * @dev Returns the effective platform fee configuration. * @param platform The platform address. * @param tier The tier of the mint. * @return The platform fee configuration struct. */ function effectivePlatformFeeConfig(address platform, uint8 tier) external view returns (PlatformFeeConfig memory); /** * @dev Returns an array of mint information structs pertaining to the mint. * @param edition The Sound Edition address. * @return An array of mint information structs. */ function mintInfoList(address edition) external view returns (MintInfo[] memory); /** * @dev Returns information pertaining to the mint. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @return The mint info struct. */ function mintInfo( address edition, uint8 tier, uint8 scheduleNum ) external view returns (MintInfo memory); /** * @dev Retuns the EIP-712 name for the contract. * @return The constant value. */ function name() external pure returns (string memory); /** * @dev Retuns the EIP-712 version for the contract. * @return The constant value. */ function version() external pure returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol) /// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) /// /// @dev Note: /// - For ETH transfers, please use `forceSafeTransferETH` for DoS protection. /// - For ERC20s, this implementation won't check that a token has code, /// responsibility is delegated to the caller. library SafeTransferLib { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The ETH transfer has failed. error ETHTransferFailed(); /// @dev The ERC20 `transferFrom` has failed. error TransferFromFailed(); /// @dev The ERC20 `transfer` has failed. error TransferFailed(); /// @dev The ERC20 `approve` has failed. error ApproveFailed(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CONSTANTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Suggested gas stipend for contract receiving ETH that disallows any storage writes. uint256 internal constant GAS_STIPEND_NO_STORAGE_WRITES = 2300; /// @dev Suggested gas stipend for contract receiving ETH to perform a few /// storage reads and writes, but low enough to prevent griefing. uint256 internal constant GAS_STIPEND_NO_GRIEF = 100000; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ETH OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ // If the ETH transfer MUST succeed with a reasonable gas budget, use the force variants. // // The regular variants: // - Forwards all remaining gas to the target. // - Reverts if the target reverts. // - Reverts if the current contract has insufficient balance. // // The force variants: // - Forwards with an optional gas stipend // (defaults to `GAS_STIPEND_NO_GRIEF`, which is sufficient for most cases). // - If the target reverts, or if the gas stipend is exhausted, // creates a temporary contract to force send the ETH via `SELFDESTRUCT`. // Future compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758. // - Reverts if the current contract has insufficient balance. // // The try variants: // - Forwards with a mandatory gas stipend. // - Instead of reverting, returns whether the transfer succeeded. /// @dev Sends `amount` (in wei) ETH to `to`. function safeTransferETH(address to, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { if iszero(call(gas(), to, amount, gas(), 0x00, gas(), 0x00)) { mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. revert(0x1c, 0x04) } } } /// @dev Sends all the ETH in the current contract to `to`. function safeTransferAllETH(address to) internal { /// @solidity memory-safe-assembly assembly { // Transfer all the ETH and check if it succeeded or not. if iszero(call(gas(), to, selfbalance(), gas(), 0x00, gas(), 0x00)) { mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. revert(0x1c, 0x04) } } } /// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`. function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal { /// @solidity memory-safe-assembly assembly { if lt(selfbalance(), amount) { mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. revert(0x1c, 0x04) } if iszero(call(gasStipend, to, amount, gas(), 0x00, gas(), 0x00)) { mstore(0x00, to) // Store the address in scratch space. mstore8(0x0b, 0x73) // Opcode `PUSH20`. mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`. if iszero(create(amount, 0x0b, 0x16)) { returndatacopy(gas(), returndatasize(), shr(20, gas())) // For gas estimation. } } } } /// @dev Force sends all the ETH in the current contract to `to`, with a `gasStipend`. function forceSafeTransferAllETH(address to, uint256 gasStipend) internal { /// @solidity memory-safe-assembly assembly { if iszero(call(gasStipend, to, selfbalance(), gas(), 0x00, gas(), 0x00)) { mstore(0x00, to) // Store the address in scratch space. mstore8(0x0b, 0x73) // Opcode `PUSH20`. mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`. if iszero(create(selfbalance(), 0x0b, 0x16)) { returndatacopy(gas(), returndatasize(), shr(20, gas())) // For gas estimation. } } } } /// @dev Force sends `amount` (in wei) ETH to `to`, with `GAS_STIPEND_NO_GRIEF`. function forceSafeTransferETH(address to, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { if lt(selfbalance(), amount) { mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. revert(0x1c, 0x04) } if iszero(call(GAS_STIPEND_NO_GRIEF, to, amount, gas(), 0x00, gas(), 0x00)) { mstore(0x00, to) // Store the address in scratch space. mstore8(0x0b, 0x73) // Opcode `PUSH20`. mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`. if iszero(create(amount, 0x0b, 0x16)) { returndatacopy(gas(), returndatasize(), shr(20, gas())) // For gas estimation. } } } } /// @dev Force sends all the ETH in the current contract to `to`, with `GAS_STIPEND_NO_GRIEF`. function forceSafeTransferAllETH(address to) internal { /// @solidity memory-safe-assembly assembly { if iszero(call(GAS_STIPEND_NO_GRIEF, to, selfbalance(), gas(), 0x00, gas(), 0x00)) { mstore(0x00, to) // Store the address in scratch space. mstore8(0x0b, 0x73) // Opcode `PUSH20`. mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`. if iszero(create(selfbalance(), 0x0b, 0x16)) { returndatacopy(gas(), returndatasize(), shr(20, gas())) // For gas estimation. } } } } /// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`. function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal returns (bool success) { /// @solidity memory-safe-assembly assembly { success := call(gasStipend, to, amount, gas(), 0x00, gas(), 0x00) } } /// @dev Sends all the ETH in the current contract to `to`, with a `gasStipend`. function trySafeTransferAllETH(address to, uint256 gasStipend) internal returns (bool success) { /// @solidity memory-safe-assembly assembly { success := call(gasStipend, to, selfbalance(), gas(), 0x00, gas(), 0x00) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ERC20 OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Sends `amount` of ERC20 `token` from `from` to `to`. /// Reverts upon failure. /// /// The `from` account must have at least `amount` approved for /// the current contract to manage. function safeTransferFrom(address token, address from, address to, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. mstore(0x60, amount) // Store the `amount` argument. mstore(0x40, to) // Store the `to` argument. mstore(0x2c, shl(96, from)) // Store the `from` argument. mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`. // Perform the transfer, reverting upon failure. if iszero( and( // The arguments of `and` are evaluated from right to left. or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing. call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20) ) ) { mstore(0x00, 0x7939f424) // `TransferFromFailed()`. revert(0x1c, 0x04) } mstore(0x60, 0) // Restore the zero slot to zero. mstore(0x40, m) // Restore the free memory pointer. } } /// @dev Sends all of ERC20 `token` from `from` to `to`. /// Reverts upon failure. /// /// The `from` account must have their entire balance approved for /// the current contract to manage. function safeTransferAllFrom(address token, address from, address to) internal returns (uint256 amount) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. mstore(0x40, to) // Store the `to` argument. mstore(0x2c, shl(96, from)) // Store the `from` argument. mstore(0x0c, 0x70a08231000000000000000000000000) // `balanceOf(address)`. // Read the balance, reverting upon failure. if iszero( and( // The arguments of `and` are evaluated from right to left. gt(returndatasize(), 0x1f), // At least 32 bytes returned. staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20) ) ) { mstore(0x00, 0x7939f424) // `TransferFromFailed()`. revert(0x1c, 0x04) } mstore(0x00, 0x23b872dd) // `transferFrom(address,address,uint256)`. amount := mload(0x60) // The `amount` is already at 0x60. We'll need to return it. // Perform the transfer, reverting upon failure. if iszero( and( // The arguments of `and` are evaluated from right to left. or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing. call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20) ) ) { mstore(0x00, 0x7939f424) // `TransferFromFailed()`. revert(0x1c, 0x04) } mstore(0x60, 0) // Restore the zero slot to zero. mstore(0x40, m) // Restore the free memory pointer. } } /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`. /// Reverts upon failure. function safeTransfer(address token, address to, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { mstore(0x14, to) // Store the `to` argument. mstore(0x34, amount) // Store the `amount` argument. mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`. // Perform the transfer, reverting upon failure. if iszero( and( // The arguments of `and` are evaluated from right to left. or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing. call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20) ) ) { mstore(0x00, 0x90b8ec18) // `TransferFailed()`. revert(0x1c, 0x04) } mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten. } } /// @dev Sends all of ERC20 `token` from the current contract to `to`. /// Reverts upon failure. function safeTransferAll(address token, address to) internal returns (uint256 amount) { /// @solidity memory-safe-assembly assembly { mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`. mstore(0x20, address()) // Store the address of the current contract. // Read the balance, reverting upon failure. if iszero( and( // The arguments of `and` are evaluated from right to left. gt(returndatasize(), 0x1f), // At least 32 bytes returned. staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20) ) ) { mstore(0x00, 0x90b8ec18) // `TransferFailed()`. revert(0x1c, 0x04) } mstore(0x14, to) // Store the `to` argument. amount := mload(0x34) // The `amount` is already at 0x34. We'll need to return it. mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`. // Perform the transfer, reverting upon failure. if iszero( and( // The arguments of `and` are evaluated from right to left. or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing. call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20) ) ) { mstore(0x00, 0x90b8ec18) // `TransferFailed()`. revert(0x1c, 0x04) } mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten. } } /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract. /// Reverts upon failure. function safeApprove(address token, address to, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { mstore(0x14, to) // Store the `to` argument. mstore(0x34, amount) // Store the `amount` argument. mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`. // Perform the approval, reverting upon failure. if iszero( and( // The arguments of `and` are evaluated from right to left. or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing. call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20) ) ) { mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`. revert(0x1c, 0x04) } mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten. } } /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract. /// If the initial attempt to approve fails, attempts to reset the approved amount to zero, /// then retries the approval again (some tokens, e.g. USDT, requires this). /// Reverts upon failure. function safeApproveWithRetry(address token, address to, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { mstore(0x14, to) // Store the `to` argument. mstore(0x34, amount) // Store the `amount` argument. mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`. // Perform the approval, retrying upon failure. if iszero( and( // The arguments of `and` are evaluated from right to left. or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing. call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20) ) ) { mstore(0x34, 0) // Store 0 for the `amount`. mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`. pop(call(gas(), token, 0, 0x10, 0x44, 0x00, 0x00)) // Reset the approval. mstore(0x34, amount) // Store back the original `amount`. // Retry the approval, reverting upon failure. if iszero( and( or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing. call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20) ) ) { mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`. revert(0x1c, 0x04) } } mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten. } } /// @dev Returns the amount of ERC20 `token` owned by `account`. /// Returns zero if the `token` does not exist. function balanceOf(address token, address account) internal view returns (uint256 amount) { /// @solidity memory-safe-assembly assembly { mstore(0x14, account) // Store the `account` argument. mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`. amount := mul( mload(0x20), and( // The arguments of `and` are evaluated from right to left. gt(returndatasize(), 0x1f), // At least 32 bytes returned. staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20) ) ) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Contract for EIP-712 typed structured data hashing and signing. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/EIP712.sol) /// @author Modified from Solbase (https://github.com/Sol-DAO/solbase/blob/main/src/utils/EIP712.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/EIP712.sol) /// /// @dev Note, this implementation: /// - Uses `address(this)` for the `verifyingContract` field. /// - Does NOT use the optional EIP-712 salt. /// - Does NOT use any EIP-712 extensions. /// This is for simplicity and to save gas. /// If you need to customize, please fork / modify accordingly. abstract contract EIP712 { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CONSTANTS AND IMMUTABLES */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev `keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")`. bytes32 internal constant _DOMAIN_TYPEHASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f; address private immutable _cachedThis; uint256 private immutable _cachedChainId; bytes32 private immutable _cachedNameHash; bytes32 private immutable _cachedVersionHash; bytes32 private immutable _cachedDomainSeparator; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CONSTRUCTOR */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Cache the hashes for cheaper runtime gas costs. /// In the case of upgradeable contracts (i.e. proxies), /// or if the chain id changes due to a hard fork, /// the domain separator will be seamlessly calculated on-the-fly. constructor() { _cachedThis = address(this); _cachedChainId = block.chainid; string memory name; string memory version; if (!_domainNameAndVersionMayChange()) (name, version) = _domainNameAndVersion(); bytes32 nameHash = _domainNameAndVersionMayChange() ? bytes32(0) : keccak256(bytes(name)); bytes32 versionHash = _domainNameAndVersionMayChange() ? bytes32(0) : keccak256(bytes(version)); _cachedNameHash = nameHash; _cachedVersionHash = versionHash; bytes32 separator; if (!_domainNameAndVersionMayChange()) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Load the free memory pointer. mstore(m, _DOMAIN_TYPEHASH) mstore(add(m, 0x20), nameHash) mstore(add(m, 0x40), versionHash) mstore(add(m, 0x60), chainid()) mstore(add(m, 0x80), address()) separator := keccak256(m, 0xa0) } } _cachedDomainSeparator = separator; } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* FUNCTIONS TO OVERRIDE */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Please override this function to return the domain name and version. /// ``` /// function _domainNameAndVersion() /// internal /// pure /// virtual /// returns (string memory name, string memory version) /// { /// name = "Solady"; /// version = "1"; /// } /// ``` /// /// Note: If the returned result may change after the contract has been deployed, /// you must override `_domainNameAndVersionMayChange()` to return true. function _domainNameAndVersion() internal view virtual returns (string memory name, string memory version); /// @dev Returns if `_domainNameAndVersion()` may change /// after the contract has been deployed (i.e. after the constructor). /// Default: false. function _domainNameAndVersionMayChange() internal pure virtual returns (bool result) {} /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* HASHING OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the EIP-712 domain separator. function _domainSeparator() internal view virtual returns (bytes32 separator) { if (_domainNameAndVersionMayChange()) { separator = _buildDomainSeparator(); } else { separator = _cachedDomainSeparator; if (_cachedDomainSeparatorInvalidated()) separator = _buildDomainSeparator(); } } /// @dev Returns the hash of the fully encoded EIP-712 message for this domain, /// given `structHash`, as defined in /// https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct. /// /// The hash can be used together with {ECDSA-recover} to obtain the signer of a message: /// ``` /// bytes32 digest = _hashTypedData(keccak256(abi.encode( /// keccak256("Mail(address to,string contents)"), /// mailTo, /// keccak256(bytes(mailContents)) /// ))); /// address signer = ECDSA.recover(digest, signature); /// ``` function _hashTypedData(bytes32 structHash) internal view virtual returns (bytes32 digest) { bytes32 separator; if (_domainNameAndVersionMayChange()) { separator = _buildDomainSeparator(); } else { separator = _cachedDomainSeparator; if (_cachedDomainSeparatorInvalidated()) separator = _buildDomainSeparator(); } /// @solidity memory-safe-assembly assembly { // Compute the digest. mstore(0x00, 0x1901000000000000) // Store "\x19\x01". mstore(0x1a, separator) // Store the domain separator. mstore(0x3a, structHash) // Store the struct hash. digest := keccak256(0x18, 0x42) // Restore the part of the free memory slot that was overwritten. mstore(0x3a, 0) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* EIP-5267 OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev See: https://eips.ethereum.org/EIPS/eip-5267 function eip712Domain() public view virtual returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ) { fields = hex"0f"; // `0b01111`. (name, version) = _domainNameAndVersion(); chainId = block.chainid; verifyingContract = address(this); salt = salt; // `bytes32(0)`. extensions = extensions; // `new uint256[](0)`. } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* PRIVATE HELPERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the EIP-712 domain separator. function _buildDomainSeparator() private view returns (bytes32 separator) { bytes32 nameHash; bytes32 versionHash; if (_domainNameAndVersionMayChange()) { (string memory name, string memory version) = _domainNameAndVersion(); nameHash = keccak256(bytes(name)); versionHash = keccak256(bytes(version)); } else { nameHash = _cachedNameHash; versionHash = _cachedVersionHash; } /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Load the free memory pointer. mstore(m, _DOMAIN_TYPEHASH) mstore(add(m, 0x20), nameHash) mstore(add(m, 0x40), versionHash) mstore(add(m, 0x60), chainid()) mstore(add(m, 0x80), address()) separator := keccak256(m, 0xa0) } } /// @dev Returns if the cached domain separator has been invalidated. function _cachedDomainSeparatorInvalidated() private view returns (bool result) { uint256 cachedChainId = _cachedChainId; address cachedThis = _cachedThis; /// @solidity memory-safe-assembly assembly { result := iszero(and(eq(chainid(), cachedChainId), eq(address(), cachedThis))) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Gas optimized verification of proof of inclusion for a leaf in a Merkle tree. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/MerkleProofLib.sol) /// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/MerkleProofLib.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/MerkleProof.sol) library MerkleProofLib { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* MERKLE PROOF VERIFICATION OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns whether `leaf` exists in the Merkle tree with `root`, given `proof`. function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool isValid) { /// @solidity memory-safe-assembly assembly { if mload(proof) { // Initialize `offset` to the offset of `proof` elements in memory. let offset := add(proof, 0x20) // Left shift by 5 is equivalent to multiplying by 0x20. let end := add(offset, shl(5, mload(proof))) // Iterate over proof elements to compute root hash. for {} 1 {} { // Slot of `leaf` in scratch space. // If the condition is true: 0x20, otherwise: 0x00. let scratch := shl(5, gt(leaf, mload(offset))) // Store elements to hash contiguously in scratch space. // Scratch space is 64 bytes (0x00 - 0x3f) and both elements are 32 bytes. mstore(scratch, leaf) mstore(xor(scratch, 0x20), mload(offset)) // Reuse `leaf` to store the hash to reduce stack operations. leaf := keccak256(0x00, 0x40) offset := add(offset, 0x20) if iszero(lt(offset, end)) { break } } } isValid := eq(leaf, root) } } /// @dev Returns whether `leaf` exists in the Merkle tree with `root`, given `proof`. function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool isValid) { /// @solidity memory-safe-assembly assembly { if proof.length { // Left shift by 5 is equivalent to multiplying by 0x20. let end := add(proof.offset, shl(5, proof.length)) // Initialize `offset` to the offset of `proof` in the calldata. let offset := proof.offset // Iterate over proof elements to compute root hash. for {} 1 {} { // Slot of `leaf` in scratch space. // If the condition is true: 0x20, otherwise: 0x00. let scratch := shl(5, gt(leaf, calldataload(offset))) // Store elements to hash contiguously in scratch space. // Scratch space is 64 bytes (0x00 - 0x3f) and both elements are 32 bytes. mstore(scratch, leaf) mstore(xor(scratch, 0x20), calldataload(offset)) // Reuse `leaf` to store the hash to reduce stack operations. leaf := keccak256(0x00, 0x40) offset := add(offset, 0x20) if iszero(lt(offset, end)) { break } } } isValid := eq(leaf, root) } } /// @dev Returns whether all `leaves` exist in the Merkle tree with `root`, /// given `proof` and `flags`. /// /// Note: /// - Breaking the invariant `flags.length == (leaves.length - 1) + proof.length` /// will always return false. /// - The sum of the lengths of `proof` and `leaves` must never overflow. /// - Any non-zero word in the `flags` array is treated as true. /// - The memory offset of `proof` must be be non-zero /// (i.e. `proof` is not pointing to the scratch space). function verifyMultiProof( bytes32[] memory proof, bytes32 root, bytes32[] memory leaves, bool[] memory flags ) internal pure returns (bool isValid) { // Rebuilds the root by consuming and producing values on a queue. // The queue starts with the `leaves` array, and goes into a `hashes` array. // After the process, the last element on the queue is verified // to be equal to the `root`. // // The `flags` array denotes whether the sibling // should be popped from the queue (`flag == true`), or // should be popped from the `proof` (`flag == false`). /// @solidity memory-safe-assembly assembly { // Cache the lengths of the arrays. let leavesLength := mload(leaves) let proofLength := mload(proof) let flagsLength := mload(flags) // Advance the pointers of the arrays to point to the data. leaves := add(0x20, leaves) proof := add(0x20, proof) flags := add(0x20, flags) // If the number of flags is correct. for {} eq(add(leavesLength, proofLength), add(flagsLength, 1)) {} { // For the case where `proof.length + leaves.length == 1`. if iszero(flagsLength) { // `isValid = (proof.length == 1 ? proof[0] : leaves[0]) == root`. isValid := eq(mload(xor(leaves, mul(xor(proof, leaves), proofLength))), root) break } // The required final proof offset if `flagsLength` is not zero, otherwise zero. let proofEnd := add(proof, shl(5, proofLength)) // We can use the free memory space for the queue. // We don't need to allocate, since the queue is temporary. let hashesFront := mload(0x40) // Copy the leaves into the hashes. // Sometimes, a little memory expansion costs less than branching. // Should cost less, even with a high free memory offset of 0x7d00. leavesLength := shl(5, leavesLength) for { let i := 0 } iszero(eq(i, leavesLength)) { i := add(i, 0x20) } { mstore(add(hashesFront, i), mload(add(leaves, i))) } // Compute the back of the hashes. let hashesBack := add(hashesFront, leavesLength) // This is the end of the memory for the queue. // We recycle `flagsLength` to save on stack variables (sometimes save gas). flagsLength := add(hashesBack, shl(5, flagsLength)) for {} 1 {} { // Pop from `hashes`. let a := mload(hashesFront) // Pop from `hashes`. let b := mload(add(hashesFront, 0x20)) hashesFront := add(hashesFront, 0x40) // If the flag is false, load the next proof, // else, pops from the queue. if iszero(mload(flags)) { // Loads the next proof. b := mload(proof) proof := add(proof, 0x20) // Unpop from `hashes`. hashesFront := sub(hashesFront, 0x20) } // Advance to the next flag. flags := add(flags, 0x20) // Slot of `a` in scratch space. // If the condition is true: 0x20, otherwise: 0x00. let scratch := shl(5, gt(a, b)) // Hash the scratch space and push the result onto the queue. mstore(scratch, a) mstore(xor(scratch, 0x20), b) mstore(hashesBack, keccak256(0x00, 0x40)) hashesBack := add(hashesBack, 0x20) if iszero(lt(hashesBack, flagsLength)) { break } } isValid := and( // Checks if the last value in the queue is same as the root. eq(mload(sub(hashesBack, 0x20)), root), // And whether all the proofs are used, if required. eq(proofEnd, proof) ) break } } } /// @dev Returns whether all `leaves` exist in the Merkle tree with `root`, /// given `proof` and `flags`. /// /// Note: /// - Breaking the invariant `flags.length == (leaves.length - 1) + proof.length` /// will always return false. /// - Any non-zero word in the `flags` array is treated as true. /// - The calldata offset of `proof` must be non-zero /// (i.e. `proof` is from a regular Solidity function with a 4-byte selector). function verifyMultiProofCalldata( bytes32[] calldata proof, bytes32 root, bytes32[] calldata leaves, bool[] calldata flags ) internal pure returns (bool isValid) { // Rebuilds the root by consuming and producing values on a queue. // The queue starts with the `leaves` array, and goes into a `hashes` array. // After the process, the last element on the queue is verified // to be equal to the `root`. // // The `flags` array denotes whether the sibling // should be popped from the queue (`flag == true`), or // should be popped from the `proof` (`flag == false`). /// @solidity memory-safe-assembly assembly { // If the number of flags is correct. for {} eq(add(leaves.length, proof.length), add(flags.length, 1)) {} { // For the case where `proof.length + leaves.length == 1`. if iszero(flags.length) { // `isValid = (proof.length == 1 ? proof[0] : leaves[0]) == root`. // forgefmt: disable-next-item isValid := eq( calldataload( xor(leaves.offset, mul(xor(proof.offset, leaves.offset), proof.length)) ), root ) break } // The required final proof offset if `flagsLength` is not zero, otherwise zero. let proofEnd := add(proof.offset, shl(5, proof.length)) // We can use the free memory space for the queue. // We don't need to allocate, since the queue is temporary. let hashesFront := mload(0x40) // Copy the leaves into the hashes. // Sometimes, a little memory expansion costs less than branching. // Should cost less, even with a high free memory offset of 0x7d00. calldatacopy(hashesFront, leaves.offset, shl(5, leaves.length)) // Compute the back of the hashes. let hashesBack := add(hashesFront, shl(5, leaves.length)) // This is the end of the memory for the queue. // We recycle `flagsLength` to save on stack variables (sometimes save gas). flags.length := add(hashesBack, shl(5, flags.length)) // We don't need to make a copy of `proof.offset` or `flags.offset`, // as they are pass-by-value (this trick may not always save gas). for {} 1 {} { // Pop from `hashes`. let a := mload(hashesFront) // Pop from `hashes`. let b := mload(add(hashesFront, 0x20)) hashesFront := add(hashesFront, 0x40) // If the flag is false, load the next proof, // else, pops from the queue. if iszero(calldataload(flags.offset)) { // Loads the next proof. b := calldataload(proof.offset) proof.offset := add(proof.offset, 0x20) // Unpop from `hashes`. hashesFront := sub(hashesFront, 0x20) } // Advance to the next flag offset. flags.offset := add(flags.offset, 0x20) // Slot of `a` in scratch space. // If the condition is true: 0x20, otherwise: 0x00. let scratch := shl(5, gt(a, b)) // Hash the scratch space and push the result onto the queue. mstore(scratch, a) mstore(xor(scratch, 0x20), b) mstore(hashesBack, keccak256(0x00, 0x40)) hashesBack := add(hashesBack, 0x20) if iszero(lt(hashesBack, flags.length)) { break } } isValid := and( // Checks if the last value in the queue is same as the root. eq(mload(sub(hashesBack, 0x20)), root), // And whether all the proofs are used, if required. eq(proofEnd, proof.offset) ) break } } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* EMPTY CALLDATA HELPERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns an empty calldata bytes32 array. function emptyProof() internal pure returns (bytes32[] calldata proof) { /// @solidity memory-safe-assembly assembly { proof.length := 0 } } /// @dev Returns an empty calldata bytes32 array. function emptyLeaves() internal pure returns (bytes32[] calldata leaves) { /// @solidity memory-safe-assembly assembly { leaves.length := 0 } } /// @dev Returns an empty calldata bool array. function emptyFlags() internal pure returns (bool[] calldata flags) { /// @solidity memory-safe-assembly assembly { flags.length := 0 } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import {LibBit} from "./LibBit.sol"; /// @notice Library for storage of packed unsigned booleans. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibBitmap.sol) /// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibBitmap.sol) /// @author Modified from Solidity-Bits (https://github.com/estarriolvetch/solidity-bits/blob/main/contracts/BitMaps.sol) library LibBitmap { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CONSTANTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The constant returned when a bitmap scan does not find a result. uint256 internal constant NOT_FOUND = type(uint256).max; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* STRUCTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev A bitmap in storage. struct Bitmap { mapping(uint256 => uint256) map; } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the boolean value of the bit at `index` in `bitmap`. function get(Bitmap storage bitmap, uint256 index) internal view returns (bool isSet) { // It is better to set `isSet` to either 0 or 1, than zero vs non-zero. // Both cost the same amount of gas, but the former allows the returned value // to be reused without cleaning the upper bits. uint256 b = (bitmap.map[index >> 8] >> (index & 0xff)) & 1; /// @solidity memory-safe-assembly assembly { isSet := b } } /// @dev Updates the bit at `index` in `bitmap` to true. function set(Bitmap storage bitmap, uint256 index) internal { bitmap.map[index >> 8] |= (1 << (index & 0xff)); } /// @dev Updates the bit at `index` in `bitmap` to false. function unset(Bitmap storage bitmap, uint256 index) internal { bitmap.map[index >> 8] &= ~(1 << (index & 0xff)); } /// @dev Flips the bit at `index` in `bitmap`. /// Returns the boolean result of the flipped bit. function toggle(Bitmap storage bitmap, uint256 index) internal returns (bool newIsSet) { /// @solidity memory-safe-assembly assembly { mstore(0x00, shr(8, index)) mstore(0x20, bitmap.slot) let storageSlot := keccak256(0x00, 0x40) let shift := and(index, 0xff) let storageValue := sload(storageSlot) let mask := shl(shift, 1) storageValue := xor(storageValue, mask) // It makes sense to return the `newIsSet`, // as it allow us to skip an additional warm `sload`, // and it costs minimal gas (about 15), // which may be optimized away if the returned value is unused. newIsSet := iszero(iszero(and(storageValue, mask))) sstore(storageSlot, storageValue) } } /// @dev Updates the bit at `index` in `bitmap` to `shouldSet`. function setTo(Bitmap storage bitmap, uint256 index, bool shouldSet) internal { /// @solidity memory-safe-assembly assembly { mstore(0x20, bitmap.slot) mstore(0x00, shr(8, index)) let storageSlot := keccak256(0x00, 0x40) let storageValue := sload(storageSlot) let shift := and(index, 0xff) sstore( storageSlot, // Unsets the bit at `shift` via `and`, then sets its new value via `or`. or(and(storageValue, not(shl(shift, 1))), shl(shift, iszero(iszero(shouldSet)))) ) } } /// @dev Consecutively sets `amount` of bits starting from the bit at `start`. function setBatch(Bitmap storage bitmap, uint256 start, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { let max := not(0) let shift := and(start, 0xff) mstore(0x20, bitmap.slot) mstore(0x00, shr(8, start)) if iszero(lt(add(shift, amount), 257)) { let storageSlot := keccak256(0x00, 0x40) sstore(storageSlot, or(sload(storageSlot), shl(shift, max))) let bucket := add(mload(0x00), 1) let bucketEnd := add(mload(0x00), shr(8, add(amount, shift))) amount := and(add(amount, shift), 0xff) shift := 0 for {} iszero(eq(bucket, bucketEnd)) { bucket := add(bucket, 1) } { mstore(0x00, bucket) sstore(keccak256(0x00, 0x40), max) } mstore(0x00, bucket) } let storageSlot := keccak256(0x00, 0x40) sstore(storageSlot, or(sload(storageSlot), shl(shift, shr(sub(256, amount), max)))) } } /// @dev Consecutively unsets `amount` of bits starting from the bit at `start`. function unsetBatch(Bitmap storage bitmap, uint256 start, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { let shift := and(start, 0xff) mstore(0x20, bitmap.slot) mstore(0x00, shr(8, start)) if iszero(lt(add(shift, amount), 257)) { let storageSlot := keccak256(0x00, 0x40) sstore(storageSlot, and(sload(storageSlot), not(shl(shift, not(0))))) let bucket := add(mload(0x00), 1) let bucketEnd := add(mload(0x00), shr(8, add(amount, shift))) amount := and(add(amount, shift), 0xff) shift := 0 for {} iszero(eq(bucket, bucketEnd)) { bucket := add(bucket, 1) } { mstore(0x00, bucket) sstore(keccak256(0x00, 0x40), 0) } mstore(0x00, bucket) } let storageSlot := keccak256(0x00, 0x40) sstore( storageSlot, and(sload(storageSlot), not(shl(shift, shr(sub(256, amount), not(0))))) ) } } /// @dev Returns number of set bits within a range by /// scanning `amount` of bits starting from the bit at `start`. function popCount(Bitmap storage bitmap, uint256 start, uint256 amount) internal view returns (uint256 count) { unchecked { uint256 bucket = start >> 8; uint256 shift = start & 0xff; if (!(amount + shift < 257)) { count = LibBit.popCount(bitmap.map[bucket] >> shift); uint256 bucketEnd = bucket + ((amount + shift) >> 8); amount = (amount + shift) & 0xff; shift = 0; for (++bucket; bucket != bucketEnd; ++bucket) { count += LibBit.popCount(bitmap.map[bucket]); } } count += LibBit.popCount((bitmap.map[bucket] >> shift) << (256 - amount)); } } /// @dev Returns the index of the most significant set bit before the bit at `before`. /// If no set bit is found, returns `NOT_FOUND`. function findLastSet(Bitmap storage bitmap, uint256 before) internal view returns (uint256 setBitIndex) { uint256 bucket; uint256 bucketBits; /// @solidity memory-safe-assembly assembly { setBitIndex := not(0) bucket := shr(8, before) mstore(0x00, bucket) mstore(0x20, bitmap.slot) let offset := and(0xff, not(before)) // `256 - (255 & before) - 1`. bucketBits := shr(offset, shl(offset, sload(keccak256(0x00, 0x40)))) if iszero(bucketBits) { for {} bucket {} { bucket := add(bucket, setBitIndex) // `sub(bucket, 1)`. mstore(0x00, bucket) bucketBits := sload(keccak256(0x00, 0x40)) if bucketBits { break } } } } if (bucketBits != 0) { setBitIndex = (bucket << 8) | LibBit.fls(bucketBits); /// @solidity memory-safe-assembly assembly { setBitIndex := or(setBitIndex, sub(0, gt(setBitIndex, before))) } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Signature verification helper that supports both ECDSA signatures from EOAs /// and ERC1271 signatures from smart contract wallets like Argent and Gnosis safe. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SignatureCheckerLib.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/SignatureChecker.sol) /// /// @dev Note: /// - The signature checking functions use the ecrecover precompile (0x1). /// - The `bytes memory signature` variants use the identity precompile (0x4) /// to copy memory internally. /// - Unlike ECDSA signatures, contract signatures are revocable. /// /// WARNING! Do NOT use signatures as unique identifiers. /// Please use EIP712 with a nonce included in the digest to prevent replay attacks. /// This implementation does NOT check if a signature is non-malleable. library SignatureCheckerLib { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* SIGNATURE CHECKING OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns whether `signature` is valid for `signer` and `hash`. /// If `signer` is a smart contract, the signature is validated with ERC1271. /// Otherwise, the signature is validated with `ECDSA.recover`. function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool isValid) { /// @solidity memory-safe-assembly assembly { // Clean the upper 96 bits of `signer` in case they are dirty. for { signer := shr(96, shl(96, signer)) } signer {} { let m := mload(0x40) if eq(mload(signature), 65) { mstore(0x00, hash) mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`. mstore(0x40, mload(add(signature, 0x20))) // `r`. mstore(0x60, mload(add(signature, 0x40))) // `s`. let t := staticcall( gas(), // Amount of gas left for the transaction. 1, // Address of `ecrecover`. 0x00, // Start of input. 0x80, // Size of input. 0x01, // Start of output. 0x20 // Size of output. ) // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) { isValid := 1 mstore(0x60, 0) // Restore the zero slot. mstore(0x40, m) // Restore the free memory pointer. break } } mstore(0x60, 0) // Restore the zero slot. mstore(0x40, m) // Restore the free memory pointer. let f := shl(224, 0x1626ba7e) mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. mstore(add(m, 0x04), hash) let d := add(m, 0x24) mstore(d, 0x40) // The offset of the `signature` in the calldata. // Copy the `signature` over. let n := add(0x20, mload(signature)) pop(staticcall(gas(), 4, signature, n, add(m, 0x44), n)) // forgefmt: disable-next-item isValid := and( // Whether the returndata is the magic value `0x1626ba7e` (left-aligned). eq(mload(d), f), // Whether the staticcall does not revert. // This must be placed at the end of the `and` clause, // as the arguments are evaluated from right to left. staticcall( gas(), // Remaining gas. signer, // The `signer` address. m, // Offset of calldata in memory. add(returndatasize(), 0x44), // Length of calldata in memory. d, // Offset of returndata. 0x20 // Length of returndata to write. ) ) break } } } /// @dev Returns whether `signature` is valid for `signer` and `hash`. /// If `signer` is a smart contract, the signature is validated with ERC1271. /// Otherwise, the signature is validated with `ECDSA.recover`. function isValidSignatureNowCalldata(address signer, bytes32 hash, bytes calldata signature) internal view returns (bool isValid) { /// @solidity memory-safe-assembly assembly { // Clean the upper 96 bits of `signer` in case they are dirty. for { signer := shr(96, shl(96, signer)) } signer {} { let m := mload(0x40) if eq(signature.length, 65) { mstore(0x00, hash) mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`. calldatacopy(0x40, signature.offset, 0x40) // `r`, `s`. let t := staticcall( gas(), // Amount of gas left for the transaction. 1, // Address of `ecrecover`. 0x00, // Start of input. 0x80, // Size of input. 0x01, // Start of output. 0x20 // Size of output. ) // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) { isValid := 1 mstore(0x60, 0) // Restore the zero slot. mstore(0x40, m) // Restore the free memory pointer. break } } mstore(0x60, 0) // Restore the zero slot. mstore(0x40, m) // Restore the free memory pointer. let f := shl(224, 0x1626ba7e) mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. mstore(add(m, 0x04), hash) let d := add(m, 0x24) mstore(d, 0x40) // The offset of the `signature` in the calldata. mstore(add(m, 0x44), signature.length) // Copy the `signature` over. calldatacopy(add(m, 0x64), signature.offset, signature.length) // forgefmt: disable-next-item isValid := and( // Whether the returndata is the magic value `0x1626ba7e` (left-aligned). eq(mload(d), f), // Whether the staticcall does not revert. // This must be placed at the end of the `and` clause, // as the arguments are evaluated from right to left. staticcall( gas(), // Remaining gas. signer, // The `signer` address. m, // Offset of calldata in memory. add(signature.length, 0x64), // Length of calldata in memory. d, // Offset of returndata. 0x20 // Length of returndata to write. ) ) break } } } /// @dev Returns whether the signature (`r`, `vs`) is valid for `signer` and `hash`. /// If `signer` is a smart contract, the signature is validated with ERC1271. /// Otherwise, the signature is validated with `ECDSA.recover`. function isValidSignatureNow(address signer, bytes32 hash, bytes32 r, bytes32 vs) internal view returns (bool isValid) { /// @solidity memory-safe-assembly assembly { // Clean the upper 96 bits of `signer` in case they are dirty. for { signer := shr(96, shl(96, signer)) } signer {} { let m := mload(0x40) mstore(0x00, hash) mstore(0x20, add(shr(255, vs), 27)) // `v`. mstore(0x40, r) // `r`. mstore(0x60, shr(1, shl(1, vs))) // `s`. let t := staticcall( gas(), // Amount of gas left for the transaction. 1, // Address of `ecrecover`. 0x00, // Start of input. 0x80, // Size of input. 0x01, // Start of output. 0x20 // Size of output. ) // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) { isValid := 1 mstore(0x60, 0) // Restore the zero slot. mstore(0x40, m) // Restore the free memory pointer. break } let f := shl(224, 0x1626ba7e) mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. mstore(add(m, 0x04), hash) let d := add(m, 0x24) mstore(d, 0x40) // The offset of the `signature` in the calldata. mstore(add(m, 0x44), 65) // Length of the signature. mstore(add(m, 0x64), r) // `r`. mstore(add(m, 0x84), mload(0x60)) // `s`. mstore8(add(m, 0xa4), mload(0x20)) // `v`. // forgefmt: disable-next-item isValid := and( // Whether the returndata is the magic value `0x1626ba7e` (left-aligned). eq(mload(d), f), // Whether the staticcall does not revert. // This must be placed at the end of the `and` clause, // as the arguments are evaluated from right to left. staticcall( gas(), // Remaining gas. signer, // The `signer` address. m, // Offset of calldata in memory. 0xa5, // Length of calldata in memory. d, // Offset of returndata. 0x20 // Length of returndata to write. ) ) mstore(0x60, 0) // Restore the zero slot. mstore(0x40, m) // Restore the free memory pointer. break } } } /// @dev Returns whether the signature (`v`, `r`, `s`) is valid for `signer` and `hash`. /// If `signer` is a smart contract, the signature is validated with ERC1271. /// Otherwise, the signature is validated with `ECDSA.recover`. function isValidSignatureNow(address signer, bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal view returns (bool isValid) { /// @solidity memory-safe-assembly assembly { // Clean the upper 96 bits of `signer` in case they are dirty. for { signer := shr(96, shl(96, signer)) } signer {} { let m := mload(0x40) mstore(0x00, hash) mstore(0x20, and(v, 0xff)) // `v`. mstore(0x40, r) // `r`. mstore(0x60, s) // `s`. let t := staticcall( gas(), // Amount of gas left for the transaction. 1, // Address of `ecrecover`. 0x00, // Start of input. 0x80, // Size of input. 0x01, // Start of output. 0x20 // Size of output. ) // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) { isValid := 1 mstore(0x60, 0) // Restore the zero slot. mstore(0x40, m) // Restore the free memory pointer. break } let f := shl(224, 0x1626ba7e) mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. mstore(add(m, 0x04), hash) let d := add(m, 0x24) mstore(d, 0x40) // The offset of the `signature` in the calldata. mstore(add(m, 0x44), 65) // Length of the signature. mstore(add(m, 0x64), r) // `r`. mstore(add(m, 0x84), s) // `s`. mstore8(add(m, 0xa4), v) // `v`. // forgefmt: disable-next-item isValid := and( // Whether the returndata is the magic value `0x1626ba7e` (left-aligned). eq(mload(d), f), // Whether the staticcall does not revert. // This must be placed at the end of the `and` clause, // as the arguments are evaluated from right to left. staticcall( gas(), // Remaining gas. signer, // The `signer` address. m, // Offset of calldata in memory. 0xa5, // Length of calldata in memory. d, // Offset of returndata. 0x20 // Length of returndata to write. ) ) mstore(0x60, 0) // Restore the zero slot. mstore(0x40, m) // Restore the free memory pointer. break } } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ERC1271 OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns whether `signature` is valid for `hash` /// for an ERC1271 `signer` contract. function isValidERC1271SignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool isValid) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) let f := shl(224, 0x1626ba7e) mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. mstore(add(m, 0x04), hash) let d := add(m, 0x24) mstore(d, 0x40) // The offset of the `signature` in the calldata. // Copy the `signature` over. let n := add(0x20, mload(signature)) pop(staticcall(gas(), 4, signature, n, add(m, 0x44), n)) // forgefmt: disable-next-item isValid := and( // Whether the returndata is the magic value `0x1626ba7e` (left-aligned). eq(mload(d), f), // Whether the staticcall does not revert. // This must be placed at the end of the `and` clause, // as the arguments are evaluated from right to left. staticcall( gas(), // Remaining gas. signer, // The `signer` address. m, // Offset of calldata in memory. add(returndatasize(), 0x44), // Length of calldata in memory. d, // Offset of returndata. 0x20 // Length of returndata to write. ) ) } } /// @dev Returns whether `signature` is valid for `hash` /// for an ERC1271 `signer` contract. function isValidERC1271SignatureNowCalldata( address signer, bytes32 hash, bytes calldata signature ) internal view returns (bool isValid) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) let f := shl(224, 0x1626ba7e) mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. mstore(add(m, 0x04), hash) let d := add(m, 0x24) mstore(d, 0x40) // The offset of the `signature` in the calldata. mstore(add(m, 0x44), signature.length) // Copy the `signature` over. calldatacopy(add(m, 0x64), signature.offset, signature.length) // forgefmt: disable-next-item isValid := and( // Whether the returndata is the magic value `0x1626ba7e` (left-aligned). eq(mload(d), f), // Whether the staticcall does not revert. // This must be placed at the end of the `and` clause, // as the arguments are evaluated from right to left. staticcall( gas(), // Remaining gas. signer, // The `signer` address. m, // Offset of calldata in memory. add(signature.length, 0x64), // Length of calldata in memory. d, // Offset of returndata. 0x20 // Length of returndata to write. ) ) } } /// @dev Returns whether the signature (`r`, `vs`) is valid for `hash` /// for an ERC1271 `signer` contract. function isValidERC1271SignatureNow(address signer, bytes32 hash, bytes32 r, bytes32 vs) internal view returns (bool isValid) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) let f := shl(224, 0x1626ba7e) mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. mstore(add(m, 0x04), hash) let d := add(m, 0x24) mstore(d, 0x40) // The offset of the `signature` in the calldata. mstore(add(m, 0x44), 65) // Length of the signature. mstore(add(m, 0x64), r) // `r`. mstore(add(m, 0x84), shr(1, shl(1, vs))) // `s`. mstore8(add(m, 0xa4), add(shr(255, vs), 27)) // `v`. // forgefmt: disable-next-item isValid := and( // Whether the returndata is the magic value `0x1626ba7e` (left-aligned). eq(mload(d), f), // Whether the staticcall does not revert. // This must be placed at the end of the `and` clause, // as the arguments are evaluated from right to left. staticcall( gas(), // Remaining gas. signer, // The `signer` address. m, // Offset of calldata in memory. 0xa5, // Length of calldata in memory. d, // Offset of returndata. 0x20 // Length of returndata to write. ) ) } } /// @dev Returns whether the signature (`v`, `r`, `s`) is valid for `hash` /// for an ERC1271 `signer` contract. function isValidERC1271SignatureNow(address signer, bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal view returns (bool isValid) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) let f := shl(224, 0x1626ba7e) mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. mstore(add(m, 0x04), hash) let d := add(m, 0x24) mstore(d, 0x40) // The offset of the `signature` in the calldata. mstore(add(m, 0x44), 65) // Length of the signature. mstore(add(m, 0x64), r) // `r`. mstore(add(m, 0x84), s) // `s`. mstore8(add(m, 0xa4), v) // `v`. // forgefmt: disable-next-item isValid := and( // Whether the returndata is the magic value `0x1626ba7e` (left-aligned). eq(mload(d), f), // Whether the staticcall does not revert. // This must be placed at the end of the `and` clause, // as the arguments are evaluated from right to left. staticcall( gas(), // Remaining gas. signer, // The `signer` address. m, // Offset of calldata in memory. 0xa5, // Length of calldata in memory. d, // Offset of returndata. 0x20 // Length of returndata to write. ) ) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* EMPTY CALLDATA HELPERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns an empty calldata bytes. function emptySignature() internal pure returns (bytes calldata signature) { /// @solidity memory-safe-assembly assembly { signature.length := 0 } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Library for compressing and decompressing bytes. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibZip.sol) /// @author Calldata compression by clabby (https://github.com/clabby/op-kompressor) /// @author FastLZ by ariya (https://github.com/ariya/FastLZ) /// /// @dev Note: /// The accompanying solady.js library includes implementations of /// FastLZ and calldata operations for convenience. library LibZip { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* FAST LZ OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ // LZ77 implementation based on FastLZ. // Equivalent to level 1 compression and decompression at the following commit: // https://github.com/ariya/FastLZ/commit/344eb4025f9ae866ebf7a2ec48850f7113a97a42 // Decompression is backwards compatible. /// @dev Returns the compressed `data`. function flzCompress(bytes memory data) internal pure returns (bytes memory result) { /// @solidity memory-safe-assembly assembly { function ms8(d_, v_) -> _d { mstore8(d_, v_) _d := add(d_, 1) } function u24(p_) -> _u { let w := mload(p_) _u := or(shl(16, byte(2, w)), or(shl(8, byte(1, w)), byte(0, w))) } function cmp(p_, q_, e_) -> _l { for { e_ := sub(e_, q_) } lt(_l, e_) { _l := add(_l, 1) } { e_ := mul(iszero(byte(0, xor(mload(add(p_, _l)), mload(add(q_, _l))))), e_) } } function literals(runs_, src_, dest_) -> _o { for { _o := dest_ } iszero(lt(runs_, 0x20)) { runs_ := sub(runs_, 0x20) } { mstore(ms8(_o, 31), mload(src_)) _o := add(_o, 0x21) src_ := add(src_, 0x20) } if iszero(runs_) { leave } mstore(ms8(_o, sub(runs_, 1)), mload(src_)) _o := add(1, add(_o, runs_)) } function match(l_, d_, o_) -> _o { for { d_ := sub(d_, 1) } iszero(lt(l_, 263)) { l_ := sub(l_, 262) } { o_ := ms8(ms8(ms8(o_, add(224, shr(8, d_))), 253), and(0xff, d_)) } if iszero(lt(l_, 7)) { _o := ms8(ms8(ms8(o_, add(224, shr(8, d_))), sub(l_, 7)), and(0xff, d_)) leave } _o := ms8(ms8(o_, add(shl(5, l_), shr(8, d_))), and(0xff, d_)) } function setHash(i_, v_) { let p := add(mload(0x40), shl(2, i_)) mstore(p, xor(mload(p), shl(224, xor(shr(224, mload(p)), v_)))) } function getHash(i_) -> _h { _h := shr(224, mload(add(mload(0x40), shl(2, i_)))) } function hash(v_) -> _r { _r := and(shr(19, mul(2654435769, v_)), 0x1fff) } function setNextHash(ip_, ipStart_) -> _ip { setHash(hash(u24(ip_)), sub(ip_, ipStart_)) _ip := add(ip_, 1) } codecopy(mload(0x40), codesize(), 0x8000) // Zeroize the hashmap. let op := add(mload(0x40), 0x8000) let a := add(data, 0x20) let ipStart := a let ipLimit := sub(add(ipStart, mload(data)), 13) for { let ip := add(2, a) } lt(ip, ipLimit) {} { let r := 0 let d := 0 for {} 1 {} { let s := u24(ip) let h := hash(s) r := add(ipStart, getHash(h)) setHash(h, sub(ip, ipStart)) d := sub(ip, r) if iszero(lt(ip, ipLimit)) { break } ip := add(ip, 1) if iszero(gt(d, 0x1fff)) { if eq(s, u24(r)) { break } } } if iszero(lt(ip, ipLimit)) { break } ip := sub(ip, 1) if gt(ip, a) { op := literals(sub(ip, a), a, op) } let l := cmp(add(r, 3), add(ip, 3), add(ipLimit, 9)) op := match(l, d, op) ip := setNextHash(setNextHash(add(ip, l), ipStart), ipStart) a := ip } op := literals(sub(add(ipStart, mload(data)), a), a, op) result := mload(0x40) let t := add(result, 0x8000) let n := sub(op, t) mstore(result, n) // Store the length. // Copy the result to compact the memory, overwriting the hashmap. let o := add(result, 0x20) for { let i } lt(i, n) { i := add(i, 0x20) } { mstore(add(o, i), mload(add(t, i))) } mstore(add(o, n), 0) // Zeroize the slot after the string. mstore(0x40, add(add(o, n), 0x20)) // Allocate the memory. } } /// @dev Returns the decompressed `data`. function flzDecompress(bytes memory data) internal pure returns (bytes memory result) { /// @solidity memory-safe-assembly assembly { let n := 0 let end := add(add(data, 0x20), mload(data)) result := mload(0x40) let op := add(result, 0x20) for { data := add(data, 0x20) } lt(data, end) {} { let w := mload(data) let c := byte(0, w) let t := shr(5, c) if iszero(t) { mstore(add(op, n), mload(add(data, 1))) data := add(data, add(2, c)) n := add(n, add(1, c)) continue } let g := eq(t, 7) let l := add(2, xor(t, mul(g, xor(t, add(7, byte(1, w)))))) for { let s := add(add(shl(8, and(0x1f, c)), byte(add(1, g), w)), 1) let r := add(op, sub(n, s)) let o := add(op, n) let f := xor(s, mul(gt(s, 0x20), xor(s, 0x20))) let j := 0 } 1 {} { mstore(add(o, j), mload(add(r, j))) j := add(j, f) if iszero(lt(j, l)) { break } } data := add(data, add(2, g)) n := add(n, l) } mstore(result, n) // Store the length. let o := add(add(result, 0x20), n) mstore(o, 0) // Zeroize the slot after the string. mstore(0x40, add(o, 0x20)) // Allocate the memory. } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CALLDATA OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ // Calldata compression and decompression using selective run length encoding: // - Sequences of 0x00 (up to 128 consecutive). // - Sequences of 0xff (up to 32 consecutive). // // A run length encoded block consists of two bytes: // (0) 0x00 // (1) A control byte with the following bit layout: // - [7] `0: 0x00, 1: 0xff`. // - [0..6] `runLength - 1`. // // The first 4 bytes are bitwise negated so that the compressed calldata // can be dispatched into the `fallback` and `receive` functions. /// @dev Returns the compressed `data`. function cdCompress(bytes memory data) internal pure returns (bytes memory result) { /// @solidity memory-safe-assembly assembly { function rle(v_, o_, d_) -> _o, _d { mstore(o_, shl(240, or(and(0xff, add(d_, 0xff)), and(0x80, v_)))) _o := add(o_, 2) } result := mload(0x40) let o := add(result, 0x20) let z := 0 // Number of consecutive 0x00. let y := 0 // Number of consecutive 0xff. for { let end := add(data, mload(data)) } iszero(eq(data, end)) {} { data := add(data, 1) let c := byte(31, mload(data)) if iszero(c) { if y { o, y := rle(0xff, o, y) } z := add(z, 1) if eq(z, 0x80) { o, z := rle(0x00, o, 0x80) } continue } if eq(c, 0xff) { if z { o, z := rle(0x00, o, z) } y := add(y, 1) if eq(y, 0x20) { o, y := rle(0xff, o, 0x20) } continue } if y { o, y := rle(0xff, o, y) } if z { o, z := rle(0x00, o, z) } mstore8(o, c) o := add(o, 1) } if y { o, y := rle(0xff, o, y) } if z { o, z := rle(0x00, o, z) } // Bitwise negate the first 4 bytes. mstore(add(result, 4), not(mload(add(result, 4)))) mstore(result, sub(o, add(result, 0x20))) // Store the length. mstore(o, 0) // Zeroize the slot after the string. mstore(0x40, add(o, 0x20)) // Allocate the memory. } } /// @dev Returns the decompressed `data`. function cdDecompress(bytes memory data) internal pure returns (bytes memory result) { /// @solidity memory-safe-assembly assembly { if mload(data) { result := mload(0x40) let o := add(result, 0x20) let s := add(data, 4) let v := mload(s) let end := add(data, mload(data)) mstore(s, not(v)) // Bitwise negate the first 4 bytes. for {} lt(data, end) {} { data := add(data, 1) let c := byte(31, mload(data)) if iszero(c) { data := add(data, 1) let d := byte(31, mload(data)) // Fill with either 0xff or 0x00. mstore(o, not(0)) if iszero(gt(d, 0x7f)) { codecopy(o, codesize(), add(d, 1)) } o := add(o, add(and(d, 0x7f), 1)) continue } mstore8(o, c) o := add(o, 1) } mstore(s, v) // Restore the first 4 bytes. mstore(result, sub(o, add(result, 0x20))) // Store the length. mstore(o, 0) // Zeroize the slot after the string. mstore(0x40, add(o, 0x20)) // Allocate the memory. } } } /// @dev To be called in the `receive` and `fallback` functions. /// ``` /// receive() external payable { LibZip.cdFallback(); } /// fallback() external payable { LibZip.cdFallback(); } /// ``` /// For efficiency, this function will directly return the results, terminating the context. /// If called internally, it must be called at the end of the function. function cdFallback() internal { assembly { if iszero(calldatasize()) { return(calldatasize(), calldatasize()) } let o := 0 let f := not(3) // For negating the first 4 bytes. for { let i := 0 } lt(i, calldatasize()) {} { let c := byte(0, xor(add(i, f), calldataload(i))) i := add(i, 1) if iszero(c) { let d := byte(0, xor(add(i, f), calldataload(i))) i := add(i, 1) // Fill with either 0xff or 0x00. mstore(o, not(0)) if iszero(gt(d, 0x7f)) { codecopy(o, codesize(), add(d, 1)) } o := add(o, add(and(d, 0x7f), 1)) continue } mstore8(o, c) o := add(o, 1) } let success := delegatecall(gas(), address(), 0x00, o, 0x00, 0x00) returndatacopy(0x00, 0x00, returndatasize()) if iszero(success) { revert(0x00, returndatasize()) } return(0x00, returndatasize()) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Library for storage of packed unsigned integers. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibMap.sol) library LibMap { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* STRUCTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev A uint8 map in storage. struct Uint8Map { mapping(uint256 => uint256) map; } /// @dev A uint16 map in storage. struct Uint16Map { mapping(uint256 => uint256) map; } /// @dev A uint32 map in storage. struct Uint32Map { mapping(uint256 => uint256) map; } /// @dev A uint40 map in storage. Useful for storing timestamps up to 34841 A.D. struct Uint40Map { mapping(uint256 => uint256) map; } /// @dev A uint64 map in storage. struct Uint64Map { mapping(uint256 => uint256) map; } /// @dev A uint128 map in storage. struct Uint128Map { mapping(uint256 => uint256) map; } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* GETTERS / SETTERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the uint8 value at `index` in `map`. function get(Uint8Map storage map, uint256 index) internal view returns (uint8 result) { /// @solidity memory-safe-assembly assembly { mstore(0x20, map.slot) mstore(0x00, shr(5, index)) result := byte(and(31, not(index)), sload(keccak256(0x00, 0x40))) } } /// @dev Updates the uint8 value at `index` in `map`. function set(Uint8Map storage map, uint256 index, uint8 value) internal { /// @solidity memory-safe-assembly assembly { mstore(0x20, map.slot) mstore(0x00, shr(5, index)) let s := keccak256(0x00, 0x40) // Storage slot. mstore(0x00, sload(s)) mstore8(and(31, not(index)), value) sstore(s, mload(0x00)) } } /// @dev Returns the uint16 value at `index` in `map`. function get(Uint16Map storage map, uint256 index) internal view returns (uint16 result) { result = uint16(map.map[index >> 4] >> ((index & 15) << 4)); } /// @dev Updates the uint16 value at `index` in `map`. function set(Uint16Map storage map, uint256 index, uint16 value) internal { /// @solidity memory-safe-assembly assembly { mstore(0x20, map.slot) mstore(0x00, shr(4, index)) let s := keccak256(0x00, 0x40) // Storage slot. let o := shl(4, and(index, 15)) // Storage slot offset (bits). let v := sload(s) // Storage slot value. let m := 0xffff // Value mask. sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value))))) } } /// @dev Returns the uint32 value at `index` in `map`. function get(Uint32Map storage map, uint256 index) internal view returns (uint32 result) { result = uint32(map.map[index >> 3] >> ((index & 7) << 5)); } /// @dev Updates the uint32 value at `index` in `map`. function set(Uint32Map storage map, uint256 index, uint32 value) internal { /// @solidity memory-safe-assembly assembly { mstore(0x20, map.slot) mstore(0x00, shr(3, index)) let s := keccak256(0x00, 0x40) // Storage slot. let o := shl(5, and(index, 7)) // Storage slot offset (bits). let v := sload(s) // Storage slot value. let m := 0xffffffff // Value mask. sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value))))) } } /// @dev Returns the uint40 value at `index` in `map`. function get(Uint40Map storage map, uint256 index) internal view returns (uint40 result) { unchecked { result = uint40(map.map[index / 6] >> ((index % 6) * 40)); } } /// @dev Updates the uint40 value at `index` in `map`. function set(Uint40Map storage map, uint256 index, uint40 value) internal { /// @solidity memory-safe-assembly assembly { mstore(0x20, map.slot) mstore(0x00, div(index, 6)) let s := keccak256(0x00, 0x40) // Storage slot. let o := mul(40, mod(index, 6)) // Storage slot offset (bits). let v := sload(s) // Storage slot value. let m := 0xffffffffff // Value mask. sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value))))) } } /// @dev Returns the uint64 value at `index` in `map`. function get(Uint64Map storage map, uint256 index) internal view returns (uint64 result) { result = uint64(map.map[index >> 2] >> ((index & 3) << 6)); } /// @dev Updates the uint64 value at `index` in `map`. function set(Uint64Map storage map, uint256 index, uint64 value) internal { /// @solidity memory-safe-assembly assembly { mstore(0x20, map.slot) mstore(0x00, shr(2, index)) let s := keccak256(0x00, 0x40) // Storage slot. let o := shl(6, and(index, 3)) // Storage slot offset (bits). let v := sload(s) // Storage slot value. let m := 0xffffffffffffffff // Value mask. sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value))))) } } /// @dev Returns the uint128 value at `index` in `map`. function get(Uint128Map storage map, uint256 index) internal view returns (uint128 result) { result = uint128(map.map[index >> 1] >> ((index & 1) << 7)); } /// @dev Updates the uint128 value at `index` in `map`. function set(Uint128Map storage map, uint256 index, uint128 value) internal { /// @solidity memory-safe-assembly assembly { mstore(0x20, map.slot) mstore(0x00, shr(1, index)) let s := keccak256(0x00, 0x40) // Storage slot. let o := shl(7, and(index, 1)) // Storage slot offset (bits). let v := sload(s) // Storage slot value. let m := 0xffffffffffffffffffffffffffffffff // Value mask. sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value))))) } } /// @dev Returns the value at `index` in `map`. function get(mapping(uint256 => uint256) storage map, uint256 index, uint256 bitWidth) internal view returns (uint256 result) { unchecked { uint256 d = _rawDiv(256, bitWidth); // Bucket size. uint256 m = (1 << bitWidth) - 1; // Value mask. result = (map[_rawDiv(index, d)] >> (_rawMod(index, d) * bitWidth)) & m; } } /// @dev Updates the value at `index` in `map`. function set( mapping(uint256 => uint256) storage map, uint256 index, uint256 value, uint256 bitWidth ) internal { unchecked { uint256 d = _rawDiv(256, bitWidth); // Bucket size. uint256 m = (1 << bitWidth) - 1; // Value mask. uint256 o = _rawMod(index, d) * bitWidth; // Storage slot offset (bits). map[_rawDiv(index, d)] ^= (((map[_rawDiv(index, d)] >> o) ^ value) & m) << o; } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* BINARY SEARCH */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ // The following functions search in the range of [`start`, `end`) // (i.e. `start <= index < end`). // The range must be sorted in ascending order. // `index` precedence: equal to > nearest before > nearest after. // An invalid search range will simply return `(found = false, index = start)`. /// @dev Returns whether `map` contains `needle`, and the index of `needle`. function searchSorted(Uint8Map storage map, uint8 needle, uint256 start, uint256 end) internal view returns (bool found, uint256 index) { return searchSorted(map.map, needle, start, end, 8); } /// @dev Returns whether `map` contains `needle`, and the index of `needle`. function searchSorted(Uint16Map storage map, uint16 needle, uint256 start, uint256 end) internal view returns (bool found, uint256 index) { return searchSorted(map.map, needle, start, end, 16); } /// @dev Returns whether `map` contains `needle`, and the index of `needle`. function searchSorted(Uint32Map storage map, uint32 needle, uint256 start, uint256 end) internal view returns (bool found, uint256 index) { return searchSorted(map.map, needle, start, end, 32); } /// @dev Returns whether `map` contains `needle`, and the index of `needle`. function searchSorted(Uint40Map storage map, uint40 needle, uint256 start, uint256 end) internal view returns (bool found, uint256 index) { return searchSorted(map.map, needle, start, end, 40); } /// @dev Returns whether `map` contains `needle`, and the index of `needle`. function searchSorted(Uint64Map storage map, uint64 needle, uint256 start, uint256 end) internal view returns (bool found, uint256 index) { return searchSorted(map.map, needle, start, end, 64); } /// @dev Returns whether `map` contains `needle`, and the index of `needle`. function searchSorted(Uint128Map storage map, uint128 needle, uint256 start, uint256 end) internal view returns (bool found, uint256 index) { return searchSorted(map.map, needle, start, end, 128); } /// @dev Returns whether `map` contains `needle`, and the index of `needle`. function searchSorted( mapping(uint256 => uint256) storage map, uint256 needle, uint256 start, uint256 end, uint256 bitWidth ) internal view returns (bool found, uint256 index) { unchecked { if (start >= end) end = start; uint256 t; uint256 o = start - 1; // Offset to derive the actual index. uint256 l = 1; // Low. uint256 d = _rawDiv(256, bitWidth); // Bucket size. uint256 m = (1 << bitWidth) - 1; // Value mask. uint256 h = end - start; // High. while (true) { index = (l & h) + ((l ^ h) >> 1); if (l > h) break; t = (map[_rawDiv(index + o, d)] >> (_rawMod(index + o, d) * bitWidth)) & m; if (t == needle) break; if (needle <= t) h = index - 1; else l = index + 1; } /// @solidity memory-safe-assembly assembly { m := or(iszero(index), iszero(bitWidth)) found := iszero(or(xor(t, needle), m)) index := add(o, xor(index, mul(xor(index, 1), m))) } } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* PRIVATE HELPERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns `x / y`, returning 0 if `y` is zero. function _rawDiv(uint256 x, uint256 y) private pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { z := div(x, y) } } /// @dev Returns `x % y`, returning 0 if `y` is zero. function _rawMod(uint256 x, uint256 y) private pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { z := mod(x, y) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; library DelegateCashLib { address internal constant REGISTRY_V2 = 0x00000000000000447e69651d841bD8D104Bed493; function checkDelegateForAll(address delegate, address vault) internal view returns (bool result) { assembly { // Cache the free memory pointer. let m := mload(0x40) // Store the function selector of `checkDelegateForAll(address,address,bytes32)`. mstore(0x00, 0xe839bd53) // Store the `delegate`. mstore(0x20, delegate) // Store the `vault`. mstore(0x40, vault) // The `bytes32 right` argument points to 0x60, which is zero. // Arguments are evaulated last to first. result := and( // The returndata is 1, which represents a bool true. eq(mload(0x00), 1), // The staticcall is successful. staticcall(gas(), REGISTRY_V2, 0x1c, 0x64, 0x00, 0x20) ) // Restore the free memory pointer. mstore(0x40, m) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; /** * @title LibOps * @dev Shared utilities. */ library LibOps { // ============================================================= // ERRORS // ============================================================= /** * @dev Error for overflows. */ error Overflow(); /** * @dev Error for unauthorized access. */ error Unauthorized(); // ============================================================= // CONSTANTS // ============================================================= /** * @dev A role every minter module must have in order to mint new tokens. * IMPORTANT: This constant must NEVER be changed! * It will always be 2 across all past and future sound protocol contracts. */ uint256 internal constant MINTER_ROLE = 1 << 1; /** * @dev A role the owner can grant for performing admin actions. * IMPORTANT: This constant must NEVER be changed! * It will always be 1 across all past and future sound protocol contracts. */ uint256 internal constant ADMIN_ROLE = 1 << 0; /** * @dev Basis points denominator used in fee calculations. * IMPORTANT: This constant must NEVER be changed! * It will always be 10000 across all past and future sound protocol contracts. */ uint16 internal constant BPS_DENOMINATOR = 10000; // ============================================================= // FUNCTIONS // ============================================================= /** * @dev `isOn ? flag : 0`. */ function toFlag(bool isOn, uint8 flag) internal pure returns (uint8 result) { assembly { result := mul(iszero(iszero(isOn)), flag) } } /** * @dev `(flags & flag != 0) != isOn ? flags ^ flag : flags`. * Sets `flag` in `flags` to 1 if `isOn` is true. * Sets `flag` in `flags` to 0 if `isOn` is false. */ function setFlagTo( uint8 flags, uint8 flag, bool isOn ) internal pure returns (uint8 result) { assembly { result := xor(flags, mul(xor(iszero(and(0xff, and(flags, flag))), iszero(isOn)), flag)) } } /** * @dev `x > y ? x : y`. */ function max(uint256 x, uint256 y) internal pure returns (uint256 z) { assembly { z := xor(x, mul(xor(x, y), gt(y, x))) } } /** * @dev `x < y ? x : y`. */ function min(uint256 x, uint256 y) internal pure returns (uint256 z) { assembly { z := xor(x, mul(xor(x, y), lt(y, x))) } } /** * @dev `(a * b) / d`. Returns 0 if `d` is zero. */ function rawMulDiv( uint256 a, uint256 b, uint256 d ) internal pure returns (uint256 z) { assembly { z := div(mul(a, b), d) } } /** * @dev `a / d`. Returns 0 if `d` is zero. */ function rawMod(uint256 a, uint256 d) internal pure returns (uint256 z) { assembly { z := mod(a, d) } } /** * @dev `a | b`. */ function or(bool a, bool b) internal pure returns (bool z) { assembly { z := or(iszero(iszero(a)), iszero(iszero(b))) } } /** * @dev `a | b | c`. */ function or( bool a, bool b, bool c ) internal pure returns (bool z) { z = or(a, or(b, c)); } /** * @dev `a | b | c | d`. */ function or( bool a, bool b, bool c, bool d ) internal pure returns (bool z) { z = or(a, or(b, or(c, d))); } /** * @dev `a & b`. */ function and(bool a, bool b) internal pure returns (bool z) { assembly { z := and(iszero(iszero(a)), iszero(iszero(b))) } } /** * @dev `x == 0 ? type(uint256).max : x` */ function maxIfZero(uint256 x) internal pure returns (uint256 z) { assembly { z := sub(x, iszero(x)) } } /** * @dev Packs an address and an index to create an unique identifier. * @param a The address. * @param i The index. * @return result The packed result. */ function packId(address a, uint96 i) internal pure returns (uint256 result) { assembly { result := or(shl(96, a), shr(160, shl(160, i))) } } /** * @dev Packs `edition`, `tier`, `scheduleNum` to create an unique identifier. * @param edition The address of the Sound Edition. * @param tier The tier. * @param scheduleNum The edition-tier schedule number. * @return result The packed result. */ function packId( address edition, uint8 tier, uint8 scheduleNum ) internal pure returns (uint256 result) { assembly { mstore(0x00, shl(96, edition)) mstore8(0x1e, tier) mstore8(0x1f, scheduleNum) result := mload(0x00) } } /** * @dev `revert Overflow()`. */ function revertOverflow() internal pure { assembly { mstore(0x00, 0x35278d12) // `Overflow()`. revert(0x1c, 0x04) } } /** * @dev `revert Unauthorized()`. */ function revertUnauthorized() internal pure { assembly { mstore(0x00, 0x82b42900) // `Unauthorized()`. revert(0x1c, 0x04) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /** * @title LibMulticaller * @author vectorized.eth * @notice Library to read the `msg.sender` of the multicaller with sender contract. */ library LibMulticaller { /** * @dev The address of the multicaller contract. */ address internal constant MULTICALLER = 0x0000000000009448722dAF1A55EF6D1E71FB162d; /** * @dev The address of the multicaller with sender contract. */ address internal constant MULTICALLER_WITH_SENDER = 0x00000000002Fd5Aeb385D324B580FCa7c83823A0; /** * @dev The address of the multicaller with signer contract. */ address internal constant MULTICALLER_WITH_SIGNER = 0x000000000000a89360A6a4786b9B33266F208AF4; /** * @dev Returns the caller of `aggregateWithSender` on `MULTICALLER_WITH_SENDER`. */ function multicallerSender() internal view returns (address result) { /// @solidity memory-safe-assembly assembly { mstore(0x00, 0x00) if iszero(staticcall(gas(), MULTICALLER_WITH_SENDER, 0x00, 0x00, 0x00, 0x20)) { revert(0x00, 0x00) // For better gas estimation. } result := mload(0x00) } } /** * @dev Returns the signer of `aggregateWithSigner` on `MULTICALLER_WITH_SIGNER`. */ function multicallerSigner() internal view returns (address result) { /// @solidity memory-safe-assembly assembly { mstore(0x00, 0x00) if iszero(staticcall(gas(), MULTICALLER_WITH_SIGNER, 0x00, 0x00, 0x00, 0x20)) { revert(0x00, 0x00) // For better gas estimation. } result := mload(0x00) } } /** * @dev Returns the caller of `aggregateWithSender` on `MULTICALLER_WITH_SENDER`, * if the current context's `msg.sender` is `MULTICALLER_WITH_SENDER`. * Otherwise, returns `msg.sender`. */ function sender() internal view returns (address result) { /// @solidity memory-safe-assembly assembly { mstore(0x00, caller()) let withSender := MULTICALLER_WITH_SENDER if eq(caller(), withSender) { if iszero(staticcall(gas(), withSender, 0x00, 0x00, 0x00, 0x20)) { revert(0x00, 0x00) // For better gas estimation. } } result := mload(0x00) } } /** * @dev Returns the caller of `aggregateWithSender` on `MULTICALLER_WITH_SENDER`, * if the current context's `msg.sender` is `MULTICALLER_WITH_SENDER`. * Returns the signer of `aggregateWithSigner` on `MULTICALLER_WITH_SIGNER`, * if the current context's `msg.sender` is `MULTICALLER_WITH_SIGNER`. * Otherwise, returns `msg.sender`. */ function senderOrSigner() internal view returns (address result) { /// @solidity memory-safe-assembly assembly { mstore(0x00, caller()) let withSender := MULTICALLER_WITH_SENDER if eq(caller(), withSender) { if iszero(staticcall(gas(), withSender, 0x00, 0x00, 0x00, 0x20)) { revert(0x00, 0x00) // For better gas estimation. } } let withSigner := MULTICALLER_WITH_SIGNER if eq(caller(), withSigner) { if iszero(staticcall(gas(), withSigner, 0x00, 0x00, 0x00, 0x20)) { revert(0x00, 0x00) // For better gas estimation. } } result := mload(0x00) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Simple single owner authorization mixin. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol) /// /// @dev Note: /// This implementation does NOT auto-initialize the owner to `msg.sender`. /// You MUST call the `_initializeOwner` in the constructor / initializer. /// /// While the ownable portion follows /// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility, /// the nomenclature for the 2-step ownership handover may be unique to this codebase. abstract contract Ownable { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The caller is not authorized to call the function. error Unauthorized(); /// @dev The `newOwner` cannot be the zero address. error NewOwnerIsZeroAddress(); /// @dev The `pendingOwner` does not have a valid handover request. error NoHandoverRequest(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* EVENTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The ownership is transferred from `oldOwner` to `newOwner`. /// This event is intentionally kept the same as OpenZeppelin's Ownable to be /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173), /// despite it not being as lightweight as a single argument event. event OwnershipTransferred(address indexed oldOwner, address indexed newOwner); /// @dev An ownership handover to `pendingOwner` has been requested. event OwnershipHandoverRequested(address indexed pendingOwner); /// @dev The ownership handover to `pendingOwner` has been canceled. event OwnershipHandoverCanceled(address indexed pendingOwner); /// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`. uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE = 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0; /// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`. uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE = 0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d; /// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`. uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE = 0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* STORAGE */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The owner slot is given by: `not(_OWNER_SLOT_NOT)`. /// It is intentionally chosen to be a high value /// to avoid collision with lower slots. /// The choice of manual storage layout is to enable compatibility /// with both regular and upgradeable contracts. uint256 private constant _OWNER_SLOT_NOT = 0x8b78c6d8; /// The ownership handover slot of `newOwner` is given by: /// ``` /// mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED)) /// let handoverSlot := keccak256(0x00, 0x20) /// ``` /// It stores the expiry timestamp of the two-step ownership handover. uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Initializes the owner directly without authorization guard. /// This function must be called upon initialization, /// regardless of whether the contract is upgradeable or not. /// This is to enable generalization to both regular and upgradeable contracts, /// and to save gas in case the initial owner is not the caller. /// For performance reasons, this function will not check if there /// is an existing owner. function _initializeOwner(address newOwner) internal virtual { /// @solidity memory-safe-assembly assembly { // Clean the upper 96 bits. newOwner := shr(96, shl(96, newOwner)) // Store the new value. sstore(not(_OWNER_SLOT_NOT), newOwner) // Emit the {OwnershipTransferred} event. log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner) } } /// @dev Sets the owner directly without authorization guard. function _setOwner(address newOwner) internal virtual { /// @solidity memory-safe-assembly assembly { let ownerSlot := not(_OWNER_SLOT_NOT) // Clean the upper 96 bits. newOwner := shr(96, shl(96, newOwner)) // Emit the {OwnershipTransferred} event. log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner) // Store the new value. sstore(ownerSlot, newOwner) } } /// @dev Throws if the sender is not the owner. function _checkOwner() internal view virtual { /// @solidity memory-safe-assembly assembly { // If the caller is not the stored owner, revert. if iszero(eq(caller(), sload(not(_OWNER_SLOT_NOT)))) { mstore(0x00, 0x82b42900) // `Unauthorized()`. revert(0x1c, 0x04) } } } /// @dev Returns how long a two-step ownership handover is valid for in seconds. /// Override to return a different value if needed. /// Made internal to conserve bytecode. Wrap it in a public function if needed. function _ownershipHandoverValidFor() internal view virtual returns (uint64) { return 48 * 3600; } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* PUBLIC UPDATE FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Allows the owner to transfer the ownership to `newOwner`. function transferOwnership(address newOwner) public payable virtual onlyOwner { /// @solidity memory-safe-assembly assembly { if iszero(shl(96, newOwner)) { mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`. revert(0x1c, 0x04) } } _setOwner(newOwner); } /// @dev Allows the owner to renounce their ownership. function renounceOwnership() public payable virtual onlyOwner { _setOwner(address(0)); } /// @dev Request a two-step ownership handover to the caller. /// The request will automatically expire in 48 hours (172800 seconds) by default. function requestOwnershipHandover() public payable virtual { unchecked { uint256 expires = block.timestamp + _ownershipHandoverValidFor(); /// @solidity memory-safe-assembly assembly { // Compute and set the handover slot to `expires`. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, caller()) sstore(keccak256(0x0c, 0x20), expires) // Emit the {OwnershipHandoverRequested} event. log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller()) } } } /// @dev Cancels the two-step ownership handover to the caller, if any. function cancelOwnershipHandover() public payable virtual { /// @solidity memory-safe-assembly assembly { // Compute and set the handover slot to 0. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, caller()) sstore(keccak256(0x0c, 0x20), 0) // Emit the {OwnershipHandoverCanceled} event. log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller()) } } /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`. /// Reverts if there is no existing ownership handover requested by `pendingOwner`. function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner { /// @solidity memory-safe-assembly assembly { // Compute and set the handover slot to 0. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, pendingOwner) let handoverSlot := keccak256(0x0c, 0x20) // If the handover does not exist, or has expired. if gt(timestamp(), sload(handoverSlot)) { mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`. revert(0x1c, 0x04) } // Set the handover slot to 0. sstore(handoverSlot, 0) } _setOwner(pendingOwner); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* PUBLIC READ FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the owner of the contract. function owner() public view virtual returns (address result) { /// @solidity memory-safe-assembly assembly { result := sload(not(_OWNER_SLOT_NOT)) } } /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`. function ownershipHandoverExpiresAt(address pendingOwner) public view virtual returns (uint256 result) { /// @solidity memory-safe-assembly assembly { // Compute the handover slot. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, pendingOwner) // Load the handover slot. result := sload(keccak256(0x0c, 0x20)) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* MODIFIERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Marks a function as only callable by the owner. modifier onlyOwner() virtual { _checkOwner(); _; } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721AUpgradeable { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables * (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, * checking first that contract recipients are aware of the ERC721 protocol * to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move * this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external payable; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) external view returns (bool); // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.0; import "../utils/introspection/IERC165Upgradeable.sol"; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. * * _Available since v4.5._ */ interface IERC2981Upgradeable is IERC165Upgradeable { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. */ function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address receiver, uint256 royaltyAmount); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; /** * @title IMetadataModule * @notice The interface for custom metadata modules. */ interface IMetadataModule { /** * @dev When implemented, SoundEdition's `tokenURI` redirects execution to this `tokenURI`. * @param tokenId The token ID to retrieve the token URI for. * @return The token URI string. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Library for bit twiddling and boolean operations. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibBit.sol) /// @author Inspired by (https://graphics.stanford.edu/~seander/bithacks.html) library LibBit { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* BIT TWIDDLING OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Find last set. /// Returns the index of the most significant bit of `x`, /// counting from the least significant bit position. /// If `x` is zero, returns 256. function fls(uint256 x) internal pure returns (uint256 r) { /// @solidity memory-safe-assembly assembly { r := or(shl(8, iszero(x)), shl(7, lt(0xffffffffffffffffffffffffffffffff, x))) r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) r := or(r, shl(4, lt(0xffff, shr(r, x)))) r := or(r, shl(3, lt(0xff, shr(r, x)))) r := or(r, shl(2, lt(0xf, shr(r, x)))) r := or(r, byte(shr(r, x), hex"00000101020202020303030303030303")) } } /// @dev Count leading zeros. /// Returns the number of zeros preceding the most significant one bit. /// If `x` is zero, returns 256. function clz(uint256 x) internal pure returns (uint256 r) { /// @solidity memory-safe-assembly assembly { r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x)) r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) r := or(r, shl(4, lt(0xffff, shr(r, x)))) r := or(r, shl(3, lt(0xff, shr(r, x)))) r := or(r, shl(2, lt(0xf, shr(r, x)))) // forgefmt: disable-next-item r := add(iszero(x), xor(255, or(r, byte(shr(r, x), hex"00000101020202020303030303030303")))) } } /// @dev Find first set. /// Returns the index of the least significant bit of `x`, /// counting from the least significant bit position. /// If `x` is zero, returns 256. /// Equivalent to `ctz` (count trailing zeros), which gives /// the number of zeros following the least significant one bit. function ffs(uint256 x) internal pure returns (uint256 r) { /// @solidity memory-safe-assembly assembly { // Isolate the least significant bit. let b := and(x, add(not(x), 1)) r := or(shl(8, iszero(x)), shl(7, lt(0xffffffffffffffffffffffffffffffff, b))) r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, b)))) r := or(r, shl(5, lt(0xffffffff, shr(r, b)))) // For the remaining 32 bits, use a De Bruijn lookup. // forgefmt: disable-next-item r := or(r, byte(and(div(0xd76453e0, shr(r, b)), 0x1f), 0x001f0d1e100c1d070f090b19131c1706010e11080a1a141802121b1503160405)) } } /// @dev Returns the number of set bits in `x`. function popCount(uint256 x) internal pure returns (uint256 c) { /// @solidity memory-safe-assembly assembly { let max := not(0) let isMax := eq(x, max) x := sub(x, and(shr(1, x), div(max, 3))) x := add(and(x, div(max, 5)), and(shr(2, x), div(max, 5))) x := and(add(x, shr(4, x)), div(max, 17)) c := or(shl(8, isMax), shr(248, mul(x, div(max, 255)))) } } /// @dev Returns whether `x` is a power of 2. function isPo2(uint256 x) internal pure returns (bool result) { /// @solidity memory-safe-assembly assembly { // Equivalent to `x && !(x & (x - 1))`. result := iszero(add(and(x, sub(x, 1)), iszero(x))) } } /// @dev Returns `x` reversed at the bit level. function reverseBits(uint256 x) internal pure returns (uint256 r) { /// @solidity memory-safe-assembly assembly { // Computing masks on-the-fly reduces bytecode size by about 500 bytes. let m := not(0) r := x for { let s := 128 } 1 {} { m := xor(m, shl(s, m)) r := or(and(shr(s, r), m), and(shl(s, r), not(m))) s := shr(1, s) if iszero(s) { break } } } } /// @dev Returns `x` reversed at the byte level. function reverseBytes(uint256 x) internal pure returns (uint256 r) { /// @solidity memory-safe-assembly assembly { // Computing masks on-the-fly reduces bytecode size by about 200 bytes. let m := not(0) r := x for { let s := 128 } 1 {} { m := xor(m, shl(s, m)) r := or(and(shr(s, r), m), and(shl(s, r), not(m))) s := shr(1, s) if eq(s, 4) { break } } } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* BOOLEAN OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ // A Solidity bool on the stack or memory is represented as a 256-bit word. // Non-zero values are true, zero is false. // A clean bool is either 0 (false) or 1 (true) under the hood. // Usually, if not always, the bool result of a regular Solidity expression, // or the argument of a public/external function will be a clean bool. // You can usually use the raw variants for more performance. // If uncertain, test (best with exact compiler settings). // Or use the non-raw variants (compiler can sometimes optimize out the double `iszero`s). /// @dev Returns `x & y`. Inputs must be clean. function rawAnd(bool x, bool y) internal pure returns (bool z) { /// @solidity memory-safe-assembly assembly { z := and(x, y) } } /// @dev Returns `x & y`. function and(bool x, bool y) internal pure returns (bool z) { /// @solidity memory-safe-assembly assembly { z := and(iszero(iszero(x)), iszero(iszero(y))) } } /// @dev Returns `x | y`. Inputs must be clean. function rawOr(bool x, bool y) internal pure returns (bool z) { /// @solidity memory-safe-assembly assembly { z := or(x, y) } } /// @dev Returns `x | y`. function or(bool x, bool y) internal pure returns (bool z) { /// @solidity memory-safe-assembly assembly { z := or(iszero(iszero(x)), iszero(iszero(y))) } } /// @dev Returns 1 if `b` is true, else 0. Input must be clean. function rawToUint(bool b) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { z := b } } /// @dev Returns 1 if `b` is true, else 0. function toUint(bool b) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { z := iszero(iszero(b)) } } }
{ "remappings": [ "openzeppelin/=lib/openzeppelin-contracts/contracts/", "openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", "chiru-labs/ERC721A-Upgradeable/=lib/ERC721A-Upgradeable/contracts/", "solady/=lib/solady/src/", "closedsea/=lib/closedsea/src/", "preapprove/=lib/preapprove/src/", "multicaller/=lib/multicaller/src/", "@core/=contracts/core/", "@modules/=contracts/modules/", "forge-std/=lib/forge-std/src/", "ERC721A-Upgradeable/=lib/ERC721A-Upgradeable/contracts/", "ds-test/=lib/solady/lib/ds-test/src/", "erc4626-tests/=lib/closedsea/lib/openzeppelin-contracts/lib/erc4626-tests/", "erc721a-upgradeable/=lib/multicaller/lib/erc721a-upgradeable/contracts/", "erc721a/=lib/multicaller/lib/erc721a/contracts/", "murky/=lib/murky/src/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "operator-filter-registry/=lib/closedsea/lib/operator-filter-registry/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "evmVersion": "paris", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"CallerNotDelegated","type":"error"},{"inputs":[],"name":"ExceedsMaxPerAccount","type":"error"},{"inputs":[],"name":"ExceedsMintSupply","type":"error"},{"inputs":[],"name":"ExceedsSignedQuantity","type":"error"},{"inputs":[],"name":"InvalidAffiliate","type":"error"},{"inputs":[],"name":"InvalidAffiliateFeeBPS","type":"error"},{"inputs":[],"name":"InvalidMaxMintableRange","type":"error"},{"inputs":[],"name":"InvalidMerkleProof","type":"error"},{"inputs":[],"name":"InvalidMode","type":"error"},{"inputs":[],"name":"InvalidPlatformFeeBPS","type":"error"},{"inputs":[],"name":"InvalidPlatformFeeConfig","type":"error"},{"inputs":[],"name":"InvalidPlatformFlatFee","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"InvalidTimeRange","type":"error"},{"inputs":[],"name":"MaxMintableIsZero","type":"error"},{"inputs":[],"name":"MaxMintablePerAccountIsZero","type":"error"},{"inputs":[],"name":"MerkleRootIsEmpty","type":"error"},{"inputs":[],"name":"MintDoesNotExist","type":"error"},{"inputs":[{"internalType":"uint256","name":"blockTimestamp","type":"uint256"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"}],"name":"MintNotOpen","type":"error"},{"inputs":[],"name":"MintPaused","type":"error"},{"inputs":[],"name":"MintsAlreadyExist","type":"error"},{"inputs":[],"name":"NotConfigurable","type":"error"},{"inputs":[],"name":"PlatformFeeAddressIsZero","type":"error"},{"inputs":[],"name":"SignatureAlreadyUsed","type":"error"},{"inputs":[],"name":"SignatureExpired","type":"error"},{"inputs":[],"name":"SignedPriceTooLow","type":"error"},{"inputs":[],"name":"SignerIsZeroAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"paid","type":"uint256"},{"internalType":"uint256","name":"required","type":"uint256"}],"name":"WrongPayment","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":false,"internalType":"uint16","name":"bps","type":"uint16"}],"name":"AffiliateFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"affiliate","type":"address"},{"indexed":false,"internalType":"uint256","name":"accrued","type":"uint256"}],"name":"AffiliateFeesWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":false,"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"AffiliateMerkleRootSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"platform","type":"address"},{"components":[{"internalType":"uint96","name":"perTxFlat","type":"uint96"},{"internalType":"uint96","name":"perMintFlat","type":"uint96"},{"internalType":"uint16","name":"perMintBPS","type":"uint16"},{"internalType":"bool","name":"active","type":"bool"}],"indexed":false,"internalType":"struct ISuperMinter.PlatformFeeConfig","name":"config","type":"tuple"}],"name":"DefaultPlatformFeeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"platform","type":"address"},{"indexed":false,"internalType":"uint96","name":"price","type":"uint96"}],"name":"GAPriceSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":false,"internalType":"uint32","name":"value","type":"uint32"}],"name":"MaxMintablePerAccountSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":false,"internalType":"uint32","name":"value","type":"uint32"}],"name":"MaxMintableSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":false,"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"name":"MerkleRootSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"components":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint96","name":"price","type":"uint96"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"},{"internalType":"uint32","name":"maxMintablePerAccount","type":"uint32"},{"internalType":"uint32","name":"maxMintable","type":"uint32"},{"internalType":"uint16","name":"affiliateFeeBPS","type":"uint16"},{"internalType":"bytes32","name":"affiliateMerkleRoot","type":"bytes32"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"address","name":"platform","type":"address"},{"internalType":"uint8","name":"mode","type":"uint8"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"indexed":false,"internalType":"struct ISuperMinter.MintCreation","name":"creation","type":"tuple"}],"name":"MintCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"components":[{"internalType":"uint32","name":"quantity","type":"uint32"},{"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"internalType":"address","name":"allowlisted","type":"address"},{"internalType":"uint32","name":"allowlistedQuantity","type":"uint32"},{"internalType":"uint32","name":"signedQuantity","type":"uint32"},{"internalType":"uint32","name":"signedClaimTicket","type":"uint32"},{"internalType":"address","name":"affiliate","type":"address"},{"internalType":"bool","name":"affiliated","type":"bool"},{"internalType":"uint256","name":"requiredEtherValue","type":"uint256"},{"internalType":"uint256","name":"unitPrice","type":"uint256"},{"internalType":"uint256","name":"platformFee","type":"uint256"},{"internalType":"uint256","name":"platformFlatFee","type":"uint256"},{"internalType":"uint256","name":"affiliateFee","type":"uint256"}],"indexed":false,"internalType":"struct ISuperMinter.MintedLogData","name":"data","type":"tuple"},{"indexed":true,"internalType":"uint256","name":"attributionId","type":"uint256"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"PausedSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"platform","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"}],"name":"PlatformFeeAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"platform","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"components":[{"internalType":"uint96","name":"perTxFlat","type":"uint96"},{"internalType":"uint96","name":"perMintFlat","type":"uint96"},{"internalType":"uint16","name":"perMintBPS","type":"uint16"},{"internalType":"bool","name":"active","type":"bool"}],"indexed":false,"internalType":"struct ISuperMinter.PlatformFeeConfig","name":"config","type":"tuple"}],"name":"PlatformFeeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"platform","type":"address"},{"indexed":false,"internalType":"uint256","name":"accrued","type":"uint256"}],"name":"PlatformFeesWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"platform","type":"address"},{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"PlatformSignerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":false,"internalType":"uint96","name":"price","type":"uint96"}],"name":"PriceSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"SignerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"indexed":false,"internalType":"uint32","name":"startTime","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"endTime","type":"uint32"}],"name":"TimeRangeSet","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"BPS_DENOMINATOR","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GA_TIER","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_AFFILIATE_FEE_BPS","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PLATFORM_PER_MINT_FEE_BPS","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PLATFORM_PER_MINT_FLAT_FEE","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PLATFORM_PER_TX_FLAT_FEE","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_TO_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERIFY_MERKLE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERIFY_SIGNATURE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"affiliateFeesAccrued","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"uint32[]","name":"claimTickets","type":"uint32[]"}],"name":"checkClaimTickets","outputs":[{"internalType":"bool[]","name":"claimed","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint32","name":"quantity","type":"uint32"},{"internalType":"address","name":"allowlisted","type":"address"},{"internalType":"uint32","name":"allowlistedQuantity","type":"uint32"},{"internalType":"bytes32[]","name":"allowlistProof","type":"bytes32[]"},{"internalType":"uint96","name":"signedPrice","type":"uint96"},{"internalType":"uint32","name":"signedQuantity","type":"uint32"},{"internalType":"uint32","name":"signedClaimTicket","type":"uint32"},{"internalType":"uint32","name":"signedDeadline","type":"uint32"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"address","name":"affiliate","type":"address"},{"internalType":"bytes32[]","name":"affiliateProof","type":"bytes32[]"},{"internalType":"uint256","name":"attributionId","type":"uint256"}],"internalType":"struct ISuperMinter.MintTo","name":"p","type":"tuple"}],"name":"computeMintToDigest","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint96","name":"price","type":"uint96"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"},{"internalType":"uint32","name":"maxMintablePerAccount","type":"uint32"},{"internalType":"uint32","name":"maxMintable","type":"uint32"},{"internalType":"uint16","name":"affiliateFeeBPS","type":"uint16"},{"internalType":"bytes32","name":"affiliateMerkleRoot","type":"bytes32"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"address","name":"platform","type":"address"},{"internalType":"uint8","name":"mode","type":"uint8"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"internalType":"struct ISuperMinter.MintCreation","name":"c","type":"tuple"}],"name":"createEditionMint","outputs":[{"internalType":"uint8","name":"scheduleNum","type":"uint8"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"platform","type":"address"}],"name":"defaultPlatformFeeConfig","outputs":[{"components":[{"internalType":"uint96","name":"perTxFlat","type":"uint96"},{"internalType":"uint96","name":"perMintFlat","type":"uint96"},{"internalType":"uint16","name":"perMintBPS","type":"uint16"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct ISuperMinter.PlatformFeeConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"platform","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"}],"name":"effectivePlatformFeeConfig","outputs":[{"components":[{"internalType":"uint96","name":"perTxFlat","type":"uint96"},{"internalType":"uint96","name":"perMintFlat","type":"uint96"},{"internalType":"uint16","name":"perMintBPS","type":"uint16"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct ISuperMinter.PlatformFeeConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"gaPrice","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"address","name":"affiliate","type":"address"}],"name":"isAffiliated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"address","name":"affiliate","type":"address"},{"internalType":"bytes32[]","name":"affiliateProof","type":"bytes32[]"}],"name":"isAffiliatedWithProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"}],"name":"mintInfo","outputs":[{"components":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"address","name":"platform","type":"address"},{"internalType":"uint96","name":"price","type":"uint96"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"},{"internalType":"uint32","name":"maxMintablePerAccount","type":"uint32"},{"internalType":"uint32","name":"maxMintable","type":"uint32"},{"internalType":"uint32","name":"minted","type":"uint32"},{"internalType":"uint16","name":"affiliateFeeBPS","type":"uint16"},{"internalType":"uint8","name":"mode","type":"uint8"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"hasMints","type":"bool"},{"internalType":"bytes32","name":"affiliateMerkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"bool","name":"usePlatformSigner","type":"bool"}],"internalType":"struct ISuperMinter.MintInfo","name":"info","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"}],"name":"mintInfoList","outputs":[{"components":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"address","name":"platform","type":"address"},{"internalType":"uint96","name":"price","type":"uint96"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"},{"internalType":"uint32","name":"maxMintablePerAccount","type":"uint32"},{"internalType":"uint32","name":"maxMintable","type":"uint32"},{"internalType":"uint32","name":"minted","type":"uint32"},{"internalType":"uint16","name":"affiliateFeeBPS","type":"uint16"},{"internalType":"uint8","name":"mode","type":"uint8"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"hasMints","type":"bool"},{"internalType":"bytes32","name":"affiliateMerkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"bool","name":"usePlatformSigner","type":"bool"}],"internalType":"struct ISuperMinter.MintInfo[]","name":"a","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint32","name":"quantity","type":"uint32"},{"internalType":"address","name":"allowlisted","type":"address"},{"internalType":"uint32","name":"allowlistedQuantity","type":"uint32"},{"internalType":"bytes32[]","name":"allowlistProof","type":"bytes32[]"},{"internalType":"uint96","name":"signedPrice","type":"uint96"},{"internalType":"uint32","name":"signedQuantity","type":"uint32"},{"internalType":"uint32","name":"signedClaimTicket","type":"uint32"},{"internalType":"uint32","name":"signedDeadline","type":"uint32"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"address","name":"affiliate","type":"address"},{"internalType":"bytes32[]","name":"affiliateProof","type":"bytes32[]"},{"internalType":"uint256","name":"attributionId","type":"uint256"}],"internalType":"struct ISuperMinter.MintTo","name":"p","type":"tuple"}],"name":"mintTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"name_","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"}],"name":"nextScheduleNum","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"address","name":"collector","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"platformFeeAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"platform","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"}],"name":"platformFeeConfig","outputs":[{"components":[{"internalType":"uint96","name":"perTxFlat","type":"uint96"},{"internalType":"uint96","name":"perMintFlat","type":"uint96"},{"internalType":"uint16","name":"perMintBPS","type":"uint16"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct ISuperMinter.PlatformFeeConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"platformFeesAccrued","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"platformSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"uint16","name":"bps","type":"uint16"}],"name":"setAffiliateFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"setAffiliateMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint96","name":"perTxFlat","type":"uint96"},{"internalType":"uint96","name":"perMintFlat","type":"uint96"},{"internalType":"uint16","name":"perMintBPS","type":"uint16"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct ISuperMinter.PlatformFeeConfig","name":"c","type":"tuple"}],"name":"setDefaultPlatformFeeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"price","type":"uint96"}],"name":"setGAPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"uint32","name":"value","type":"uint32"}],"name":"setMaxMintable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"uint32","name":"value","type":"uint32"}],"name":"setMaxMintablePerAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"bool","name":"paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"setPlatformFeeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"tier","type":"uint8"},{"components":[{"internalType":"uint96","name":"perTxFlat","type":"uint96"},{"internalType":"uint96","name":"perMintFlat","type":"uint96"},{"internalType":"uint16","name":"perMintBPS","type":"uint16"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct ISuperMinter.PlatformFeeConfig","name":"c","type":"tuple"}],"name":"setPlatformFeeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"setPlatformSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"uint96","name":"price","type":"uint96"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"address","name":"signer","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"uint32","name":"startTime","type":"uint32"}],"name":"setStartTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"}],"name":"setTimeRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"uint32","name":"quantity","type":"uint32"}],"name":"totalPriceAndFees","outputs":[{"components":[{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"subTotal","type":"uint256"},{"internalType":"uint256","name":"unitPrice","type":"uint256"},{"internalType":"uint256","name":"platformFee","type":"uint256"},{"internalType":"uint256","name":"platformFlatFee","type":"uint256"},{"internalType":"uint256","name":"platformTxFlatFee","type":"uint256"},{"internalType":"uint256","name":"platformMintFlatFee","type":"uint256"},{"internalType":"uint256","name":"platformMintBPSFee","type":"uint256"},{"internalType":"uint256","name":"affiliateFee","type":"uint256"}],"internalType":"struct ISuperMinter.TotalPriceAndFees","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint8","name":"scheduleNum","type":"uint8"},{"internalType":"uint32","name":"quantity","type":"uint32"},{"internalType":"uint96","name":"signedPrice","type":"uint96"}],"name":"totalPriceAndFeesWithSignedPrice","outputs":[{"components":[{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"subTotal","type":"uint256"},{"internalType":"uint256","name":"unitPrice","type":"uint256"},{"internalType":"uint256","name":"platformFee","type":"uint256"},{"internalType":"uint256","name":"platformFlatFee","type":"uint256"},{"internalType":"uint256","name":"platformTxFlatFee","type":"uint256"},{"internalType":"uint256","name":"platformMintFlatFee","type":"uint256"},{"internalType":"uint256","name":"platformMintBPSFee","type":"uint256"},{"internalType":"uint256","name":"affiliateFee","type":"uint256"}],"internalType":"struct ISuperMinter.TotalPriceAndFees","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"version_","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"affiliate","type":"address"}],"name":"withdrawForAffiliate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"platform","type":"address"}],"name":"withdrawForPlatform","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6101206040523480156200001257600080fd5b50306080524660a0526060806200005f604080518082018252600b81526a29bab832b926b4b73a32b960a91b602080830191909152825180840190935260018352603160f81b9083015291565b815160209283012081519183019190912060c082905260e0819052604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8152938401929092529082015246606082015230608082015260a090206101005250620000c99050565b60805160a05160c05160e051610100516146496200010e6000396000613428015260006134e2015260006134bc0152600061346c0152600061344901526146496000f3fe6080604052600436106103035760003560e01c8063a01efa3411610190578063de9484af116100dc578063e62a61a711610095578063f57402961161006f578063f574029614610b4e578063f7b2f1bf14610b6e578063fb128c8314610ab2578063fe1c0c4b14610b8357610312565b8063e62a61a714610aee578063edb3a0a314610b0e578063edcf0e2114610b2e57610312565b8063de9484af14610a19578063e1a4521814610a39578063e1f3e17d14610a4f578063e3d47d5c14610a85578063e4f6a4f014610ab2578063e544144314610ace57610312565b8063b985423111610149578063cbd8aff211610123578063cbd8aff214610976578063d03206a41461067a578063d379ab5f146109c4578063d3ec6f59146109e457610312565b8063b9854231146108d4578063bd3e8fc9146108f4578063c4f0c1c21461092857610312565b8063a01efa3414610805578063a167fd5f14610825578063ab9868971461083a578063ac1fc22c14610867578063b057868814610894578063b276be35146108b457610312565b8063532cf5961161024f57806370304e2f1161020857806387d4d28c116101e257806387d4d28c146107985780639375da5a146107c557806393e8bcf914610371578063998eb8c2146107e557610312565b806370304e2f146106a3578063752d8e91146106d057806384b0196e1461077057610312565b8063532cf5961461055a57806354fd4d50146105875780635e7876821461059c57806361b26ea41461063a5780636a7319cf1461065a5780636c5f55f71461067a57610312565b80631e1846c8116102bc57806344a8246f1161029657806344a8246f146104e75780634618d76214610507578063498120a0146105275780634a04a1c91461054757610312565b80631e1846c8146103f857806320606b70146104855780633b79c44f146104c757610312565b806301ffc9a71461031a57806306fdde031461034f5780630a25dea91461037157806315329da0146103985780631542b7fc146103b85780631b98e510146103d857610312565b3661031257610310610ba3565b005b610310610ba3565b34801561032657600080fd5b5061033a6103353660046137de565b610c3b565b60405190151581526020015b60405180910390f35b34801561035b57600080fd5b50610364610c66565b604051610346919061384e565b34801561037d57600080fd5b50610386600081565b60405160ff9091168152602001610346565b3480156103a457600080fd5b506103106103b3366004613892565b610c76565b3480156103c457600080fd5b506103106103d33660046138ea565b610da9565b3480156103e457600080fd5b506103866103f3366004613937565b610e31565b34801561040457600080fd5b50610418610413366004613980565b610e69565b6040516103469190600061012082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015160e083015261010080840151818401525092915050565b34801561049157600080fd5b506104b97f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b604051908152602001610346565b3480156104d357600080fd5b506103106104e23660046139d6565b610e8a565b3480156104f357600080fd5b506103106105023660046139f3565b610efe565b34801561051357600080fd5b50610310610522366004613980565b610fe6565b34801561053357600080fd5b50610310610542366004613a71565b6110c4565b610310610555366004613abc565b611190565b34801561056657600080fd5b5061057a610575366004613937565b6116af565b6040516103469190613af8565b34801561059357600080fd5b506103646117d7565b3480156105a857600080fd5b5061057a6105b73660046139d6565b604080516080808201835260008083526020808401829052838501829052606093840182905294831b6101001781526006855283902083519182018452546001600160601b038082168352600160601b82041694820194909452600160c01b840461ffff1692810192909252600160d01b90920460ff1615159181019190915290565b34801561064657600080fd5b50610310610655366004613b3a565b6117e1565b34801561066657600080fd5b5061033a610675366004613ba1565b61185a565b34801561068657600080fd5b506106906103e881565b60405161ffff9091168152602001610346565b3480156106af57600080fd5b506106c36106be366004613c2b565b61188a565b6040516103469190613ca3565b3480156106dc57600080fd5b5061057a6106eb366004613937565b604080516080808201835260008083526020808401829052838501829052606093840182905295831b60ff9586161781526006865283902083519182018452546001600160601b038082168352600160601b82041695820195909552600160c01b850461ffff1692810192909252600160d01b90930490911615159181019190915290565b34801561077c57600080fd5b5061078561196e565b6040516103469796959493929190613ce9565b3480156107a457600080fd5b506104b96107b33660046139d6565b60006020819052908152604090205481565b3480156107d157600080fd5b506103106107e03660046139d6565b611995565b3480156107f157600080fd5b50610310610800366004613e7e565b611a0a565b34801561081157600080fd5b506103106108203660046138ea565b611ade565b34801561083157600080fd5b50610386600281565b34801561084657600080fd5b5061085a6108553660046139d6565b611b91565b6040516103469190613fe7565b34801561087357600080fd5b506104b96108823660046139d6565b60026020526000908152604090205481565b3480156108a057600080fd5b506103106108af366004613980565b611c87565b3480156108c057600080fd5b506103106108cf366004613980565b611d81565b3480156108e057600080fd5b506103106108ef36600461402a565b611dc9565b34801561090057600080fd5b506104b97fc03e2545e609fd0b7813d6074f00235b048ae7580a8e57070eed03901dd951ae81565b34801561093457600080fd5b5061095e6109433660046139d6565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610346565b34801561098257600080fd5b506109ac6109913660046139d6565b6003602052600090815260409020546001600160601b031681565b6040516001600160601b039091168152602001610346565b3480156109d057600080fd5b506103106109df366004614055565b611ead565b3480156109f057600080fd5b50610a046109ff366004613892565b611f4c565b60405163ffffffff9091168152602001610346565b348015610a2557600080fd5b50610386610a343660046140a0565b611f99565b348015610a4557600080fd5b5061069061271081565b348015610a5b57600080fd5b5061095e610a6a3660046139d6565b6001602052600090815260409020546001600160a01b031681565b348015610a9157600080fd5b50610aa5610aa0366004614192565b612462565b60405161034691906141d7565b348015610abe57600080fd5b506109ac67016345785d8a000081565b348015610ada57600080fd5b50610310610ae93660046141e6565b6125f1565b348015610afa57600080fd5b506104b9610b09366004613abc565b6126a6565b348015610b1a57600080fd5b50610310610b293660046139d6565b6127eb565b348015610b3a57600080fd5b50610418610b49366004614233565b612891565b348015610b5a57600080fd5b50610310610b693660046139d6565b6128c7565b348015610b7a57600080fd5b50610386600181565b348015610b8f57600080fd5b5061033a610b9e366004613892565b612948565b36610bac573636f35b6000805b80368210610bbe5750610c1a565b600180830192600319810190351860001a9081610c0a57600019855260028301933560021984011860001a607f808211610bf9578282013888395b16949094019093019250610bb09050565b8185538085019450505050610bb0565b50600080826000305af490503d6000803e80610c35573d6000fd5b503d6000f35b60006301ffc9a760e01b6001600160e01b0319831690811463028b35ad60e31b909114175b92915050565b6060610c70612958565b50919050565b83610c8081612995565b6000610c8d868686612a98565b90506000610c9a82612ab4565b6001810154909150600160e81b900460ff16600214610ccc5760405163d25a973560e01b815260040160405180910390fd5b610cd584612af7565b6001818101546001600160a01b03861690911490610d0a9060ff600160f01b9091041660048360ff8383161615901518021890565b82600101601e6101000a81548160ff021916908360ff16021790555080610d49576004820180546001600160a01b0319166001600160a01b0387161790555b6040805160ff808a168252881660208201526001600160a01b0387811692820192909252908916907fc82787a128aa35191b6a1df922a24f581a06500f78030b89582d624c6ae9b2c9906060015b60405180910390a25050505050505050565b83610db381612995565b6000610dc0868686612a98565b90506000610dcd82612ab4565b600281018590556040805160ff808a168252881660208201529081018690529091506001600160a01b038816907fe08051cfd6c9341327f7f5550f77e02e815f59c1ecba22a4ac006ddca62dec20906060015b60405180910390a250505050505050565b600060056000610e4385856000612a98565b8152602081019190915260400160002060010154600160e01b900460ff16905092915050565b610e716136fe565b610e7f858585856000612891565b90505b949350505050565b6000610e94612b21565b6001600160a01b0381811660008181526004602090815260409182902080546001600160a01b03191694881694851790559051928352929350917fb9aba67a9619eecb4b3e9fe6ded4a35c9bcdbfb1040f5122f91716de616a799391015b60405180910390a25050565b84610f0881612995565b6000610f15878787612a98565b90506000610f2282612ab4565b905060ff8716158015610f3b575063ffffffff84811614155b15610f595760405163d25a973560e01b815260040160405180910390fd5b610f638585612b59565b60018101805463ffffffff87811667ffffffffffffffff199092168217640100000000918816918202179092556040805160ff808c1682528a1660208201529081019190915260608101919091526001600160a01b038916907f41ad9ed088bad8a3ad3052c7360f6919b647b45d4b527e478d463edbb8f9a43590608001610d97565b83610ff081612995565b6000610ffd868686612a98565b9050600061100a82612ab4565b905060ff861615801561102957506001810154600160e81b900460ff16155b156110475760405163d25a973560e01b815260040160405180910390fd5b61105084612b86565b60018101805463ffffffff60601b1916600160601b63ffffffff8716908102919091179091556040805160ff808a16825288166020820152908101919091526001600160a01b038816907f5da54689220406b0ee18edb07d2007345f96968da27c7fd0f405f649d26040a890606001610e20565b836110ce81612995565b60006110db868686612a98565b905060006110e882612ab4565b905060ff861615801561110a57506001810154600160e81b900460ff16600214155b156111285760405163d25a973560e01b815260040160405180910390fd5b80546001600160601b038516600160a01b81026001600160a01b039283161783556040805160ff8a811682528916602082015290810191909152908816907f3b082de0ef84f822f97496af03a3df5a8d5f0c271ea658b5b210819f1310494f90606001610e20565b60006111cf6111ca6111a560208501856139d6565b6111b5604086016020870161428e565b6111c5606087016040880161428e565b612a98565b612ab4565b600181015490915042640100000000820463ffffffff9081168211921611171561123657600181015460405163296f4f6960e01b815242600482015263ffffffff808316602483015264010000000090920490911660448201526064015b60405180910390fd5b61124d8160010154600160f01b9004600216151590565b1561126b57604051636be9245d60e11b815260040160405180910390fd5b6001810154600160e81b900460ff1660001981016112925761128d8284612bad565b6112a8565b60011960ff8216016112a8576112a88284612d2e565b6112b3818385612e67565b60006112f06112c8604086016020870161428e565b846112d960a08801608089016142a9565b6112eb61012089016101008a01613b3a565b6130b1565b905060008082600001513414611325578251604051630374cb4760e21b8152346004820152602481019190915260440161122d565b6060830151835186546001600160a01b03166000908152602081905260409020805483019055039150611377856113646101c089016101a08a016139d6565b6113726101c08a018a6142c4565b613221565b905080156113c5576101008301519182900391600260006113a06101c08a016101a08b016139d6565b6001600160a01b03168152602081019190915260400160002080549091019055611409565b60006113d96101c088016101a089016139d6565b6001600160a01b031614611400576040516320d6c38960e01b815260040160405180910390fd5b60006101008401525b600061141860208801886139d6565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915290915061149460a0890160808a016142a9565b63ffffffff1681526001600160a01b03821663eebab8ef856114bc60408c0160208d0161428e565b6114cc60808d0160608e016139d6565b6114dc60a08e0160808f016142a9565b6040516001600160e01b031960e087901b16815260ff90931660048401526001600160a01b03909116602483015263ffffffff16604482015260640160206040518083038185885af1158015611536573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061155b919061430e565b602082015261157060c0890160a08a016139d6565b6001600160a01b0316604082015261158e60e0890160c08a016142a9565b63ffffffff1660608201526115ab61016089016101408a016142a9565b63ffffffff1660a08201526115c86101c089016101a08a016139d6565b6001600160a01b031660c082015282151560e08201528451610100808301919091526040860151610120830152606080870151610140840152608080880151610160850152918701516101808401526101e08a01359161162d91908b01908b016139d6565b6001600160a01b031661164360208b018b6139d6565b6001600160a01b03167f2a29f7402bd32f0e4bbe17d44be064f7f64d96ee174ed7cb27936d869bf9a88861167d60408d0160208e0161428e565b61168d60608e0160408f0161428e565b8660405161169d93929190614327565b60405180910390a45050505050505050565b604080516080808201835260008083526020808401829052838501829052606080850183905260ff87811689831b178452600683529286902086519485018752546001600160601b038082168652600160601b8204169285019290925261ffff600160c01b83041695840195909552600160d01b900416151592810183905290916117a15760066000606086901b6101001781526020808201929092526040908101600020815160808101835290546001600160601b038082168352600160601b82041693820193909352600160c01b830461ffff1691810191909152600160d01b90910460ff161515606082015290505b80606001516117d057506040805160808101825260008082526020820181905291810182905260608101919091525b9392505050565b6060610c60612958565b60006117eb612b21565b6001600160a01b03811660008181526003602090815260409182902080546bffffffffffffffffffffffff19166001600160601b038816908117909155915191825292935090917fed3d3f99e57c78ce76ac9a1704a72bb912e8f231cc25c6379fdf5354dbb6481b9101610ef2565b600080611868888888612a98565b905061187e61187682612ab4565b868686613221565b98975050505050505050565b60606000611899878787612a98565b60008181526008602052604090209091508367ffffffffffffffff8111156118c3576118c3613d7f565b6040519080825280602002602001820160405280156118ec578160200160208202803683370190505b50925060005b8085146119625761193886868381811061190e5761190e614418565b905060200201602081019061192391906142a9565b63ffffffff168361327590919063ffffffff16565b84828151811061194a5761194a614418565b911515602092830291909101909101526001016118f2565b50505095945050505050565b600f60f81b6060806000808083611983612958565b97989097965046955030945091925090565b600061199f612b21565b90506119aa82613297565b6001600160a01b0381811660008181526001602090815260409182902080546001600160a01b0319169487169485179055905192835290917f3a9b87574e9f01aaafa6d829c77645fe96010be0b3093259c7873f4a93de28e99101610ef2565b6000611a14612b21565b9050611a1f826132be565b606081811b61010017600090815260066020908152604091829020855181549287015187850151958801511515600160d01b0260ff60d01b1961ffff909716600160c01b029690961662ffffff60c01b196001600160601b03928316600160601b026001600160c01b0319909616929093169190911793909317169190911792909217909155516001600160a01b038216907fec59616fef2c95b1d9e549c69e956a02fc10d12473c9667d711355ff224a2fe690610ef2908590613af8565b83611ae881612995565b6000611af5868686612a98565b90506000611b0282612ab4565b600180820154919250600160e81b90910460ff1614611b345760405163d25a973560e01b815260040160405180910390fd5b611b3d84613337565b600381018490556040805160ff8089168252871660208201529081018590526001600160a01b038816907f0b0a6fe894fe7695ac067d44d6e0de766337e9c3b5f0ee0a61be727383aac5a790606001610e20565b606081811b6000908152600560205260409020600181015461ffff600160d01b8204811691600160c01b9004168167ffffffffffffffff811115611bd757611bd7613d7f565b604051908082528060200260200182016040528015611c1057816020015b611bfd61374a565b815260200190600190039081611bf55790505b5093505b8115611c7f5761ffff8116606086901b176000908152600560205260409020611c458660ff600885901c1684612462565b85846001900394508481518110611c5e57611c5e614418565b602090810291909101015260010154600160b01b900461ffff169050611c14565b505050919050565b83611c9181612995565b6000611c9e868686612a98565b90506000611cab82612ab4565b905060ff8616611cce5760405163d25a973560e01b815260040160405180910390fd5b6001810154600119600160e81b90910460ff1601611cff5760405163d25a973560e01b815260040160405180910390fd5b611d0884613355565b6001810180546bffffffff00000000000000001916600160401b63ffffffff8716908102919091179091556040805160ff808a16825288166020820152908101919091526001600160a01b038816907f674233c20daf715ad9e94f9e5818adc53482b77e9556564e5fe3766678246e8e90606001610e20565b6000611d8e858585612a98565b600081815260056020526040902060010154909150611dc2908690869086908690640100000000900463ffffffff16610efe565b5050505050565b6000611dd3612b21565b9050611dde826132be565b606081811b60ff851617600090815260066020908152604091829020855181549287015187850151958801511515600160d01b0260ff60d01b1961ffff909716600160c01b029690961662ffffff60c01b196001600160601b03928316600160601b026001600160c01b0319909616929093169190911793909317169190911792909217909155516001600160a01b038216907f2e28b985b43becdaa221ff743fd386f80ace62daa5b69941fd6b51445ddaf4ee90611ea0908690869061442e565b60405180910390a2505050565b83611eb781612995565b6000611ec4868686612a98565b90506000611ed182612ab4565b9050611edc8461337c565b60018101805461ffff60a01b1916600160a01b61ffff8716908102919091179091556040805160ff808a16825288166020820152908101919091526001600160a01b038816907fcdff4ec2999e249a9a848accff5e46b43263f82c4076334cd70300e07326472d90606001610e20565b600080611f5a868686612a98565b6001600160a01b0384166000908152600760209081526040808320600385901c845290915290205490915060e0600583901b161c5b9695505050505050565b6000611fa88260000151612995565b611fb58260c0015161337c565b61014082015160ff8116611fd85760006101608401819052610180840152612049565b60001960ff821601611fff57611ff2836101800151613337565b6000610160840152612049565b60011960ff82160161203057612019836101600151612af7565b600061018084015263ffffffff6080840152612049565b60405163a0042b1760e01b815260040160405180910390fd5b61010083015160ff1661208d5763ffffffff60608401819052608084015260ff811660021461207a57600060208401525b60ff811661208d5763ffffffff60a08401525b61209f83604001518460600151612b59565b6120ac8360800151613355565b6120b98360a00151612b86565b6000600560006120d486600001518761010001516000612a98565b815260208082019290925260409081016000908120875160601b8252600590935220600180830154600160e01b900460ff169550919250908401610100811061211f5761211f6133c6565b6001808401805460ff909316600160e01b0260ff60e01b19909316929092179091558181015461ffff600160d01b9091041601620100008110612164576121646133c6565b60018201805461ffff60d01b1916600160d01b61ffff84160217905585516101008701516000916121959188612a98565b9050600060016001600160a01b03168861016001516001600160a01b031614905060006005600084815260200190815260200160002090508861012001518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555088602001518160000160146101000a8154816001600160601b0302191690836001600160601b0316021790555088604001518160010160006101000a81548163ffffffff021916908363ffffffff16021790555088606001518160010160046101000a81548163ffffffff021916908363ffffffff16021790555088608001518160010160086101000a81548163ffffffff021916908363ffffffff1602179055508860a0015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055508860c001518160010160146101000a81548161ffff021916908361ffff16021790555088610140015181600101601d6101000a81548160ff021916908360ff1602179055506123168260049015150290565b6001828101805460ff60f01b198116600160f01b94841760ff908116959095029081178355928901805468ff000000000000ffff60b01b1990921661ffff60b01b1990941693909317600160c01b9182900461ffff16600160b01b02179091556101008c0151825461ffff60c01b1916938c1660089190911b61ff0016170291909117905560e0890151156123b05760e089015160028201555b610180890151156123c75761018089015160038201555b6101608901516001600160a01b0316156124085781612408576101608901516004820180546001600160a01b0319166001600160a01b039092169190911790555b88600001516001600160a01b03167fcbaa8cb5ab7e807c363e8c49ecb8b778bb2217e8e7d375826e911413a4c734f48a61010001518a8c60405161244e93929190614479565b60405180910390a250505050505050919050565b61246a61374a565b6000612477858585612a98565b9050600061248482612ab4565b6001600160a01b03808816855260ff808816602087018190529087166040870152825490911660608601529091501580156124ce57506001810154600160e81b900460ff16600214155b6124e9578054600160a01b90046001600160601b031661250d565b80546001600160a01b03166000908152600360205260409020546001600160601b03165b6001600160601b03166080840152600181015463ffffffff80821660a08601526401000000008204811660c0860152600160401b8204811660e0860152600160601b82048116610100860152600160801b820416610120850152600160a01b810461ffff16610140850152600160e81b810460ff166101608501526002600160f01b909104811615156101808501528101546101c084015260038101546101e08401526125b9816133d4565b6001600160a01b03166102008401526125df8160010154600160f01b9004600416151590565b15156102208401525090949350505050565b836125fb81612995565b6000612608868686612a98565b9050600061261582612ab4565b600181015490915061263e9060ff600160f01b9091041660028660ff8383161615901518021890565b60018201805460ff60f01b1916600160f01b60ff938416021790556040805188831681529187166020830152851515908201526001600160a01b038816907f81bd379475659273b35365d353d46c7de87aa468a01efc54544fcee90ae0d3b690606001610e20565b6000610c607fc03e2545e609fd0b7813d6074f00235b048ae7580a8e57070eed03901dd951ae6126d960208501856139d6565b6126e9604086016020870161428e565b6126f9606087016040880161428e565b61270960808801606089016139d6565b61271b61014089016101208a016142a9565b61272d6101608a016101408b016142a9565b61273f6101208b016101008c01613b3a565b6127516101808c016101608d016142a9565b6127636101c08d016101a08e016139d6565b60408051602081019b909b526001600160a01b03998a16908b015260ff97881660608b015296909516608089015292861660a088015263ffffffff91821660c0880152811660e08701526001600160601b0390911661010086015216610120840152166101408201526101600160405160208183030381529060405280519060200120613424565b6001600160a01b038082166000908152600160205260409020541661280f81613297565b6001600160a01b038216600090815260208190526040902054801561288c576001600160a01b038316600090815260208190526040812055612851828261353f565b826001600160a01b03167ffc7ad544ff6a06d6499925723d25b6fe70457a42939995b1d3d6f560fe33633382604051611ea091815260200190565b505050565b6128996136fe565b60006128a6878787612a98565b90506128bc866128b583612ab4565b86866130b1565b979650505050505050565b6001600160a01b0381166000908152600260205260409020548015612944576001600160a01b038216600090815260026020526040812055612909828261353f565b816001600160a01b03167f0a1adaaf9d9caba9cf65528900e946b718d511ebd66ae81d5eb71e7fd0122c4a82604051610ef291815260200190565b5050565b6000610e7f85858585368661185a565b604080518082018252600b81526a29bab832b926b4b73a32b960a91b602080830191909152825180840190935260018352603160f81b9083015291565b600061299f612b21565b9050816001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129df573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a039190614592565b6001600160a01b0316816001600160a01b0316146129445760405163145398bf60e21b81526001600160a01b0382811660048301526001602483015283169063514e62fc90604401602060405180830381865afa158015612a68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a8c91906145af565b61294457612944613589565b60008360601b60005282601e5381601f53505060005192915050565b60008181526005602052604081206001808201549192600160f01b909204169003612af25760405163947dbacd60e01b815260040160405180910390fd5b919050565b6001600160a01b038116612b1e5760405163327effa960e11b815260040160405180910390fd5b50565b6000336000526e2fd5aeb385d324b580fca7c83823a0803303612b515760206000806000845afa612b5157600080fd5b505060005190565b8063ffffffff168263ffffffff1611156129445760405163536a71af60e01b815260040160405180910390fd5b8063ffffffff16600003612b1e57604051630ccae60160e31b815260040160405180910390fd5b6000612bbf60e0830160c084016142a9565b90506000612bd360c0840160a085016139d6565b90506001600160a01b038116612bfc5760405163582f497d60e11b815260040160405180910390fd5b63fffffffe1963ffffffff831601612c8757612c3b8460030154612c25836000526014600c2090565b612c3260e08701876142c4565b90929091613597565b158015612c645750612c628460030154612c258363ffffffff6004526000526018600c2090565b155b15612c825760405163582f497d60e11b815260040160405180910390fd5b612cbf565b612ca28460030154612c2583856004526000526018600c2090565b612cbf5760405163582f497d60e11b815260040160405180910390fd5b6000612cc9612b21565b9050612d036001600160a01b03838116908316811490612cef60808801606089016139d6565b6001600160a01b0316149015159015151790565b611dc257612d1181836135d1565b611dc25760405163fe736e0160e01b815260040160405180910390fd5b612d40610140820161012083016142a9565b63ffffffff16612d5660a08301608084016142a9565b63ffffffff161115612d7b576040516352ad28c360e11b815260040160405180910390fd5b6000612d86836133d4565b9050612da881612d95846126a6565b612da36101808601866145cc565b613612565b612dc557604051638baa579f60e01b815260040160405180910390fd5b612dd7610180830161016084016142a9565b63ffffffff16421115612dfd57604051630819bdcd60e01b815260040160405180910390fd5b6000612e0f6111a560208501856139d6565b9050612e44612e26610160850161014086016142a9565b60008381526008602052604090209063ffffffff908116906136bb16565b612e615760405163900bb2c960e01b815260040160405180910390fd5b50505050565b6000612e7960a08301608084016142a9565b600184015463ffffffff918216600160801b82048316019250600160601b900416811115612eba57604051637f70f90b60e01b815260040160405180910390fd5b60018301805463ffffffff60801b1916600160801b63ffffffff8416021790556000612eec6111a560208501856139d6565b905060001960ff861601612fe7576000600781612f0f60c0870160a088016139d6565b6001600160a01b0316815260208101919091526040016000209050612f3a60a08501608086016142a9565b63ffffffff16612f5383836133a390919063ffffffff16565b600187015463ffffffff918216929092019450612f9691600160401b9004168411612f8460e0870160c088016142a9565b63ffffffff1685119015159015151790565b15612fb457604051631b75136560e01b815260040160405180910390fd5b6020819052600382901c600090815260409020805460e0600585901b1681811c861863ffffffff16901b18905550611dc2565b6000600781612ffc60808701606088016139d6565b6001600160a01b031681526020810191909152604001600020905061302760a08501608086016142a9565b63ffffffff1661304083836133a390919063ffffffff16565b600187015463ffffffff918216929092019450600160401b9091041683111561307c57604051631b75136560e01b815260040160405180910390fd5b6020819052600382901c600090815260409020805460e0600585901b1681811c861863ffffffff16901b189055505050505050565b6130b96136fe565b83546000906130d1906001600160a01b0316876116af565b6001860154909150600090600119600160e81b90910460ff16016131355785546001600160601b03600160a01b909104811690851610156131255760405163dcdc2f1560e01b815260040160405180910390fd5b506001600160601b03831661317a565b60ff8716613166575084546001600160a01b03166000908152600360205260409020546001600160601b031661317a565b508454600160a01b90046001600160601b03165b604080840182905263ffffffff8616808302602080870182905285516001600160601b0390811660a08901819052918701511690920260c087018190529091016080860152908301516131d5919061ffff1661271091020490565b60e08401819052608084015101606084015260208301516001870154612710600160a01b90910461ffff1690910204610100840152505060808101516020820151018152949350505050565b6002840154600090806132415750506001600160a01b0383161515610e82565b611f8f6001600160a01b038616151561326c83613263896000526014600c2090565b88918891613597565b15159015151690565b600881901c6000908152602092909252604090912054600160ff9092161c1690565b6001600160a01b038116612b1e576040516362ccef3360e01b815260040160405180910390fd5b61331967016345785d8a00006001600160601b031682600001516001600160601b03161167016345785d8a00006001600160601b031683602001516001600160601b0316116103e861ffff16846040015161ffff16116136ea565b15612b1e5760405163b17424c360e01b815260040160405180910390fd5b80612b1e5760405163caa2867f60e01b815260040160405180910390fd5b8063ffffffff16600003612b1e5760405163a017714560e01b815260040160405180910390fd5b6103e861ffff82161115612b1e57604051631a52ce6f60e01b815260040160405180910390fd5b600381901c600090815260209290925260409091205460059190911b60e0161c90565b6335278d126000526004601cfd5b60006133ed8260010154600160f01b9004600416151590565b6134045760048201546001600160a01b0316610c60565b50546001600160a01b039081166000908152600460205260409020541690565b60007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000030147f00000000000000000000000000000000000000000000000000000000000000004614166135195750604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81527f000000000000000000000000000000000000000000000000000000000000000060208201527f00000000000000000000000000000000000000000000000000000000000000009181019190915246606082015230608082015260a090205b67190100000000000060005280601a5282603a52604260182091506000603a5250919050565b804710156135555763b12d13eb6000526004601cfd5b60005a60005a8486620186a0f161294457816000526073600b5360ff6020536016600b82f0612944575a60141c3d5a3e5050565b6382b429006000526004601cfd5b600083156135c9578360051b8501855b803580851160051b948552602094851852604060002093018181106135a75750505b501492915050565b600060405163e839bd536000528360205282604052602060006064601c6c447e69651d841bd8d104bed4935afa600160005114169150806040525092915050565b6001600160a01b039093169260008415610e8257604051604183036136705784600052604084013560001a602052604084604037602060016080600060015afa805187183d151761366e57506000606052604052506001610e82565b505b600060605280604052631626ba7e60e01b80825285600483015260248201604081528460448401528486606485013760208160648701858b5afa905190911416915050949350505050565b600881901c600090815260209290925260409091208054600160ff9093169290921b9182189081905516151590565b600083151583151583151517151517610e82565b6040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040805161024081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101829052610200810182905261022081019190915290565b6000602082840312156137f057600080fd5b81356001600160e01b0319811681146117d057600080fd5b6000815180845260005b8181101561382e57602081850181015186830182015201613812565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006117d06020830184613808565b6001600160a01b0381168114612b1e57600080fd5b8035612af281613861565b803560ff81168114612af257600080fd5b600080600080608085870312156138a857600080fd5b84356138b381613861565b93506138c160208601613881565b92506138cf60408601613881565b915060608501356138df81613861565b939692955090935050565b6000806000806080858703121561390057600080fd5b843561390b81613861565b935061391960208601613881565b925061392760408601613881565b9396929550929360600135925050565b6000806040838503121561394a57600080fd5b823561395581613861565b915061396360208401613881565b90509250929050565b803563ffffffff81168114612af257600080fd5b6000806000806080858703121561399657600080fd5b84356139a181613861565b93506139af60208601613881565b92506139bd60408601613881565b91506139cb6060860161396c565b905092959194509250565b6000602082840312156139e857600080fd5b81356117d081613861565b600080600080600060a08688031215613a0b57600080fd5b8535613a1681613861565b9450613a2460208701613881565b9350613a3260408701613881565b9250613a406060870161396c565b9150613a4e6080870161396c565b90509295509295909350565b80356001600160601b0381168114612af257600080fd5b60008060008060808587031215613a8757600080fd5b8435613a9281613861565b9350613aa060208601613881565b9250613aae60408601613881565b91506139cb60608601613a5a565b600060208284031215613ace57600080fd5b813567ffffffffffffffff811115613ae557600080fd5b820161020081850312156117d057600080fd5b60808101610c6082846001600160601b038082511683528060208301511660208401525061ffff60408201511660408301526060810151151560608301525050565b600060208284031215613b4c57600080fd5b6117d082613a5a565b60008083601f840112613b6757600080fd5b50813567ffffffffffffffff811115613b7f57600080fd5b6020830191508360208260051b8501011115613b9a57600080fd5b9250929050565b60008060008060008060a08789031215613bba57600080fd5b8635613bc581613861565b9550613bd360208801613881565b9450613be160408801613881565b93506060870135613bf181613861565b9250608087013567ffffffffffffffff811115613c0d57600080fd5b613c1989828a01613b55565b979a9699509497509295939492505050565b600080600080600060808688031215613c4357600080fd5b8535613c4e81613861565b9450613c5c60208701613881565b9350613c6a60408701613881565b9250606086013567ffffffffffffffff811115613c8657600080fd5b613c9288828901613b55565b969995985093965092949392505050565b6020808252825182820181905260009190848201906040850190845b81811015613cdd578351151583529284019291840191600101613cbf565b50909695505050505050565b60ff60f81b881681526000602060e081840152613d0960e084018a613808565b8381036040850152613d1b818a613808565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b81811015613d6d57835183529284019291840191600101613d51565b50909c9b505050505050505050505050565b634e487b7160e01b600052604160045260246000fd5b6040516101a0810167ffffffffffffffff81118282101715613dc757634e487b7160e01b600052604160045260246000fd5b60405290565b803561ffff81168114612af257600080fd5b8015158114612b1e57600080fd5b600060808284031215613dff57600080fd5b6040516080810181811067ffffffffffffffff82111715613e3057634e487b7160e01b600052604160045260246000fd5b604052905080613e3f83613a5a565b8152613e4d60208401613a5a565b6020820152613e5e60408401613dcd565b60408201526060830135613e7181613ddf565b6060919091015292915050565b600060808284031215613e9057600080fd5b6117d08383613ded565b80516001600160a01b031682526020810151613ebb602084018260ff169052565b506040810151613ed0604084018260ff169052565b506060810151613eeb60608401826001600160a01b03169052565b506080810151613f0660808401826001600160601b03169052565b5060a0810151613f1e60a084018263ffffffff169052565b5060c0810151613f3660c084018263ffffffff169052565b5060e0810151613f4e60e084018263ffffffff169052565b506101008181015163ffffffff9081169184019190915261012080830151909116908301526101408082015161ffff16908301526101608082015160ff1690830152610180808201511515908301526101a0808201511515908301526101c080820151908301526101e08082015190830152610200808201516001600160a01b0316908301526102208082015180151582850152612e61565b6020808252825182820181905260009190848201906040850190845b81811015613cdd57614016838551613e9a565b928401926102409290920191600101614003565b60008060a0838503121561403d57600080fd5b61404683613881565b91506139638460208501613ded565b6000806000806080858703121561406b57600080fd5b843561407681613861565b935061408460208601613881565b925061409260408601613881565b91506139cb60608601613dcd565b60006101a082840312156140b357600080fd5b6140bb613d95565b6140c483613876565b81526140d260208401613a5a565b60208201526140e36040840161396c565b60408201526140f46060840161396c565b60608201526141056080840161396c565b608082015261411660a0840161396c565b60a082015261412760c08401613dcd565b60c082015260e083013560e0820152610100614144818501613881565b90820152610120614156848201613876565b90820152610140614168848201613881565b9082015261016061417a848201613876565b90820152610180928301359281019290925250919050565b6000806000606084860312156141a757600080fd5b83356141b281613861565b92506141c060208501613881565b91506141ce60408501613881565b90509250925092565b6102408101610c608284613e9a565b600080600080608085870312156141fc57600080fd5b843561420781613861565b935061421560208601613881565b925061422360408601613881565b915060608501356138df81613ddf565b600080600080600060a0868803121561424b57600080fd5b853561425681613861565b945061426460208701613881565b935061427260408701613881565b92506142806060870161396c565b9150613a4e60808701613a5a565b6000602082840312156142a057600080fd5b6117d082613881565b6000602082840312156142bb57600080fd5b6117d08261396c565b6000808335601e198436030181126142db57600080fd5b83018035915067ffffffffffffffff8211156142f657600080fd5b6020019150600581901b3603821315613b9a57600080fd5b60006020828403121561432057600080fd5b5051919050565b60ff848116825283166020820152815163ffffffff1660408201526101e081016020830151606083015260408301516001600160a01b038116608084015250606083015163ffffffff811660a084015250608083015163ffffffff811660c08401525060a083015163ffffffff811660e08401525060c08301516101006143b8818501836001600160a01b03169052565b60e085015191506101206143cf8186018415159052565b908501516101408581019190915290850151610160808601919091529085015161018080860191909152908501516101a0850152909301516101c0909201919091529392505050565b634e487b7160e01b600052603260045260246000fd5b60ff8316815260a081016117d060208301846001600160601b038082511683528060208301511660208401525061ffff60408201511660408301526060810151151560608301525050565b60ff84811682528316602082015281516001600160a01b031660408201526101e0810160208301516001600160601b038116606084015250604083015163ffffffff8116608084015250606083015163ffffffff811660a084015250608083015163ffffffff811660c08401525060a083015163ffffffff811660e08401525060c08301516101006145108185018361ffff169052565b60e085015161012085810191909152908501519150610140906145378286018460ff169052565b8501519150610160614553858201846001600160a01b03169052565b9085015191506101809061456b8583018460ff169052565b8501516001600160a01b03166101a0850152909301516101c0909201919091529392505050565b6000602082840312156145a457600080fd5b81516117d081613861565b6000602082840312156145c157600080fd5b81516117d081613ddf565b6000808335601e198436030181126145e357600080fd5b83018035915067ffffffffffffffff8211156145fe57600080fd5b602001915036819003821315613b9a57600080fdfea264697066735822122082a9fe6d3c01d9f8932f133836ed974fec48211730542b3dc9d954d491f4065164736f6c63430008130033
Deployed Bytecode
0x6080604052600436106103035760003560e01c8063a01efa3411610190578063de9484af116100dc578063e62a61a711610095578063f57402961161006f578063f574029614610b4e578063f7b2f1bf14610b6e578063fb128c8314610ab2578063fe1c0c4b14610b8357610312565b8063e62a61a714610aee578063edb3a0a314610b0e578063edcf0e2114610b2e57610312565b8063de9484af14610a19578063e1a4521814610a39578063e1f3e17d14610a4f578063e3d47d5c14610a85578063e4f6a4f014610ab2578063e544144314610ace57610312565b8063b985423111610149578063cbd8aff211610123578063cbd8aff214610976578063d03206a41461067a578063d379ab5f146109c4578063d3ec6f59146109e457610312565b8063b9854231146108d4578063bd3e8fc9146108f4578063c4f0c1c21461092857610312565b8063a01efa3414610805578063a167fd5f14610825578063ab9868971461083a578063ac1fc22c14610867578063b057868814610894578063b276be35146108b457610312565b8063532cf5961161024f57806370304e2f1161020857806387d4d28c116101e257806387d4d28c146107985780639375da5a146107c557806393e8bcf914610371578063998eb8c2146107e557610312565b806370304e2f146106a3578063752d8e91146106d057806384b0196e1461077057610312565b8063532cf5961461055a57806354fd4d50146105875780635e7876821461059c57806361b26ea41461063a5780636a7319cf1461065a5780636c5f55f71461067a57610312565b80631e1846c8116102bc57806344a8246f1161029657806344a8246f146104e75780634618d76214610507578063498120a0146105275780634a04a1c91461054757610312565b80631e1846c8146103f857806320606b70146104855780633b79c44f146104c757610312565b806301ffc9a71461031a57806306fdde031461034f5780630a25dea91461037157806315329da0146103985780631542b7fc146103b85780631b98e510146103d857610312565b3661031257610310610ba3565b005b610310610ba3565b34801561032657600080fd5b5061033a6103353660046137de565b610c3b565b60405190151581526020015b60405180910390f35b34801561035b57600080fd5b50610364610c66565b604051610346919061384e565b34801561037d57600080fd5b50610386600081565b60405160ff9091168152602001610346565b3480156103a457600080fd5b506103106103b3366004613892565b610c76565b3480156103c457600080fd5b506103106103d33660046138ea565b610da9565b3480156103e457600080fd5b506103866103f3366004613937565b610e31565b34801561040457600080fd5b50610418610413366004613980565b610e69565b6040516103469190600061012082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015160e083015261010080840151818401525092915050565b34801561049157600080fd5b506104b97f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b604051908152602001610346565b3480156104d357600080fd5b506103106104e23660046139d6565b610e8a565b3480156104f357600080fd5b506103106105023660046139f3565b610efe565b34801561051357600080fd5b50610310610522366004613980565b610fe6565b34801561053357600080fd5b50610310610542366004613a71565b6110c4565b610310610555366004613abc565b611190565b34801561056657600080fd5b5061057a610575366004613937565b6116af565b6040516103469190613af8565b34801561059357600080fd5b506103646117d7565b3480156105a857600080fd5b5061057a6105b73660046139d6565b604080516080808201835260008083526020808401829052838501829052606093840182905294831b6101001781526006855283902083519182018452546001600160601b038082168352600160601b82041694820194909452600160c01b840461ffff1692810192909252600160d01b90920460ff1615159181019190915290565b34801561064657600080fd5b50610310610655366004613b3a565b6117e1565b34801561066657600080fd5b5061033a610675366004613ba1565b61185a565b34801561068657600080fd5b506106906103e881565b60405161ffff9091168152602001610346565b3480156106af57600080fd5b506106c36106be366004613c2b565b61188a565b6040516103469190613ca3565b3480156106dc57600080fd5b5061057a6106eb366004613937565b604080516080808201835260008083526020808401829052838501829052606093840182905295831b60ff9586161781526006865283902083519182018452546001600160601b038082168352600160601b82041695820195909552600160c01b850461ffff1692810192909252600160d01b90930490911615159181019190915290565b34801561077c57600080fd5b5061078561196e565b6040516103469796959493929190613ce9565b3480156107a457600080fd5b506104b96107b33660046139d6565b60006020819052908152604090205481565b3480156107d157600080fd5b506103106107e03660046139d6565b611995565b3480156107f157600080fd5b50610310610800366004613e7e565b611a0a565b34801561081157600080fd5b506103106108203660046138ea565b611ade565b34801561083157600080fd5b50610386600281565b34801561084657600080fd5b5061085a6108553660046139d6565b611b91565b6040516103469190613fe7565b34801561087357600080fd5b506104b96108823660046139d6565b60026020526000908152604090205481565b3480156108a057600080fd5b506103106108af366004613980565b611c87565b3480156108c057600080fd5b506103106108cf366004613980565b611d81565b3480156108e057600080fd5b506103106108ef36600461402a565b611dc9565b34801561090057600080fd5b506104b97fc03e2545e609fd0b7813d6074f00235b048ae7580a8e57070eed03901dd951ae81565b34801561093457600080fd5b5061095e6109433660046139d6565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610346565b34801561098257600080fd5b506109ac6109913660046139d6565b6003602052600090815260409020546001600160601b031681565b6040516001600160601b039091168152602001610346565b3480156109d057600080fd5b506103106109df366004614055565b611ead565b3480156109f057600080fd5b50610a046109ff366004613892565b611f4c565b60405163ffffffff9091168152602001610346565b348015610a2557600080fd5b50610386610a343660046140a0565b611f99565b348015610a4557600080fd5b5061069061271081565b348015610a5b57600080fd5b5061095e610a6a3660046139d6565b6001602052600090815260409020546001600160a01b031681565b348015610a9157600080fd5b50610aa5610aa0366004614192565b612462565b60405161034691906141d7565b348015610abe57600080fd5b506109ac67016345785d8a000081565b348015610ada57600080fd5b50610310610ae93660046141e6565b6125f1565b348015610afa57600080fd5b506104b9610b09366004613abc565b6126a6565b348015610b1a57600080fd5b50610310610b293660046139d6565b6127eb565b348015610b3a57600080fd5b50610418610b49366004614233565b612891565b348015610b5a57600080fd5b50610310610b693660046139d6565b6128c7565b348015610b7a57600080fd5b50610386600181565b348015610b8f57600080fd5b5061033a610b9e366004613892565b612948565b36610bac573636f35b6000805b80368210610bbe5750610c1a565b600180830192600319810190351860001a9081610c0a57600019855260028301933560021984011860001a607f808211610bf9578282013888395b16949094019093019250610bb09050565b8185538085019450505050610bb0565b50600080826000305af490503d6000803e80610c35573d6000fd5b503d6000f35b60006301ffc9a760e01b6001600160e01b0319831690811463028b35ad60e31b909114175b92915050565b6060610c70612958565b50919050565b83610c8081612995565b6000610c8d868686612a98565b90506000610c9a82612ab4565b6001810154909150600160e81b900460ff16600214610ccc5760405163d25a973560e01b815260040160405180910390fd5b610cd584612af7565b6001818101546001600160a01b03861690911490610d0a9060ff600160f01b9091041660048360ff8383161615901518021890565b82600101601e6101000a81548160ff021916908360ff16021790555080610d49576004820180546001600160a01b0319166001600160a01b0387161790555b6040805160ff808a168252881660208201526001600160a01b0387811692820192909252908916907fc82787a128aa35191b6a1df922a24f581a06500f78030b89582d624c6ae9b2c9906060015b60405180910390a25050505050505050565b83610db381612995565b6000610dc0868686612a98565b90506000610dcd82612ab4565b600281018590556040805160ff808a168252881660208201529081018690529091506001600160a01b038816907fe08051cfd6c9341327f7f5550f77e02e815f59c1ecba22a4ac006ddca62dec20906060015b60405180910390a250505050505050565b600060056000610e4385856000612a98565b8152602081019190915260400160002060010154600160e01b900460ff16905092915050565b610e716136fe565b610e7f858585856000612891565b90505b949350505050565b6000610e94612b21565b6001600160a01b0381811660008181526004602090815260409182902080546001600160a01b03191694881694851790559051928352929350917fb9aba67a9619eecb4b3e9fe6ded4a35c9bcdbfb1040f5122f91716de616a799391015b60405180910390a25050565b84610f0881612995565b6000610f15878787612a98565b90506000610f2282612ab4565b905060ff8716158015610f3b575063ffffffff84811614155b15610f595760405163d25a973560e01b815260040160405180910390fd5b610f638585612b59565b60018101805463ffffffff87811667ffffffffffffffff199092168217640100000000918816918202179092556040805160ff808c1682528a1660208201529081019190915260608101919091526001600160a01b038916907f41ad9ed088bad8a3ad3052c7360f6919b647b45d4b527e478d463edbb8f9a43590608001610d97565b83610ff081612995565b6000610ffd868686612a98565b9050600061100a82612ab4565b905060ff861615801561102957506001810154600160e81b900460ff16155b156110475760405163d25a973560e01b815260040160405180910390fd5b61105084612b86565b60018101805463ffffffff60601b1916600160601b63ffffffff8716908102919091179091556040805160ff808a16825288166020820152908101919091526001600160a01b038816907f5da54689220406b0ee18edb07d2007345f96968da27c7fd0f405f649d26040a890606001610e20565b836110ce81612995565b60006110db868686612a98565b905060006110e882612ab4565b905060ff861615801561110a57506001810154600160e81b900460ff16600214155b156111285760405163d25a973560e01b815260040160405180910390fd5b80546001600160601b038516600160a01b81026001600160a01b039283161783556040805160ff8a811682528916602082015290810191909152908816907f3b082de0ef84f822f97496af03a3df5a8d5f0c271ea658b5b210819f1310494f90606001610e20565b60006111cf6111ca6111a560208501856139d6565b6111b5604086016020870161428e565b6111c5606087016040880161428e565b612a98565b612ab4565b600181015490915042640100000000820463ffffffff9081168211921611171561123657600181015460405163296f4f6960e01b815242600482015263ffffffff808316602483015264010000000090920490911660448201526064015b60405180910390fd5b61124d8160010154600160f01b9004600216151590565b1561126b57604051636be9245d60e11b815260040160405180910390fd5b6001810154600160e81b900460ff1660001981016112925761128d8284612bad565b6112a8565b60011960ff8216016112a8576112a88284612d2e565b6112b3818385612e67565b60006112f06112c8604086016020870161428e565b846112d960a08801608089016142a9565b6112eb61012089016101008a01613b3a565b6130b1565b905060008082600001513414611325578251604051630374cb4760e21b8152346004820152602481019190915260440161122d565b6060830151835186546001600160a01b03166000908152602081905260409020805483019055039150611377856113646101c089016101a08a016139d6565b6113726101c08a018a6142c4565b613221565b905080156113c5576101008301519182900391600260006113a06101c08a016101a08b016139d6565b6001600160a01b03168152602081019190915260400160002080549091019055611409565b60006113d96101c088016101a089016139d6565b6001600160a01b031614611400576040516320d6c38960e01b815260040160405180910390fd5b60006101008401525b600061141860208801886139d6565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915290915061149460a0890160808a016142a9565b63ffffffff1681526001600160a01b03821663eebab8ef856114bc60408c0160208d0161428e565b6114cc60808d0160608e016139d6565b6114dc60a08e0160808f016142a9565b6040516001600160e01b031960e087901b16815260ff90931660048401526001600160a01b03909116602483015263ffffffff16604482015260640160206040518083038185885af1158015611536573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061155b919061430e565b602082015261157060c0890160a08a016139d6565b6001600160a01b0316604082015261158e60e0890160c08a016142a9565b63ffffffff1660608201526115ab61016089016101408a016142a9565b63ffffffff1660a08201526115c86101c089016101a08a016139d6565b6001600160a01b031660c082015282151560e08201528451610100808301919091526040860151610120830152606080870151610140840152608080880151610160850152918701516101808401526101e08a01359161162d91908b01908b016139d6565b6001600160a01b031661164360208b018b6139d6565b6001600160a01b03167f2a29f7402bd32f0e4bbe17d44be064f7f64d96ee174ed7cb27936d869bf9a88861167d60408d0160208e0161428e565b61168d60608e0160408f0161428e565b8660405161169d93929190614327565b60405180910390a45050505050505050565b604080516080808201835260008083526020808401829052838501829052606080850183905260ff87811689831b178452600683529286902086519485018752546001600160601b038082168652600160601b8204169285019290925261ffff600160c01b83041695840195909552600160d01b900416151592810183905290916117a15760066000606086901b6101001781526020808201929092526040908101600020815160808101835290546001600160601b038082168352600160601b82041693820193909352600160c01b830461ffff1691810191909152600160d01b90910460ff161515606082015290505b80606001516117d057506040805160808101825260008082526020820181905291810182905260608101919091525b9392505050565b6060610c60612958565b60006117eb612b21565b6001600160a01b03811660008181526003602090815260409182902080546bffffffffffffffffffffffff19166001600160601b038816908117909155915191825292935090917fed3d3f99e57c78ce76ac9a1704a72bb912e8f231cc25c6379fdf5354dbb6481b9101610ef2565b600080611868888888612a98565b905061187e61187682612ab4565b868686613221565b98975050505050505050565b60606000611899878787612a98565b60008181526008602052604090209091508367ffffffffffffffff8111156118c3576118c3613d7f565b6040519080825280602002602001820160405280156118ec578160200160208202803683370190505b50925060005b8085146119625761193886868381811061190e5761190e614418565b905060200201602081019061192391906142a9565b63ffffffff168361327590919063ffffffff16565b84828151811061194a5761194a614418565b911515602092830291909101909101526001016118f2565b50505095945050505050565b600f60f81b6060806000808083611983612958565b97989097965046955030945091925090565b600061199f612b21565b90506119aa82613297565b6001600160a01b0381811660008181526001602090815260409182902080546001600160a01b0319169487169485179055905192835290917f3a9b87574e9f01aaafa6d829c77645fe96010be0b3093259c7873f4a93de28e99101610ef2565b6000611a14612b21565b9050611a1f826132be565b606081811b61010017600090815260066020908152604091829020855181549287015187850151958801511515600160d01b0260ff60d01b1961ffff909716600160c01b029690961662ffffff60c01b196001600160601b03928316600160601b026001600160c01b0319909616929093169190911793909317169190911792909217909155516001600160a01b038216907fec59616fef2c95b1d9e549c69e956a02fc10d12473c9667d711355ff224a2fe690610ef2908590613af8565b83611ae881612995565b6000611af5868686612a98565b90506000611b0282612ab4565b600180820154919250600160e81b90910460ff1614611b345760405163d25a973560e01b815260040160405180910390fd5b611b3d84613337565b600381018490556040805160ff8089168252871660208201529081018590526001600160a01b038816907f0b0a6fe894fe7695ac067d44d6e0de766337e9c3b5f0ee0a61be727383aac5a790606001610e20565b606081811b6000908152600560205260409020600181015461ffff600160d01b8204811691600160c01b9004168167ffffffffffffffff811115611bd757611bd7613d7f565b604051908082528060200260200182016040528015611c1057816020015b611bfd61374a565b815260200190600190039081611bf55790505b5093505b8115611c7f5761ffff8116606086901b176000908152600560205260409020611c458660ff600885901c1684612462565b85846001900394508481518110611c5e57611c5e614418565b602090810291909101015260010154600160b01b900461ffff169050611c14565b505050919050565b83611c9181612995565b6000611c9e868686612a98565b90506000611cab82612ab4565b905060ff8616611cce5760405163d25a973560e01b815260040160405180910390fd5b6001810154600119600160e81b90910460ff1601611cff5760405163d25a973560e01b815260040160405180910390fd5b611d0884613355565b6001810180546bffffffff00000000000000001916600160401b63ffffffff8716908102919091179091556040805160ff808a16825288166020820152908101919091526001600160a01b038816907f674233c20daf715ad9e94f9e5818adc53482b77e9556564e5fe3766678246e8e90606001610e20565b6000611d8e858585612a98565b600081815260056020526040902060010154909150611dc2908690869086908690640100000000900463ffffffff16610efe565b5050505050565b6000611dd3612b21565b9050611dde826132be565b606081811b60ff851617600090815260066020908152604091829020855181549287015187850151958801511515600160d01b0260ff60d01b1961ffff909716600160c01b029690961662ffffff60c01b196001600160601b03928316600160601b026001600160c01b0319909616929093169190911793909317169190911792909217909155516001600160a01b038216907f2e28b985b43becdaa221ff743fd386f80ace62daa5b69941fd6b51445ddaf4ee90611ea0908690869061442e565b60405180910390a2505050565b83611eb781612995565b6000611ec4868686612a98565b90506000611ed182612ab4565b9050611edc8461337c565b60018101805461ffff60a01b1916600160a01b61ffff8716908102919091179091556040805160ff808a16825288166020820152908101919091526001600160a01b038816907fcdff4ec2999e249a9a848accff5e46b43263f82c4076334cd70300e07326472d90606001610e20565b600080611f5a868686612a98565b6001600160a01b0384166000908152600760209081526040808320600385901c845290915290205490915060e0600583901b161c5b9695505050505050565b6000611fa88260000151612995565b611fb58260c0015161337c565b61014082015160ff8116611fd85760006101608401819052610180840152612049565b60001960ff821601611fff57611ff2836101800151613337565b6000610160840152612049565b60011960ff82160161203057612019836101600151612af7565b600061018084015263ffffffff6080840152612049565b60405163a0042b1760e01b815260040160405180910390fd5b61010083015160ff1661208d5763ffffffff60608401819052608084015260ff811660021461207a57600060208401525b60ff811661208d5763ffffffff60a08401525b61209f83604001518460600151612b59565b6120ac8360800151613355565b6120b98360a00151612b86565b6000600560006120d486600001518761010001516000612a98565b815260208082019290925260409081016000908120875160601b8252600590935220600180830154600160e01b900460ff169550919250908401610100811061211f5761211f6133c6565b6001808401805460ff909316600160e01b0260ff60e01b19909316929092179091558181015461ffff600160d01b9091041601620100008110612164576121646133c6565b60018201805461ffff60d01b1916600160d01b61ffff84160217905585516101008701516000916121959188612a98565b9050600060016001600160a01b03168861016001516001600160a01b031614905060006005600084815260200190815260200160002090508861012001518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555088602001518160000160146101000a8154816001600160601b0302191690836001600160601b0316021790555088604001518160010160006101000a81548163ffffffff021916908363ffffffff16021790555088606001518160010160046101000a81548163ffffffff021916908363ffffffff16021790555088608001518160010160086101000a81548163ffffffff021916908363ffffffff1602179055508860a0015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055508860c001518160010160146101000a81548161ffff021916908361ffff16021790555088610140015181600101601d6101000a81548160ff021916908360ff1602179055506123168260049015150290565b6001828101805460ff60f01b198116600160f01b94841760ff908116959095029081178355928901805468ff000000000000ffff60b01b1990921661ffff60b01b1990941693909317600160c01b9182900461ffff16600160b01b02179091556101008c0151825461ffff60c01b1916938c1660089190911b61ff0016170291909117905560e0890151156123b05760e089015160028201555b610180890151156123c75761018089015160038201555b6101608901516001600160a01b0316156124085781612408576101608901516004820180546001600160a01b0319166001600160a01b039092169190911790555b88600001516001600160a01b03167fcbaa8cb5ab7e807c363e8c49ecb8b778bb2217e8e7d375826e911413a4c734f48a61010001518a8c60405161244e93929190614479565b60405180910390a250505050505050919050565b61246a61374a565b6000612477858585612a98565b9050600061248482612ab4565b6001600160a01b03808816855260ff808816602087018190529087166040870152825490911660608601529091501580156124ce57506001810154600160e81b900460ff16600214155b6124e9578054600160a01b90046001600160601b031661250d565b80546001600160a01b03166000908152600360205260409020546001600160601b03165b6001600160601b03166080840152600181015463ffffffff80821660a08601526401000000008204811660c0860152600160401b8204811660e0860152600160601b82048116610100860152600160801b820416610120850152600160a01b810461ffff16610140850152600160e81b810460ff166101608501526002600160f01b909104811615156101808501528101546101c084015260038101546101e08401526125b9816133d4565b6001600160a01b03166102008401526125df8160010154600160f01b9004600416151590565b15156102208401525090949350505050565b836125fb81612995565b6000612608868686612a98565b9050600061261582612ab4565b600181015490915061263e9060ff600160f01b9091041660028660ff8383161615901518021890565b60018201805460ff60f01b1916600160f01b60ff938416021790556040805188831681529187166020830152851515908201526001600160a01b038816907f81bd379475659273b35365d353d46c7de87aa468a01efc54544fcee90ae0d3b690606001610e20565b6000610c607fc03e2545e609fd0b7813d6074f00235b048ae7580a8e57070eed03901dd951ae6126d960208501856139d6565b6126e9604086016020870161428e565b6126f9606087016040880161428e565b61270960808801606089016139d6565b61271b61014089016101208a016142a9565b61272d6101608a016101408b016142a9565b61273f6101208b016101008c01613b3a565b6127516101808c016101608d016142a9565b6127636101c08d016101a08e016139d6565b60408051602081019b909b526001600160a01b03998a16908b015260ff97881660608b015296909516608089015292861660a088015263ffffffff91821660c0880152811660e08701526001600160601b0390911661010086015216610120840152166101408201526101600160405160208183030381529060405280519060200120613424565b6001600160a01b038082166000908152600160205260409020541661280f81613297565b6001600160a01b038216600090815260208190526040902054801561288c576001600160a01b038316600090815260208190526040812055612851828261353f565b826001600160a01b03167ffc7ad544ff6a06d6499925723d25b6fe70457a42939995b1d3d6f560fe33633382604051611ea091815260200190565b505050565b6128996136fe565b60006128a6878787612a98565b90506128bc866128b583612ab4565b86866130b1565b979650505050505050565b6001600160a01b0381166000908152600260205260409020548015612944576001600160a01b038216600090815260026020526040812055612909828261353f565b816001600160a01b03167f0a1adaaf9d9caba9cf65528900e946b718d511ebd66ae81d5eb71e7fd0122c4a82604051610ef291815260200190565b5050565b6000610e7f85858585368661185a565b604080518082018252600b81526a29bab832b926b4b73a32b960a91b602080830191909152825180840190935260018352603160f81b9083015291565b600061299f612b21565b9050816001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129df573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a039190614592565b6001600160a01b0316816001600160a01b0316146129445760405163145398bf60e21b81526001600160a01b0382811660048301526001602483015283169063514e62fc90604401602060405180830381865afa158015612a68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a8c91906145af565b61294457612944613589565b60008360601b60005282601e5381601f53505060005192915050565b60008181526005602052604081206001808201549192600160f01b909204169003612af25760405163947dbacd60e01b815260040160405180910390fd5b919050565b6001600160a01b038116612b1e5760405163327effa960e11b815260040160405180910390fd5b50565b6000336000526e2fd5aeb385d324b580fca7c83823a0803303612b515760206000806000845afa612b5157600080fd5b505060005190565b8063ffffffff168263ffffffff1611156129445760405163536a71af60e01b815260040160405180910390fd5b8063ffffffff16600003612b1e57604051630ccae60160e31b815260040160405180910390fd5b6000612bbf60e0830160c084016142a9565b90506000612bd360c0840160a085016139d6565b90506001600160a01b038116612bfc5760405163582f497d60e11b815260040160405180910390fd5b63fffffffe1963ffffffff831601612c8757612c3b8460030154612c25836000526014600c2090565b612c3260e08701876142c4565b90929091613597565b158015612c645750612c628460030154612c258363ffffffff6004526000526018600c2090565b155b15612c825760405163582f497d60e11b815260040160405180910390fd5b612cbf565b612ca28460030154612c2583856004526000526018600c2090565b612cbf5760405163582f497d60e11b815260040160405180910390fd5b6000612cc9612b21565b9050612d036001600160a01b03838116908316811490612cef60808801606089016139d6565b6001600160a01b0316149015159015151790565b611dc257612d1181836135d1565b611dc25760405163fe736e0160e01b815260040160405180910390fd5b612d40610140820161012083016142a9565b63ffffffff16612d5660a08301608084016142a9565b63ffffffff161115612d7b576040516352ad28c360e11b815260040160405180910390fd5b6000612d86836133d4565b9050612da881612d95846126a6565b612da36101808601866145cc565b613612565b612dc557604051638baa579f60e01b815260040160405180910390fd5b612dd7610180830161016084016142a9565b63ffffffff16421115612dfd57604051630819bdcd60e01b815260040160405180910390fd5b6000612e0f6111a560208501856139d6565b9050612e44612e26610160850161014086016142a9565b60008381526008602052604090209063ffffffff908116906136bb16565b612e615760405163900bb2c960e01b815260040160405180910390fd5b50505050565b6000612e7960a08301608084016142a9565b600184015463ffffffff918216600160801b82048316019250600160601b900416811115612eba57604051637f70f90b60e01b815260040160405180910390fd5b60018301805463ffffffff60801b1916600160801b63ffffffff8416021790556000612eec6111a560208501856139d6565b905060001960ff861601612fe7576000600781612f0f60c0870160a088016139d6565b6001600160a01b0316815260208101919091526040016000209050612f3a60a08501608086016142a9565b63ffffffff16612f5383836133a390919063ffffffff16565b600187015463ffffffff918216929092019450612f9691600160401b9004168411612f8460e0870160c088016142a9565b63ffffffff1685119015159015151790565b15612fb457604051631b75136560e01b815260040160405180910390fd5b6020819052600382901c600090815260409020805460e0600585901b1681811c861863ffffffff16901b18905550611dc2565b6000600781612ffc60808701606088016139d6565b6001600160a01b031681526020810191909152604001600020905061302760a08501608086016142a9565b63ffffffff1661304083836133a390919063ffffffff16565b600187015463ffffffff918216929092019450600160401b9091041683111561307c57604051631b75136560e01b815260040160405180910390fd5b6020819052600382901c600090815260409020805460e0600585901b1681811c861863ffffffff16901b189055505050505050565b6130b96136fe565b83546000906130d1906001600160a01b0316876116af565b6001860154909150600090600119600160e81b90910460ff16016131355785546001600160601b03600160a01b909104811690851610156131255760405163dcdc2f1560e01b815260040160405180910390fd5b506001600160601b03831661317a565b60ff8716613166575084546001600160a01b03166000908152600360205260409020546001600160601b031661317a565b508454600160a01b90046001600160601b03165b604080840182905263ffffffff8616808302602080870182905285516001600160601b0390811660a08901819052918701511690920260c087018190529091016080860152908301516131d5919061ffff1661271091020490565b60e08401819052608084015101606084015260208301516001870154612710600160a01b90910461ffff1690910204610100840152505060808101516020820151018152949350505050565b6002840154600090806132415750506001600160a01b0383161515610e82565b611f8f6001600160a01b038616151561326c83613263896000526014600c2090565b88918891613597565b15159015151690565b600881901c6000908152602092909252604090912054600160ff9092161c1690565b6001600160a01b038116612b1e576040516362ccef3360e01b815260040160405180910390fd5b61331967016345785d8a00006001600160601b031682600001516001600160601b03161167016345785d8a00006001600160601b031683602001516001600160601b0316116103e861ffff16846040015161ffff16116136ea565b15612b1e5760405163b17424c360e01b815260040160405180910390fd5b80612b1e5760405163caa2867f60e01b815260040160405180910390fd5b8063ffffffff16600003612b1e5760405163a017714560e01b815260040160405180910390fd5b6103e861ffff82161115612b1e57604051631a52ce6f60e01b815260040160405180910390fd5b600381901c600090815260209290925260409091205460059190911b60e0161c90565b6335278d126000526004601cfd5b60006133ed8260010154600160f01b9004600416151590565b6134045760048201546001600160a01b0316610c60565b50546001600160a01b039081166000908152600460205260409020541690565b60007f7f88e5d4fe8478d2cbee68c8c08d5aeecbc339410172d285126b4c9b4a5e64947f0000000000000000000000000000000000cf4558c36229ac0026ee16d3ae35cd30147f00000000000000000000000000000000000000000000000000000000000000014614166135195750604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81527fa6cb2587267be99efde5eb570922efe1ef200501c220db4e8df4187255e6c05060208201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc69181019190915246606082015230608082015260a090205b67190100000000000060005280601a5282603a52604260182091506000603a5250919050565b804710156135555763b12d13eb6000526004601cfd5b60005a60005a8486620186a0f161294457816000526073600b5360ff6020536016600b82f0612944575a60141c3d5a3e5050565b6382b429006000526004601cfd5b600083156135c9578360051b8501855b803580851160051b948552602094851852604060002093018181106135a75750505b501492915050565b600060405163e839bd536000528360205282604052602060006064601c6c447e69651d841bd8d104bed4935afa600160005114169150806040525092915050565b6001600160a01b039093169260008415610e8257604051604183036136705784600052604084013560001a602052604084604037602060016080600060015afa805187183d151761366e57506000606052604052506001610e82565b505b600060605280604052631626ba7e60e01b80825285600483015260248201604081528460448401528486606485013760208160648701858b5afa905190911416915050949350505050565b600881901c600090815260209290925260409091208054600160ff9093169290921b9182189081905516151590565b600083151583151583151517151517610e82565b6040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040805161024081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101829052610200810182905261022081019190915290565b6000602082840312156137f057600080fd5b81356001600160e01b0319811681146117d057600080fd5b6000815180845260005b8181101561382e57602081850181015186830182015201613812565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006117d06020830184613808565b6001600160a01b0381168114612b1e57600080fd5b8035612af281613861565b803560ff81168114612af257600080fd5b600080600080608085870312156138a857600080fd5b84356138b381613861565b93506138c160208601613881565b92506138cf60408601613881565b915060608501356138df81613861565b939692955090935050565b6000806000806080858703121561390057600080fd5b843561390b81613861565b935061391960208601613881565b925061392760408601613881565b9396929550929360600135925050565b6000806040838503121561394a57600080fd5b823561395581613861565b915061396360208401613881565b90509250929050565b803563ffffffff81168114612af257600080fd5b6000806000806080858703121561399657600080fd5b84356139a181613861565b93506139af60208601613881565b92506139bd60408601613881565b91506139cb6060860161396c565b905092959194509250565b6000602082840312156139e857600080fd5b81356117d081613861565b600080600080600060a08688031215613a0b57600080fd5b8535613a1681613861565b9450613a2460208701613881565b9350613a3260408701613881565b9250613a406060870161396c565b9150613a4e6080870161396c565b90509295509295909350565b80356001600160601b0381168114612af257600080fd5b60008060008060808587031215613a8757600080fd5b8435613a9281613861565b9350613aa060208601613881565b9250613aae60408601613881565b91506139cb60608601613a5a565b600060208284031215613ace57600080fd5b813567ffffffffffffffff811115613ae557600080fd5b820161020081850312156117d057600080fd5b60808101610c6082846001600160601b038082511683528060208301511660208401525061ffff60408201511660408301526060810151151560608301525050565b600060208284031215613b4c57600080fd5b6117d082613a5a565b60008083601f840112613b6757600080fd5b50813567ffffffffffffffff811115613b7f57600080fd5b6020830191508360208260051b8501011115613b9a57600080fd5b9250929050565b60008060008060008060a08789031215613bba57600080fd5b8635613bc581613861565b9550613bd360208801613881565b9450613be160408801613881565b93506060870135613bf181613861565b9250608087013567ffffffffffffffff811115613c0d57600080fd5b613c1989828a01613b55565b979a9699509497509295939492505050565b600080600080600060808688031215613c4357600080fd5b8535613c4e81613861565b9450613c5c60208701613881565b9350613c6a60408701613881565b9250606086013567ffffffffffffffff811115613c8657600080fd5b613c9288828901613b55565b969995985093965092949392505050565b6020808252825182820181905260009190848201906040850190845b81811015613cdd578351151583529284019291840191600101613cbf565b50909695505050505050565b60ff60f81b881681526000602060e081840152613d0960e084018a613808565b8381036040850152613d1b818a613808565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b81811015613d6d57835183529284019291840191600101613d51565b50909c9b505050505050505050505050565b634e487b7160e01b600052604160045260246000fd5b6040516101a0810167ffffffffffffffff81118282101715613dc757634e487b7160e01b600052604160045260246000fd5b60405290565b803561ffff81168114612af257600080fd5b8015158114612b1e57600080fd5b600060808284031215613dff57600080fd5b6040516080810181811067ffffffffffffffff82111715613e3057634e487b7160e01b600052604160045260246000fd5b604052905080613e3f83613a5a565b8152613e4d60208401613a5a565b6020820152613e5e60408401613dcd565b60408201526060830135613e7181613ddf565b6060919091015292915050565b600060808284031215613e9057600080fd5b6117d08383613ded565b80516001600160a01b031682526020810151613ebb602084018260ff169052565b506040810151613ed0604084018260ff169052565b506060810151613eeb60608401826001600160a01b03169052565b506080810151613f0660808401826001600160601b03169052565b5060a0810151613f1e60a084018263ffffffff169052565b5060c0810151613f3660c084018263ffffffff169052565b5060e0810151613f4e60e084018263ffffffff169052565b506101008181015163ffffffff9081169184019190915261012080830151909116908301526101408082015161ffff16908301526101608082015160ff1690830152610180808201511515908301526101a0808201511515908301526101c080820151908301526101e08082015190830152610200808201516001600160a01b0316908301526102208082015180151582850152612e61565b6020808252825182820181905260009190848201906040850190845b81811015613cdd57614016838551613e9a565b928401926102409290920191600101614003565b60008060a0838503121561403d57600080fd5b61404683613881565b91506139638460208501613ded565b6000806000806080858703121561406b57600080fd5b843561407681613861565b935061408460208601613881565b925061409260408601613881565b91506139cb60608601613dcd565b60006101a082840312156140b357600080fd5b6140bb613d95565b6140c483613876565b81526140d260208401613a5a565b60208201526140e36040840161396c565b60408201526140f46060840161396c565b60608201526141056080840161396c565b608082015261411660a0840161396c565b60a082015261412760c08401613dcd565b60c082015260e083013560e0820152610100614144818501613881565b90820152610120614156848201613876565b90820152610140614168848201613881565b9082015261016061417a848201613876565b90820152610180928301359281019290925250919050565b6000806000606084860312156141a757600080fd5b83356141b281613861565b92506141c060208501613881565b91506141ce60408501613881565b90509250925092565b6102408101610c608284613e9a565b600080600080608085870312156141fc57600080fd5b843561420781613861565b935061421560208601613881565b925061422360408601613881565b915060608501356138df81613ddf565b600080600080600060a0868803121561424b57600080fd5b853561425681613861565b945061426460208701613881565b935061427260408701613881565b92506142806060870161396c565b9150613a4e60808701613a5a565b6000602082840312156142a057600080fd5b6117d082613881565b6000602082840312156142bb57600080fd5b6117d08261396c565b6000808335601e198436030181126142db57600080fd5b83018035915067ffffffffffffffff8211156142f657600080fd5b6020019150600581901b3603821315613b9a57600080fd5b60006020828403121561432057600080fd5b5051919050565b60ff848116825283166020820152815163ffffffff1660408201526101e081016020830151606083015260408301516001600160a01b038116608084015250606083015163ffffffff811660a084015250608083015163ffffffff811660c08401525060a083015163ffffffff811660e08401525060c08301516101006143b8818501836001600160a01b03169052565b60e085015191506101206143cf8186018415159052565b908501516101408581019190915290850151610160808601919091529085015161018080860191909152908501516101a0850152909301516101c0909201919091529392505050565b634e487b7160e01b600052603260045260246000fd5b60ff8316815260a081016117d060208301846001600160601b038082511683528060208301511660208401525061ffff60408201511660408301526060810151151560608301525050565b60ff84811682528316602082015281516001600160a01b031660408201526101e0810160208301516001600160601b038116606084015250604083015163ffffffff8116608084015250606083015163ffffffff811660a084015250608083015163ffffffff811660c08401525060a083015163ffffffff811660e08401525060c08301516101006145108185018361ffff169052565b60e085015161012085810191909152908501519150610140906145378286018460ff169052565b8501519150610160614553858201846001600160a01b03169052565b9085015191506101809061456b8583018460ff169052565b8501516001600160a01b03166101a0850152909301516101c0909201919091529392505050565b6000602082840312156145a457600080fd5b81516117d081613861565b6000602082840312156145c157600080fd5b81516117d081613ddf565b6000808335601e198436030181126145e357600080fd5b83018035915067ffffffffffffffff8211156145fe57600080fd5b602001915036819003821315613b9a57600080fdfea264697066735822122082a9fe6d3c01d9f8932f133836ed974fec48211730542b3dc9d954d491f4065164736f6c63430008130033
Deployed Bytecode Sourcemap
1029:41530:3:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21878:19;:17;:19::i;:::-;1029:41530;;21755:19;:17;:19::i;28514:210::-;;;;;;;;;;-1:-1:-1;28514:210:3;;;;;:::i;:::-;;:::i;:::-;;;566:14:21;;559:22;541:41;;529:2;514:18;28514:210:3;;;;;;;;28178:112;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;3899:33::-;;;;;;;;;;;;3931:1;3899:33;;;;;1498:4:21;1486:17;;;1468:36;;1456:2;1441:18;3899:33:3;1326:184:21;18345:643:3;;;;;;;;;;-1:-1:-1;18345:643:3;;;;;:::i;:::-;;:::i;15962:407::-;;;;;;;;;;-1:-1:-1;15962:407:3;;;;;:::i;:::-;;:::i;23464:164::-;;;;;;;;;;-1:-1:-1;23464:164:3;;;;;:::i;:::-;;:::i;22701:274::-;;;;;;;;;;-1:-1:-1;22701:274:3;;;;;:::i;:::-;;:::i;:::-;;;;;;4063:4:21;4105:3;4094:9;4090:19;4082:27;;4142:6;4136:13;4125:9;4118:32;4206:4;4198:6;4194:17;4188:24;4181:4;4170:9;4166:20;4159:54;4269:4;4261:6;4257:17;4251:24;4244:4;4233:9;4229:20;4222:54;4332:4;4324:6;4320:17;4314:24;4307:4;4296:9;4292:20;4285:54;4395:4;4387:6;4383:17;4377:24;4370:4;4359:9;4355:20;4348:54;4458:4;4450:6;4446:17;4440:24;4433:4;4422:9;4418:20;4411:54;4521:4;4513:6;4509:17;4503:24;4496:4;4485:9;4481:20;4474:54;4584:4;4576:6;4572:17;4566:24;4559:4;4548:9;4544:20;4537:54;4610:6;4670:2;4662:6;4658:15;4652:22;4647:2;4636:9;4632:18;4625:50;;3901:780;;;;;3775:58:3;;;;;;;;;;-1:-1:-1;3775:58:3;1250:66:13;3775:58:3;;;;;4832:25:21;;;4820:2;4805:18;3775:58:3;4686:177:21;21414:196:3;;;;;;;;;;-1:-1:-1;21414:196:3;;;;;:::i;:::-;;:::i;14424:656::-;;;;;;;;;;-1:-1:-1;14424:656:3;;;;;:::i;:::-;;:::i;17166:569::-;;;;;;;;;;-1:-1:-1;17166:569:3;;;;;:::i;:::-;;:::i;13350:550::-;;;;;;;;;;-1:-1:-1;13350:550:3;;;;;:::i;:::-;;:::i;10437:2692::-;;;;;;:::i;:::-;;:::i;25860:387::-;;;;;;;;;;-1:-1:-1;25860:387:3;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;28344:121::-;;;;;;;;;;;;;:::i;25612:194::-;;;;;;;;;;-1:-1:-1;25612:194:3;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4543:10:2;;;5459:3:3;4540:37:2;25728:71:3;;:19;:71;;;;;25721:78;;;;;;;;-1:-1:-1;;;;;25721:78:3;;;;;-1:-1:-1;;;25721:78:3;;;;;;;;;;-1:-1:-1;;;25721:78:3;;;;;;;;;;;-1:-1:-1;;;25721:78:3;;;;;;;;;;;;;;;25612:194;21189:171;;;;;;;;;;-1:-1:-1;21189:171:3;;;;;:::i;:::-;;:::i;24022:377::-;;;;;;;;;;-1:-1:-1;24022:377:3;;;;;:::i;:::-;;:::i;4345:51::-;;;;;;;;;;;;4392:4;4345:51;;;;;9152:6:21;9140:19;;;9122:38;;9110:2;9095:18;4345:51:3;8978:188:21;24782:544:3;;;;;;;;;;-1:-1:-1;24782:544:3;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;25380:178::-;;;;;;;;;;-1:-1:-1;25380:178:3;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4543:10:2;;;25521:29:3;;;;4540:37:2;25501:50:3;;:19;:50;;;;;25494:57;;;;;;;;-1:-1:-1;;;;;25494:57:3;;;;;-1:-1:-1;;;25494:57:3;;;;;;;;;;-1:-1:-1;;;25494:57:3;;;;;;;;;;;-1:-1:-1;;;25494:57:3;;;;;;;;;;;;;;;;25380:178;6926:596:13;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;5720:54:3:-;;;;;;;;;;-1:-1:-1;5720:54:3;;;;;:::i;:::-;;;;;;;;;;;;;;;20171:265;;;;;;;;;;-1:-1:-1;20171:265:3;;;;;:::i;:::-;;:::i;20831:304::-;;;;;;;;;;-1:-1:-1;20831:304:3;;;;;:::i;:::-;;:::i;17789:502::-;;;;;;;;;;-1:-1:-1;17789:502:3;;;;;:::i;:::-;;:::i;4098:42::-;;;;;;;;;;;;4139:1;4098:42;;26301:751;;;;;;;;;;-1:-1:-1;26301:751:3;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;5983:55::-;;;;;;;;;;-1:-1:-1;5983:55:3;;;;;:::i;:::-;;;;;;;;;;;;;;16423:689;;;;;;;;;;-1:-1:-1;16423:689:3;;;;;:::i;:::-;;:::i;15134:296::-;;;;;;;;;;-1:-1:-1;15134:296:3;;;;;:::i;:::-;;:::i;20490:287::-;;;;;;;;;;-1:-1:-1;20490:287:3;;;;;:::i;:::-;;:::i;3230:468::-;;;;;;;;;;;;3308:390;3230:468;;6230:49;;;;;;;;;;-1:-1:-1;6230:49:3;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;6230:49:3;;;;;;-1:-1:-1;;;;;17325:32:21;;;17307:51;;17295:2;17280:18;6230:49:3;17161:203:21;6109:41:3;;;;;;;;;;-1:-1:-1;6109:41:3;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;6109:41:3;;;;;;-1:-1:-1;;;;;17531:39:21;;;17513:58;;17501:2;17486:18;6109:41:3;17369:208:21;15484:424:3;;;;;;;;;;-1:-1:-1;15484:424:3;;;;;:::i;:::-;;:::i;23682:286::-;;;;;;;;;;-1:-1:-1;23682:286:3;;;;;:::i;:::-;;:::i;:::-;;;18221:10:21;18209:23;;;18191:42;;18179:2;18164:18;23682:286:3;18047:192:21;7101:3282:3;;;;;;;;;;-1:-1:-1;7101:3282:3;;;;;:::i;:::-;;:::i;4216:63::-;;;;;;;;;;;;1495:5:2;4216:63:3;;5852:53;;;;;;;;;;-1:-1:-1;5852:53:3;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;5852:53:3;;;27106:1018;;;;;;;;;;-1:-1:-1;27106:1018:3;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;4604:65::-;;;;;;;;;;;;4660:9;4604:65;;13954:416;;;;;;;;;;-1:-1:-1;13954:416:3;;;;;:::i;:::-;;:::i;22151:496::-;;;;;;;;;;-1:-1:-1;22151:496:3;;;;;:::i;:::-;;:::i;19543:438::-;;;;;;;;;;-1:-1:-1;19543:438:3;;;;;:::i;:::-;;:::i;23029:381::-;;;;;;;;;;-1:-1:-1;23029:381:3;;;;;:::i;:::-;;:::i;19149:340::-;;;;;;;;;;-1:-1:-1;19149:340:3;;;;;:::i;:::-;;:::i;3994:39::-;;;;;;;;;;;;4032:1;3994:39;;24453:275;;;;;;;;;;-1:-1:-1;24453:275:3;;;;;:::i;:::-;;:::i;11272:1120:17:-;11346:14;11336:68;;11346:14;;11364:38;11336:68;11426:1;;11503:628;11522:21;11346:14;11525:1;11522:21;;;-1:-1:-1;;;11522:21:17;11643:1;11636:9;;;;-1:-1:-1;;11586:9:17;;11597:15;;11582:31;11426:1;11574:40;;;11662:394;;-1:-1:-1;;11856:17:17;;11718:9;11772;;;11729:15;-1:-1:-1;;11718:9:17;;11714:31;11426:1;11706:40;11910:4;11904:11;;;11894:61;;11643:1;11947;11943:9;11931:10;11928:1;11919:34;11894:61;11992:12;11981:28;;;;;;;;-1:-1:-1;11503:628:17;;-1:-1:-1;11503:628:17;11662:394;12084:1;12081;12073:13;11643:1;12112;12108:9;12103:14;;;;;11503:628;;;11507:14;11426:1;;12196;11426;12179:9;12172:5;12159:51;12144:66;;12250:16;11426:1;;12223:44;12290:7;12280:53;;12314:16;11426:1;12301:30;12280:53;;12359:16;11426:1;12346:30;28514:210:3;28590:4;-1:-1:-1;;;;;;;;;28623:45:3;;28670:46;;;-1:-1:-1;;;28623:45:3;;;3385:40:2;28613:104:3;28606:111;28514:210;-1:-1:-1;;28514:210:3:o;28178:112::-;28217:19;28260:23;:21;:23::i;:::-;-1:-1:-1;28248:35:3;28178:112;-1:-1:-1;28178:112:3:o;18345:643::-;18497:7;29168:40;29200:7;29168:31;:40::i;:::-;18516:14:::1;18533:41;18547:7;18556:4;18562:11;18533:13;:41::i;:::-;18516:58;;18584:18;18605:20;18618:6;18605:12;:20::i;:::-;18639:6;::::0;::::1;::::0;18584:41;;-1:-1:-1;;;;18639:6:3;::::1;:26;:6;4139:1;18639:26;18635:56;;18674:17;;-1:-1:-1::0;;;18674:17:3::1;;;;;;;;;;;18635:56;18701:23;18717:6;18701:15;:23::i;:::-;18777:1;18816:7:::0;;::::1;::::0;-1:-1:-1;;;;;18759:20:3;::::1;::::0;;::::1;::::0;18799:71:::1;::::0;18816:7:::1;-1:-1:-1::0;;;18816:7:3;;::::1;;5240:6;18759:20:::0;2304:4:2;2310:16;;;2300:27;2293:35;2330:12;;2289:54;2285:65;2274:77;;2109:258;18799:71:3::1;18789:1;:7;;;:81;;;;;;;;;;;;;;;;;;18885:17;18880:41;;18904:8;::::0;::::1;:17:::0;;-1:-1:-1;;;;;;18904:17:3::1;-1:-1:-1::0;;;;;18904:17:3;::::1;;::::0;;18880:41:::1;18936:45;::::0;;21419:4:21;21407:17;;;21389:36;;21461:17;;21456:2;21441:18;;21434:45;-1:-1:-1;;;;;21515:32:21;;;21495:18;;;21488:60;;;;18936:45:3;;::::1;::::0;::::1;::::0;21377:2:21;21362:18;18936:45:3::1;;;;;;;;18506:482;;;18345:643:::0;;;;;:::o;15962:407::-;16125:7;29168:40;29200:7;29168:31;:40::i;:::-;16144:14:::1;16161:41;16175:7;16184:4;16190:11;16161:13;:41::i;:::-;16144:58;;16212:18;16233:20;16246:6;16233:12;:20::i;:::-;16263:21;::::0;::::1;:28:::0;;;16306:56:::1;::::0;;21783:4:21;21771:17;;;21753:36;;21825:17;;21820:2;21805:18;;21798:45;21859:18;;;21852:34;;;16212:41:3;;-1:-1:-1;;;;;;16306:56:3;::::1;::::0;::::1;::::0;21741:2:21;21726:18;16306:56:3::1;;;;;;;;16134:235;;15962:407:::0;;;;;:::o;23464:164::-;23539:5;23563:9;:42;23573:31;23587:7;23596:4;23602:1;23573:13;:31::i;:::-;23563:42;;;;;;;;;;;-1:-1:-1;23563:42:3;:58;;;-1:-1:-1;;;23563:58:3;;;;;-1:-1:-1;23464:164:3;;;;:::o;22701:274::-;22852:24;;:::i;:::-;22895:73;22928:7;22937:4;22943:11;22956:8;22966:1;22895:32;:73::i;:::-;22888:80;;22701:274;;;;;;;:::o;21414:196::-;21474:14;21491:23;:21;:23::i;:::-;-1:-1:-1;;;;;21524:22:3;;;;;;;:14;:22;;;;;;;;;:31;;-1:-1:-1;;;;;;21524:31:3;;;;;;;;;21570:33;;17307:51:21;;;21524:22:3;;-1:-1:-1;21524:22:3;21570:33;;17280:18:21;21570:33:3;;;;;;;;21464:146;21414:196;:::o;14424:656::-;14605:7;29168:40;29200:7;29168:31;:40::i;:::-;14624:14:::1;14641:41;14655:7;14664:4;14670:11;14641:13;:41::i;:::-;14624:58;;14692:18;14713:20;14726:6;14713:12;:20::i;:::-;14692:41:::0;-1:-1:-1;14816:15:3::1;::::0;::::1;::::0;:46;::::1;;;-1:-1:-1::0;14846:16:3::1;14835:27:::0;;::::1;;;14816:46;14812:76;;;14871:17;;-1:-1:-1::0;;;14871:17:3::1;;;;;;;;;;;14812:76;14898:38;14917:9;14928:7;14898:18;:38::i;:::-;14946:11;::::0;::::1;:23:::0;;::::1;::::0;;::::1;-1:-1:-1::0;;14979:19:3;;;;;;;;::::1;::::0;;::::1;;::::0;;;15013:60:::1;::::0;;22146:4:21;22134:17;;;22116:36;;22188:17;;22183:2;22168:18;;22161:45;22251:18;;;22244:43;;;;22318:2;22303:18;;22296:43;;;;-1:-1:-1;;;;;15013:60:3;::::1;::::0;::::1;::::0;22103:3:21;22088:19;15013:60:3::1;21897:448:21::0;17166:569:3;17321:7;29168:40;29200:7;29168:31;:40::i;:::-;17340:14:::1;17357:41;17371:7;17380:4;17386:11;17357:13;:41::i;:::-;17340:58;;17408:18;17429:20;17442:6;17429:12;:20::i;:::-;17408:41:::0;-1:-1:-1;17534:15:3::1;::::0;::::1;::::0;:36;::::1;;;-1:-1:-1::0;17553:6:3::1;::::0;::::1;::::0;-1:-1:-1;;;17553:6:3;::::1;:17;:6;:17:::0;17534:36:::1;17530:66;;;17579:17;;-1:-1:-1::0;;;17579:17:3::1;;;;;;;;;;;17530:66;17606:27;17627:5;17606:20;:27::i;:::-;17643:13;::::0;::::1;:21:::0;;-1:-1:-1;;;;17643:21:3::1;-1:-1:-1::0;;;17643:21:3::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;17679:49:::1;::::0;;22572:4:21;22560:17;;;22542:36;;22614:17;;22609:2;22594:18;;22587:45;22648:18;;;22641:51;;;;-1:-1:-1;;;;;17679:49:3;::::1;::::0;::::1;::::0;22530:2:21;22515:18;17679:49:3::1;22350:348:21::0;13350:550:3;13499:7;29168:40;29200:7;29168:31;:40::i;:::-;13518:14:::1;13535:41;13549:7;13558:4;13564:11;13535:13;:41::i;:::-;13518:58;;13586:18;13607:20;13620:6;13607:12;:20::i;:::-;13586:41:::0;-1:-1:-1;13739:15:3::1;::::0;::::1;::::0;:45;::::1;;;-1:-1:-1::0;13758:6:3::1;::::0;::::1;::::0;-1:-1:-1;;;13758:6:3;::::1;:26;:6;4139:1;13758:26;;13739:45;13735:75;;;13793:17;;-1:-1:-1::0;;;13793:17:3::1;;;;;;;;;;;13735:75;13820:15:::0;;-1:-1:-1;;;;;13820:15:3;::::1;-1:-1:-1::0;;;13820:15:3;::::1;-1:-1:-1::0;;;;;13820:15:3;;::::1;;::::0;;13850:43:::1;::::0;;22925:4:21;22913:17;;;22895:36;;22967:17;;22962:2;22947:18;;22940:45;23001:18;;;22994:67;;;;13850:43:3;;::::1;::::0;::::1;::::0;22883:2:21;22868:18;13850:43:3::1;22703:364:21::0;10437:2692:3;10497:18;10518:61;10531:47;10545:9;;;;:1;:9;:::i;:::-;10556:6;;;;;;;;:::i;:::-;10564:13;;;;;;;;:::i;:::-;10531;:47::i;:::-;10518:12;:61::i;:::-;10734:11;;;;;;-1:-1:-1;10716:15:3;10765:9;;;10734:11;10765:9;;;-1:-1:-1;;10734:11:3;;-1:-1:-1;3385:40:2;10702:146:3;;;10825:11;;;;10796:52;;-1:-1:-1;;;10796:52:3;;10808:15;10838:9;10796:52;;23457:25:21;10825:11:3;;;;23527:18:21;;;23520:43;10838:9:3;;;;;;;23579:18:21;;;23572:43;23430:18;;10796:52:3;;;;;;;;10702:146;10862:12;10872:1;41846:7;;;-1:-1:-1;;;41846:7:3;;5082:6;41846:27;:32;;;41761:124;10862:12;10858:37;;;10883:12;;-1:-1:-1;;;10883:12:3;;;;;;;;;;;10858:37;11020:6;;;;-1:-1:-1;;;11020:6:3;;;;-1:-1:-1;;11040:21:3;;11036:121;;11063:19;11077:1;11080;11063:13;:19::i;:::-;11036:121;;;-1:-1:-1;;11101:24:3;;;;11097:60;;11127:30;11152:1;11155;11127:24;:30::i;:::-;11168:28;11185:4;11191:1;11194;11168:16;:28::i;:::-;11281:26;11310:56;11329:6;;;;;;;;:::i;:::-;11337:1;11340:10;;;;;;;;:::i;:::-;11352:13;;;;;;;;:::i;:::-;11310:18;:56::i;:::-;11281:85;;11377:17;11460:15;11527:1;:7;;;11514:9;:20;11510:65;;11567:7;;11543:32;;-1:-1:-1;;;11543:32:3;;11556:9;11543:32;;;23989:25:21;24030:18;;;24023:34;;;;23962:18;;11543:32:3;23815:248:21;11510:65:3;11638:13;;;;11628:7;;11712:10;;-1:-1:-1;;;;;11712:10:3;11628:7;11692:31;;;;;;;;;;:48;;;;;;11628:23;;-1:-1:-1;11800:56:3;11712:1;11826:11;;;;;;;;:::i;:::-;11839:16;;;;:1;:16;:::i;:::-;11800:22;:56::i;:::-;11787:69;;;11783:545;;;11889:14;;;;11876:27;;;;;11953:20;:33;11974:11;;;;;;;;:::i;:::-;-1:-1:-1;;;;;11953:33:3;;;;;;;;;;;;-1:-1:-1;11953:33:3;:51;;;;;;;11783:545;;;12196:1;12173:11;;;;;;;;:::i;:::-;-1:-1:-1;;;;;12173:25:3;;12169:56;;12207:18;;-1:-1:-1;;;12207:18:3;;;;;;;;;;;12169:56;12260:1;12243:14;;;:18;11783:545;12422:23;12464:9;;;;:1;:9;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12422:52:3;;-1:-1:-1;12529:10:3;;;;;;;;:::i;:::-;12516:23;;;;-1:-1:-1;;;;;12565:12:3;;;12586:9;12598:6;;;;;;;;:::i;:::-;12606:4;;;;;;;;:::i;:::-;12612:10;;;;;;;;:::i;:::-;12565:58;;-1:-1:-1;;;;;;12565:58:3;;;;;;;24845:4:21;24833:17;;;12565:58:3;;;24815:36:21;-1:-1:-1;;;;;24887:32:21;;;24867:18;;;24860:60;12565:58:3;24956:23:21;24936:18;;;24929:51;24788:18;;12565:58:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12549:13;;;:74;12649:13;;;;;;;;:::i;:::-;-1:-1:-1;;;;;12633:29:3;:13;;;:29;12696:21;;;;;;;;:::i;:::-;12672:45;;:21;;;:45;12749:19;;;;;;;;:::i;:::-;12727:41;;:19;;;:41;12792:11;;;;;;;;:::i;:::-;-1:-1:-1;;;;;12778:25:3;:11;;;:25;12813;;;:12;;;:25;12871:7;;12848:20;;;;:30;;;;12902:11;;;;12888;;;:25;12939:13;;;;;12923;;;:29;12982:17;;;;;12962;;;:37;13026:14;;;;13009;;;:31;13106:15;;;;;13097:4;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;13056:66:3;13063:9;;;;:1;:9;:::i;:::-;-1:-1:-1;;;;;13056:66:3;;13074:6;;;;;;;;:::i;:::-;13082:13;;;;;;;;:::i;:::-;13103:1;13056:66;;;;;;;;:::i;:::-;;;;;;;;10487:2642;;;;;;;10437:2692;:::o;25860:387::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26032:29:3;;;;4543:10:2;;;4540:37;26012:50:3;;:19;:50;;;;;;25983:79;;;;;;;;-1:-1:-1;;;;;25983:79:3;;;;;-1:-1:-1;;;25983:79:3;;;;;;;;;;;-1:-1:-1;;;25983:79:3;;;;;;;;;;-1:-1:-1;;;25983:79:3;;;;;;;;;;;-1:-1:-1;;26072:90:3;;26091:19;:71;4547:2:2;4543:10;;;5459:3:3;4540:37:2;26091:71:3;;;;;;;;;;;;;;-1:-1:-1;26091:71:3;26087:75;;;;;;;;;-1:-1:-1;;;;;26087:75:3;;;;;-1:-1:-1;;;26087:75:3;;;;;;;;;;-1:-1:-1;;;26087:75:3;;;;;;;;;;;-1:-1:-1;;;26087:75:3;;;;;;;;;;;;-1:-1:-1;26072:90:3;26177:1;:8;;;26172:23;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26172:23:3;26239:1;25860:387;-1:-1:-1;;;25860:387:3:o;28344:121::-;28386:22;28435:23;:21;:23::i;21189:171::-;21240:14;21257:23;:21;:23::i;:::-;-1:-1:-1;;;;;21290:15:3;;;;;;:7;:15;;;;;;;;;:23;;-1:-1:-1;;21290:23:3;-1:-1:-1;;;;;21290:23:3;;;;;;;;21328:25;;17513:58:21;;;21290:15:3;;-1:-1:-1;21290:15:3;;21328:25;;17486:18:21;21328:25:3;17369:208:21;24022:377:3;24230:4;24246:14;24263:41;24277:7;24286:4;24292:11;24263:13;:41::i;:::-;24246:58;;24321:71;24344:20;24357:6;24344:12;:20::i;:::-;24366:9;24377:14;;24321:22;:71::i;:::-;24314:78;24022:377;-1:-1:-1;;;;;;;;24022:377:3:o;24782:544::-;24948:21;24981:14;24998:41;25012:7;25021:4;25027:11;24998:13;:41::i;:::-;25049:31;25083:22;;;:14;:22;;;;;24981:58;;-1:-1:-1;25136:12:3;25125:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;25125:31:3;;25115:41;;25195:9;25190:120;25206:24;;;25190:120;;25268:27;25279:12;;25292:1;25279:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;25268:27;;:6;:10;;:27;;;;:::i;:::-;25255:7;25263:1;25255:10;;;;;;;;:::i;:::-;:40;;;:10;;;;;;;;;;;:40;25232:3;;25190:120;;;;24971:355;;24782:544;;;;;;;:::o;6926:596:13:-;-1:-1:-1;;;7051:18:13;;7024:13;;;7051:18;7322:23;:21;:23::i;:::-;6926:596;;7304:41;;;-1:-1:-1;7365:13:13;;-1:-1:-1;7416:4:13;;-1:-1:-1;6926:596:13;;-1:-1:-1;6926:596:13;:::o;20171:265:3:-;20238:14;20255:23;:21;:23::i;:::-;20238:40;;20288:38;20316:9;20288:27;:38::i;:::-;-1:-1:-1;;;;;20336:26:3;;;;;;;:18;:26;;;;;;;;;:38;;-1:-1:-1;;;;;;20336:38:3;;;;;;;;;20389:40;;17307:51:21;;;20336:26:3;;20389:40;;17280:18:21;20389:40:3;17161:203:21;20831:304:3;20913:14;20930:23;:21;:23::i;:::-;20913:40;;20963:29;20990:1;20963:26;:29::i;:::-;4547:2:2;4543:10;;;5459:3:3;4540:37:2;21002:69:3;;;;:19;:69;;;;;;;;;:73;;;;;;;;;;;;;;;;;;-1:-1:-1;;;21002:73:3;-1:-1:-1;;;;21002:73:3;;;;-1:-1:-1;;;21002:73:3;;;;;-1:-1:-1;;;;;;;;;21002:73:3;;;-1:-1:-1;;;21002:73:3;-1:-1:-1;;;;;;21002:73:3;;;;;;;;;;;;;;;;;;;;;;;;;;;21090:38;-1:-1:-1;;;;;21090:38:3;;;;;;;21002:73;;21090:38;:::i;17789:502::-;17949:7;29168:40;29200:7;29168:31;:40::i;:::-;17968:14:::1;17985:41;17999:7;18008:4;18014:11;17985:13;:41::i;:::-;17968:58;;18036:18;18057:20;18070:6;18057:12;:20::i;:::-;4032:1;18091:6:::0;;::::1;::::0;18036:41;;-1:-1:-1;;;;18091:6:3;;::::1;:23;:6;:23;18087:53;;18123:17;;-1:-1:-1::0;;;18123:17:3::1;;;;;;;;;;;18087:53;18150:31;18170:10;18150:19;:31::i;:::-;18191:12;::::0;::::1;:25:::0;;;18231:53:::1;::::0;;21783:4:21;21771:17;;;21753:36;;21825:17;;21820:2;21805:18;;21798:45;21859:18;;;21852:34;;;-1:-1:-1;;;;;18231:53:3;::::1;::::0;::::1;::::0;21741:2:21;21726:18;18231:53:3::1;21559:333:21::0;26301:751:3;26361:19;4543:10:2;;;26416:28:3;26447:36;;;:9;:36;;;;;26509:23;;;;;-1:-1:-1;;;26509:23:3;;;;;-1:-1:-1;;;26580:16:3;;;26509:23;26646:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;26642:21;;26834:202;26841:6;;26834:202;;26898:25;;;4547:2:2;4543:10;;;4540:37;26867:18:3;26888:36;;;:9;:36;;;;;26951:42;4543:10:2;26975:6:3;26980:1;26975:6;;;;26898:25;26951:8;:42::i;:::-;26942:1;26944:3;;;;;;;26942:6;;;;;;;;:::i;:::-;;;;;;;;;;:51;27015:6;;;-1:-1:-1;;;27015:6:3;;;;;-1:-1:-1;26834:202:3;;;26392:654;;;26301:751;;;:::o;16423:689::-;16588:7;29168:40;29200:7;29168:31;:40::i;:::-;16607:14:::1;16624:41;16638:7;16647:4;16653:11;16624:13;:41::i;:::-;16607:58;;16675:18;16696:20;16709:6;16696:12;:20::i;:::-;16675:41:::0;-1:-1:-1;16779:15:3::1;::::0;::::1;16775:45;;16803:17;;-1:-1:-1::0;;;16803:17:3::1;;;;;;;;;;;16775:45;16891:6;::::0;::::1;::::0;-1:-1:-1;;;;;16891:6:3;;::::1;:26;:6;:26:::0;16887:56:::1;;16926:17;;-1:-1:-1::0;;;16926:17:3::1;;;;;;;;;;;16887:56;16953:37;16984:5;16953:30;:37::i;:::-;17000:23;::::0;::::1;:31:::0;;-1:-1:-1;;17000:31:3::1;-1:-1:-1::0;;;17000:31:3::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;17046:59:::1;::::0;;22572:4:21;22560:17;;;22542:36;;22614:17;;22609:2;22594:18;;22587:45;22648:18;;;22641:51;;;;-1:-1:-1;;;;;17046:59:3;::::1;::::0;::::1;::::0;22530:2:21;22515:18;17046:59:3::1;22350:348:21::0;15134:296:3;15277:14;15294:41;15308:7;15317:4;15323:11;15294:13;:41::i;:::-;15397:17;;;;:9;:17;;;;;:25;;;:17;;-1:-1:-1;15345:78:3;;15358:7;;15367:4;;15373:11;;15386:9;;15397:25;;;;;15345:12;:78::i;:::-;15267:163;15134:296;;;;:::o;20490:287::-;20577:14;20594:23;:21;:23::i;:::-;20577:40;;20627:29;20654:1;20627:26;:29::i;:::-;4547:2:2;4543:10;;;20686:27:3;;;4540:37:2;20666:48:3;;;;:19;:48;;;;;;;;;:52;;;;;;;;;;;;;;;;;;-1:-1:-1;;;20666:52:3;-1:-1:-1;;;;20666:52:3;;;;-1:-1:-1;;;20666:52:3;;;;;-1:-1:-1;;;;;;;;;20666:52:3;;;-1:-1:-1;;;20666:52:3;-1:-1:-1;;;;;;20666:52:3;;;;;;;;;;;;;;;;;;;;;;;;;;;20733:37;-1:-1:-1;;;;;20733:37:3;;;;;;;20686:27;;20666:52;;20733:37;:::i;:::-;;;;;;;;20567:210;20490:287;;:::o;15484:424::-;15638:7;29168:40;29200:7;29168:31;:40::i;:::-;15657:14:::1;15674:41;15688:7;15697:4;15703:11;15674:13;:41::i;:::-;15657:58;;15725:18;15746:20;15759:6;15746:12;:20::i;:::-;15725:41;;15776:29;15801:3;15776:24;:29::i;:::-;15815:17;::::0;::::1;:23:::0;;-1:-1:-1;;;;15815:23:3::1;-1:-1:-1::0;;;15815:23:3::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;15853:48:::1;::::0;;27536:4:21;27524:17;;;27506:36;;27578:17;;27573:2;27558:18;;27551:45;27612:18;;;27605:47;;;;-1:-1:-1;;;;;15853:48:3;::::1;::::0;::::1;::::0;27494:2:21;27479:18;15853:48:3::1;27314:344:21::0;23682:286:3;23832:6;23850:14;23867:41;23881:7;23890:4;23896:11;23867:13;:41::i;:::-;-1:-1:-1;;;;;23925:24:3;;;;;;:13;:24;;;;;;;;3360:1:16;3351:10;;;3343:19;;;;;;;;23850:58:3;;-1:-1:-1;3367:16:16;3382:1;3367:16;;;;3343:41;23925:36:3;23918:43;23682:286;-1:-1:-1;;;;;;23682:286:3:o;7101:3282::-;7167:17;7196:42;7228:1;:9;;;7196:31;:42::i;:::-;7249:43;7274:1;:17;;;7249:24;:43::i;:::-;7316:6;;;;7337:15;;;7333:464;;7387:1;7368:8;;;:21;;;7403:12;;;:25;7333:464;;;-1:-1:-1;;7449:21:3;;;;7445:352;;7486:33;7506:1;:12;;;7486:19;:33::i;:::-;7552:1;7533:8;;;:21;7445:352;;;-1:-1:-1;;7575:24:3;;;;7571:226;;7615:25;7631:1;:8;;;7615:15;:25::i;:::-;7677:1;7654:12;;;:25;7719:16;7693:23;;;:42;7571:226;;;7773:13;;-1:-1:-1;;;7773:13:3;;;;;;;;;;;7571:226;7876:6;;;;:17;;7872:586;;7921:16;7909:9;;;:28;;;7951:23;;;:42;8266:24;;;4139:1;8266:24;8262:41;;8302:1;8292:7;;;:11;8262:41;8398:15;;;8394:53;;8431:16;8415:13;;;:32;8394:53;8468:42;8487:1;:11;;;8500:1;:9;;;8468:18;:42::i;:::-;8520:55;8551:1;:23;;;8520:30;:55::i;:::-;8585:35;8606:1;:13;;;8585:20;:35::i;:::-;8655:25;8683:9;:46;8693:35;8707:1;:9;;;8718:1;:6;;;8726:1;8693:13;:35::i;:::-;8683:46;;;;;;;;;;;;;;-1:-1:-1;8683:46:3;;;8798:9;;4547:2:2;4543:10;8774:38:3;;:9;:38;;;;8841:24;;;;;-1:-1:-1;;;8841:24:3;;;;;-1:-1:-1;8683:46:3;;-1:-1:-1;8774:38:3;8920:3;;8841:24;8920:13;;8916:42;;8935:23;:21;:23::i;:::-;8972:24;;;;:35;;;;;;-1:-1:-1;;;8972:35:3;-1:-1:-1;;;;8972:35:3;;;;;;;;;;9026:23;;;;;-1:-1:-1;;;9026:23:3;;;;9067:3;9074:7;9067:14;;9063:43;;9083:23;:21;:23::i;:::-;9120;;;:35;;-1:-1:-1;;;;9120:35:3;-1:-1:-1;;;9120:35:3;;;;;;;9201:9;;9120:35;9212:6;;;-1:-1:-1;;9187:45:3;;9220:11;9187:13;:45::i;:::-;9170:62;;9246:22;9291:1;-1:-1:-1;;;;;9271:22:3;:1;:8;;;-1:-1:-1;;;;;9271:22:3;;9246:47;;9308:18;9329:9;:17;9339:6;9329:17;;;;;;;;;;;9308:38;;9373:1;:10;;;9360:1;:10;;;:23;;;;;-1:-1:-1;;;;;9360:23:3;;;;;-1:-1:-1;;;;;9360:23:3;;;;;;9407:1;:7;;;9397:1;:7;;;:17;;;;;-1:-1:-1;;;;;9397:17:3;;;;;-1:-1:-1;;;;;9397:17:3;;;;;;9442:1;:11;;;9428:1;:11;;;:25;;;;;;;;;;;;;;;;;;9479:1;:9;;;9467:1;:9;;;:21;;;;;;;;;;;;;;;;;;9528:1;:23;;;9502:1;:23;;;:49;;;;;;;;;;;;;;;;;;9581:1;:13;;;9565:1;:13;;;:29;;;;;;;;;;;;;;;;;;9628:1;:17;;;9608:1;:17;;;:37;;;;;;;;;;;;;;;;;;9668:1;:6;;;9659:1;:6;;;:15;;;;;;;;;;;;;;;;;;9719:59;9733:17;5240:6;1866:12:2;;1859:20;1855:31;;1736:166;9719:59:3;4949:6;9688:7;;;:90;;-1:-1:-1;;;;9688:90:3;;-1:-1:-1;;;9698:80:3;;;9688:90;;;;;;;;;;;;;9801:16;;;;;-1:-1:-1;;;;9792:25:3;;;-1:-1:-1;;;;9792:25:3;;;;;;;-1:-1:-1;;;9801:16:3;;;;;;-1:-1:-1;;;9792:25:3;;;;;9688:90;9866:6;;;9831:72;;-1:-1:-1;;;;9831:72:3;9882:20;;;9877:1;9858:20;;;;;;9857:45;9831:72;;;;;;;9980:21;;;;:35;9976:86;;10041:21;;;;10017;;;:45;9976:86;10080:12;;;;:26;10076:59;;10123:12;;;;10108;;;:27;10076:59;10153:8;;;;-1:-1:-1;;;;;10153:22:3;;10149:152;;10200:17;10195:43;;10230:8;;;;10219;;;:19;;-1:-1:-1;;;;;;10219:19:3;-1:-1:-1;;;;;10219:19:3;;;;;;;;;10195:43;10332:1;:9;;;-1:-1:-1;;;;;10320:46:3;;10343:1;:6;;;10351:11;10364:1;10320:46;;;;;;;;:::i;:::-;;;;;;;;8631:1746;;;;;;7186:3197;7101:3282;;;:::o;27106:1018::-;27223:20;;:::i;:::-;27255:14;27272:41;27286:7;27295:4;27301:11;27272:13;:41::i;:::-;27255:58;;27323:18;27344:20;27357:6;27344:12;:20::i;:::-;-1:-1:-1;;;;;27374:22:3;;;;;27406:16;;;;:9;;;:16;;;27432:30;;;:16;;;:30;27488:10;;;;;27472:13;;;:26;27323:41;;-1:-1:-1;27521:15:3;:45;;;;-1:-1:-1;27540:6:3;;;;-1:-1:-1;;;27540:6:3;;:26;:6;4139:1;27540:26;;27521:45;:77;;27591:7;;-1:-1:-1;;;27591:7:3;;-1:-1:-1;;;;;27591:7:3;27521:77;;;27577:10;;-1:-1:-1;;;;;27577:10:3;27569:19;;;;:7;:19;;;;;;-1:-1:-1;;;;;27569:19:3;27521:77;-1:-1:-1;;;;;27508:90:3;:10;;;:90;27625:11;;;;;;;;27608:14;;;:28;27661:9;;;;;27646:12;;;:24;-1:-1:-1;;;27709:23:3;;;;27680:26;;;:52;-1:-1:-1;;;27761:13:3;;;;27625:11;27742:16;;:32;-1:-1:-1;;;27798:8:3;;;27784:11;;;:22;-1:-1:-1;;;27839:17:3;;;;27816:20;;;:40;-1:-1:-1;;;27878:6:3;;;;27866:9;;;:18;5082:6;-1:-1:-1;;;41846:7:3;;;:27;;:32;;27894:11;;;:26;27957:21;;;27930:24;;;:48;28006:12;;;;27988:15;;;:30;28042:19;27625:11;28042:16;:19::i;:::-;-1:-1:-1;;;;;28028:33:3;:11;;;:33;28096:21;28115:1;42510:7;;;-1:-1:-1;;;42510:7:3;;5240:6;42510:35;:40;;;42416:141;28096:21;28071:46;;:22;;;:46;-1:-1:-1;28071:4:3;;27106:1018;-1:-1:-1;;;;27106:1018:3:o;13954:416::-;14103:7;29168:40;29200:7;29168:31;:40::i;:::-;14122:14:::1;14139:41;14153:7;14162:4;14168:11;14139:13;:41::i;:::-;14122:58;;14190:18;14211:20;14224:6;14211:12;:20::i;:::-;14268:7;::::0;::::1;::::0;14190:41;;-1:-1:-1;14251:52:3::1;::::0;14268:7:::1;-1:-1:-1::0;;;14268:7:3;;::::1;;5082:6;14296::::0;2304:4:2;2310:16;;;2300:27;2293:35;2330:12;;2289:54;2285:65;2274:77;;2109:258;14251:52:3::1;14241:7;::::0;::::1;:62:::0;;-1:-1:-1;;;;14241:62:3::1;-1:-1:-1::0;;;14241:62:3::1;::::0;;::::1;;;::::0;;14318:45:::1;::::0;;29692:17:21;;;29674:36;;29746:17;;;29741:2;29726:18;;29719:45;29807:14;;29800:22;29780:18;;;29773:50;-1:-1:-1;;;;;14318:45:3;::::1;::::0;::::1;::::0;29662:2:21;29647:18;14318:45:3::1;29486:343:21::0;22151:496:3;22220:7;22285:355;3308:390;22372:9;;;;:1;:9;:::i;:::-;22399:6;;;;;;;;:::i;:::-;22424:13;;;;;;;;:::i;:::-;22455:4;;;;;;;;:::i;:::-;22477:16;;;;;;;;:::i;:::-;22511:19;;;;;;;;:::i;:::-;22548:13;;;;;;;;:::i;:::-;22579:16;;;;;;;;:::i;:::-;22613:11;;;;;;;;:::i;:::-;22310:328;;;;;;30217:25:21;;;;-1:-1:-1;;;;;30316:15:21;;;30296:18;;;30289:43;30380:4;30368:17;;;30348:18;;;30341:45;30422:17;;;;30402:18;;;30395:45;30477:15;;;30456:19;;;30449:44;30512:10;30559:15;;;30538:19;;;30531:44;30612:15;;30591:19;;;30584:44;-1:-1:-1;;;;;30665:39:21;;;30644:19;;;30637:68;30742:15;30721:19;;;30714:44;30795:15;30774:19;;;30767:44;30189:19;;22310:328:3;;;;;;;;;;;;22300:339;;;;;;22285:14;:355::i;19543:438::-;-1:-1:-1;;;;;19627:28:3;;;19607:17;19627:28;;;:18;:28;;;;;;;19665:38;19627:28;19665:27;:38::i;:::-;-1:-1:-1;;;;;19731:29:3;;19713:15;19731:29;;;;;;;;;;;19774:12;;19770:205;;-1:-1:-1;;;;;19802:29:3;;19834:1;19802:29;;;;;;;;;;:33;19849:56;19886:9;19897:7;19849:36;:56::i;:::-;19946:8;-1:-1:-1;;;;;19924:40:3;;19956:7;19924:40;;;;4832:25:21;;4820:2;4805:18;;4686:177;19770:205:3;19597:384;;19543:438;:::o;23029:381::-;23223:24;;:::i;:::-;23259:14;23276:41;23290:7;23299:4;23305:11;23276:13;:41::i;:::-;23259:58;;23334:69;23353:4;23359:20;23372:6;23359:12;:20::i;:::-;23381:8;23391:11;23334:18;:69::i;:::-;23327:76;23029:381;-1:-1:-1;;;;;;;23029:381:3:o;19149:340::-;-1:-1:-1;;;;;19233:31:3;;19215:15;19233:31;;;:20;:31;;;;;;19278:12;;19274:209;;-1:-1:-1;;;;;19306:31:3;;19340:1;19306:31;;;:20;:31;;;;;:35;19355:56;19327:9;19403:7;19355:36;:56::i;:::-;19453:9;-1:-1:-1;;;;;19430:42:3;;19464:7;19430:42;;;;4832:25:21;;4820:2;4805:18;;4686:177;19274:209:3;19205:284;19149:340;:::o;24453:275::-;24609:4;24632:89;24654:7;24663:4;24669:11;24682:9;14093:24:18;24609:4:3;24022:377;:::i;32223:224::-;32395:21;;;;;;;;;;;-1:-1:-1;;;32395:21:3;;;;;;;;32426:14;;;;;;;;;;;-1:-1:-1;;;32426:14:3;;;;32395:21;32223:224::o;29364:289::-;29446:14;29463:23;:21;:23::i;:::-;29446:40;;29523:7;-1:-1:-1;;;;;29510:27:3;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;29500:39:3;:6;-1:-1:-1;;;;;29500:39:3;;29496:150;;29558:59;;-1:-1:-1;;;29558:59:3;;-1:-1:-1;;;;;31270:32:21;;;29558:59:3;;;31252:51:21;1211:6:2;31319:18:21;;;31312:34;29558:32:3;;;;;31225:18:21;;29558:59:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;29553:93;;29619:27;:25;:27::i;4895:317:2:-;5012:14;5082:7;5078:2;5074:16;5068:4;5061:30;5118:4;5112;5104:19;5150:11;5144:4;5136:26;-1:-1:-1;;5191:4:2;5185:11;;4895:317;-1:-1:-1;;4895:317:2:o;41401:193:3:-;41462:18;41496:17;;;:9;:17;;;;;4949:6;41527:7;;;;41496:17;;-1:-1:-1;;;41527:7:3;;;:28;:33;;41523:64;;41569:18;;-1:-1:-1;;;41569:18:3;;;;;;;;;;;41523:64;41401:193;;;:::o;30870:126::-;-1:-1:-1;;;;;30939:20:3;;30935:54;;30968:21;;-1:-1:-1;;;30968:21:3;;;;;;;;;;;30935:54;30870:126;:::o;1961:485:7:-;2002:14;2107:8;2101:4;2094:22;2147:23;2199:10;2189:8;2186:24;2183:213;;2287:4;2281;2275;2269;2257:10;2250:5;2239:53;2229:153;;2329:4;2323;2316:18;2229:153;-1:-1:-1;;2425:4:7;2419:11;;1961:485::o;29830:143:3:-;29932:7;29920:19;;:9;:19;;;29916:50;;;29948:18;;-1:-1:-1;;;29948:18:3;;;;;;;;;;;30378:117;30450:5;:10;;30459:1;30450:10;30446:42;;30469:19;;-1:-1:-1;;;30469:19:3;;;;;;;;;;;34981:1700;35067:26;35096:21;;;;;;;;:::i;:::-;35067:50;-1:-1:-1;35127:19:3;35149:13;;;;;;;;:::i;:::-;35127:35;-1:-1:-1;;;;;;35339:25:3;;35335:58;;35373:20;;-1:-1:-1;;;35373:20:3;;;;;;;;;;;35335:58;-1:-1:-1;;35542:16:3;35519:39;;;35515:782;;35769:65;35801:1;:12;;;35815:18;35821:11;40515:14;40564:25;40628:4;40622;40612:21;;40456:193;35815:18;35769:16;;;;:1;:16;:::i;:::-;:31;;;;;:65::i;:::-;35768:66;:170;;;;;35855:83;35887:1;:12;;;35901:36;35907:11;35920:16;41078:4;41071:33;41022:14;41117:25;41181:4;41175;41165:21;;40935:267;35855:83;35854:84;35768:170;35747:233;;;35960:20;;-1:-1:-1;;;35960:20:3;;;;;;;;;;;35747:233;35515:782;;;36155:86;36187:1;:12;;;36201:39;36207:11;36220:19;41078:4;41071:33;41022:14;41117:25;41181:4;41175;41165:21;;40935:267;36155:86;36150:136;;36266:20;;-1:-1:-1;;;36266:20:3;;;;;;;;;;;36150:136;36384:14;36401:23;:21;:23::i;:::-;36384:40;-1:-1:-1;36439:53:3;-1:-1:-1;;;;;36449:21:3;;;;;;;;;36472:4;;;;;;;;:::i;:::-;-1:-1:-1;;;;;36472:19:3;;3395:9:2;;3388:17;3414:9;;3407:17;3385:40;;3288:153;36439:53:3;36434:241;;36579:56;36615:6;36623:11;36579:35;:56::i;:::-;36574:90;;36644:20;;-1:-1:-1;;;36644:20:3;;;;;;;;;;;34234:601;34343:16;;;;;;;;:::i;:::-;34330:29;;:10;;;;;;;;:::i;:::-;:29;;;34326:65;;;34368:23;;-1:-1:-1;;;34368:23:3;;;;;;;;;;;34326:65;34401:14;34418:19;34435:1;34418:16;:19::i;:::-;34401:36;;34452:92;34500:6;34508:22;34528:1;34508:19;:22::i;:::-;34532:11;;;;:1;:11;:::i;:::-;34452:47;:92::i;:::-;34447:136;;34565:18;;-1:-1:-1;;;34565:18:3;;;;;;;;;;;34447:136;34615:16;;;;;;;;:::i;:::-;34597:34;;:15;:34;34593:65;;;34640:18;;-1:-1:-1;;;34640:18:3;;;;;;;;;;;34593:65;34668:14;34685:47;34699:9;;;;:1;:9;:::i;34685:47::-;34668:64;-1:-1:-1;34747:50:3;34777:19;;;;;;;;:::i;:::-;34747:22;;;;:14;:22;;;;;;:50;;;;;:29;:50;:::i;:::-;34742:86;;34806:22;;-1:-1:-1;;;34806:22:3;;;;;;;;;;;34742:86;34316:519;;34234:601;;:::o;32722:1324::-;32928:9;32968:10;;;;;;;;:::i;:::-;32948:8;;;;32960:19;;;;-1:-1:-1;;;32948:8:3;;;;32940:39;;-1:-1:-1;;;;33023:13:3;;;33019:17;;33015:49;;;33045:19;;-1:-1:-1;;;33045:19:3;;;;;;;;;;;33015:49;33078:8;;;:20;;-1:-1:-1;;;;33078:20:3;-1:-1:-1;;;33078:20:3;;;;;;;-1:-1:-1;33191:47:3;33205:9;;;;;;:::i;33191:47::-;33174:64;-1:-1:-1;;;33256:21:3;;;;33252:778;;33297:26;33326:13;33297:26;33340:13;;;;;;;;:::i;:::-;-1:-1:-1;;;;;33326:28:3;;;;;;;;;;;;-1:-1:-1;33326:28:3;;-1:-1:-1;33409:10:3;;;;;;;;:::i;:::-;33401:19;;33384:13;33390:6;33384:1;:5;;:13;;;;:::i;:::-;33616:23;;;;33376:22;;;;:44;;;;;-1:-1:-1;33602:65:3;;-1:-1:-1;;;33616:23:3;;;33612:27;;33645:21;;;;;;;;:::i;:::-;33641:25;;:1;:25;3395:9:2;;3388:17;3414:9;;3407:17;3385:40;;3288:153;33602:65:3;33598:100;;;33676:22;;-1:-1:-1;;;33676:22:3;;;;;;;;;;;33598:100;3614:4:16;3607:22;;;3659:1;3655:13;;;3649:4;3642:27;;;3707:4;3691:21;;3825:8;;3751:21;3755:1;3751:21;;;;3951:9;;;3947:21;;3878:10;3940:29;3933:37;;3926:45;3916:56;;33279:476:3;33252:778;;;33779:26;33808:13;33779:26;33822:4;;;;;;;;:::i;:::-;-1:-1:-1;;;;;33808:19:3;;;;;;;;;;;;-1:-1:-1;33808:19:3;;-1:-1:-1;33882:10:3;;;;;;;;:::i;:::-;33874:19;;33857:13;33863:6;33857:1;:5;;:13;;;;:::i;:::-;33919:23;;;;33849:22;;;;:44;;;;;-1:-1:-1;;;;33919:23:3;;;;33915:27;;33911:62;;;33951:22;;-1:-1:-1;;;33951:22:3;;;;;;;;;;;33911:62;3614:4:16;3607:22;;;3659:1;3655:13;;;3649:4;3642:27;;;3707:4;3691:21;;3825:8;;3751:21;3755:1;3751:21;;;;3951:9;;;3947:21;;3878:10;3940:29;3933:37;;3926:45;3916:56;;33761:269:3;32848:1192;;32722:1324;;;:::o;37042:2188::-;37200:26;;:::i;:::-;37318:10;;37262:26;;37291:44;;-1:-1:-1;;;;;37318:10:3;37330:4;37291:26;:44::i;:::-;37521:6;;;;37262:73;;-1:-1:-1;37397:17:3;;-1:-1:-1;;;;;37521:6:3;;;:26;:6;:26;37517:407;;37585:7;;-1:-1:-1;;;;;;;;37585:7:3;;;;;37571:21;;;;37567:53;;;37601:19;;-1:-1:-1;;;37601:19:3;;;;;;;;;;;37567:53;-1:-1:-1;;;;;;37666:23:3;;37517:407;;;37714:15;;;37710:214;;-1:-1:-1;37769:10:3;;-1:-1:-1;;;;;37769:10:3;37761:19;;;;:7;:19;;;;;;-1:-1:-1;;;;;37761:19:3;37710:214;;;-1:-1:-1;37876:7:3;;-1:-1:-1;;;37876:7:3;;-1:-1:-1;;;;;37876:7:3;37710:214;37937:11;;;;:23;;;38177:17;;;38165:29;;;38152:10;;;;:42;;;38310:11;;-1:-1:-1;;;;;38288:33:3;;;:19;;;:33;;;38359:13;;;;:33;;;;38335:21;;;:57;;;38426:43;;;38406:17;;;:63;38598:12;;;;38569:59;;38165:29;38569:59;;1495:5:2;3012:9;;3008:17;;2854:187;38569:59:3;38546:20;;;:82;;;38805:17;;;;38782:40;38766:13;;;:56;-1:-1:-1;39017:10:3;;;39029:17;;;;1495:5:2;-1:-1:-1;;;39029:17:3;;;;;3012:9:2;;;3008:17;38983:14:3;;;:81;-1:-1:-1;;39196:17:3;;;;39183:10;;;;:30;39173:40;;38983:1;37042:2188;-1:-1:-1;;;;37042:2188:3:o;39525:700::-;39723:21;;;;39692:4;;39723:21;39815:54;;-1:-1:-1;;;;;;;39846:23:3;;;;39839:30;;39815:54;40128:90;-1:-1:-1;;;;;40139:23:3;;;;40164:53;40194:4;40200:16;40139:9;40515:14;40564:25;40628:4;40622;40612:21;;40456:193;40200:16;40164:14;;;;:29;:53::i;:::-;3999:9:2;3992:17;3980:9;;3973:17;3969:41;;3871:155;1672:479:15;2024:1;2015:10;;;1746;2004:22;;;;;;;;;;;;;2048:1;2039:4;2031:12;;;2004:40;2003:46;;1672:479::o;31914:133:3:-;-1:-1:-1;;;;;31990:15:3;;31986:54;;32014:26;;-1:-1:-1;;;32014:26:3;;;;;;;;;;;31408:365;31513:209;4805:9;-1:-1:-1;;;;;31540:42:3;:1;:11;;;-1:-1:-1;;;;;31540:42:3;;4660:9;-1:-1:-1;;;;;31600:46:3;:1;:13;;;-1:-1:-1;;;;;31600:46:3;;4525:4;31664:44;;:1;:12;;;:44;;;31513:9;:209::i;:::-;31496:270;;;31740:26;;-1:-1:-1;;;31740:26:3;;;;;;;;;;;30616:136;30693:10;30689:56;;30726:19;;-1:-1:-1;;;30726:19:3;;;;;;;;;;;30116:137;30198:5;:10;;30207:1;30198:10;30194:52;;30217:29;;-1:-1:-1;;;30217:29:3;;;;;;;;;;;31143:141;4392:4;31217:27;;;;31213:64;;;31253:24;;-1:-1:-1;;;31253:24:3;;;;;;;;;;;3228:164:16;3360:1;3351:10;;;3302:13;3343:19;;;;;;;;;;;;;3382:1;3367:16;;;;;;3343:41;;3228:164::o;5267:161:2:-;5353:10;5347:4;5340:24;5407:4;5401;5394:18;42040:163:3;42109:7;42135:21;42154:1;42510:7;;;-1:-1:-1;;;42510:7:3;;5240:6;42510:35;:40;;;42416:141;42135:21;:61;;42188:8;;;;-1:-1:-1;;;;;42188:8:3;42135:61;;;-1:-1:-1;42174:10:3;-1:-1:-1;;;;;42174:10:3;;;42159:26;;;;:14;:26;;;;;;;;42040:163::o;5739:840:13:-;5814:14;5997:22;8980:11;9121:9;9118:25;8935:14;9091:9;9088:28;9084:60;6033:76;;-1:-1:-1;8426:4:13;8420:11;;8487:16;8477:27;;8264:15;8531:4;8524:12;;8517:30;8307:18;8567:12;;;8560:33;;;;8627:9;8620:4;8613:12;;8606:31;8671:9;8664:4;8657:12;;8650:31;8720:4;8707:18;;6033:76;6243:18;6237:4;6230:32;6309:9;6303:4;6296:23;6376:10;6370:4;6363:24;6452:4;6446;6436:21;6426:31;;6561:1;6555:4;6548:15;6181:392;5739:840;;;:::o;5578:772:19:-;5742:6;5727:13;5724:25;5721:146;;;5781:10;5775:4;5768:24;5848:4;5842;5835:18;5721:146;5949:4;5942:5;5936:4;5929:5;5921:6;5917:2;5895:20;5890:64;5880:454;;5987:2;5981:4;5974:16;6060:4;6054;6046:19;6116:4;6110;6102:19;6195:4;6189;6181:6;6174:26;6164:156;;6272:5;6268:2;6264:14;6246:16;6239:5;6224:55;5578:772;;:::o;5487:169:2:-;5577:10;5571:4;5564:24;5635:4;5629;5622:18;2397:1407:18;2522:12;2619;2616:1134;;;2759:12;2756:1;2752:20;2738:12;2734:39;2885:12;2983:753;3176:20;;3167:30;;;3164:1;3160:38;3391:21;;;3453:4;3440:18;;;3433:48;3608:4;3602;3592:21;;3644:17;3692:15;;;2983:753;3682:36;2987:2;;2616:1134;-1:-1:-1;3774:14:18;;2397:1407;-1:-1:-1;;2397:1407:18:o;176:956:5:-;261:11;368:4;362:11;493:10;487:4;480:24;567:8;561:4;554:22;636:5;630:4;623:19;1020:4;1014;1008;1002;989:11;982:5;971:54;902:1;895:4;889:11;886:18;795:244;785:254;;1114:1;1108:4;1101:15;;176:956;;;;:::o;4820:3036:20:-;-1:-1:-1;;;;;5145:24:20;;;;4960:12;5172:6;5129:2711;;;5215:4;5209:11;5261:2;5243:16;5240:24;5237:1102;;5300:4;5294;5287:18;5382:4;5364:16;5360:27;5347:41;5344:1;5339:50;5333:4;5326:64;5456:4;5438:16;5432:4;5419:42;5863:4;5809;5757;5704;5646:1;5568:5;5528:384;6083:1;6077:8;6069:6;6065:21;6046:16;6039:24;6036:51;6026:295;;-1:-1:-1;6165:1:20;6159:4;6152:15;6225:4;6218:15;-1:-1:-1;6126:1:20;6294:5;;6026:295;;5237:1102;6369:1;6363:4;6356:15;6427:1;6421:4;6414:15;6501:10;6496:3;6492:20;6539:1;6536;6529:12;6638:4;6631;6628:1;6624:12;6617:26;6676:4;6673:1;6669:12;6708:4;6705:1;6698:15;6801:16;6794:4;6791:1;6787:12;6780:38;6926:16;6908;6901:4;6898:1;6894:12;6881:62;7726:4;7674:1;7610:4;7592:16;7588:27;7528:1;7471:6;7422:5;7386:400;7140:8;;7137:15;;;7018:786;;-1:-1:-1;;4820:3036:20;;;;;;:::o;2649:841:15:-;2829:1;2825:13;;;2721;2812:27;;;2859:4;2852:25;;;;2925:4;2909:21;;;3005:18;;3060:1;2967:4;2956:16;;;3049:13;;;;3091:23;;;3441:33;;;;3403:23;3396:31;3389:39;;2649:841::o;3488:133:2:-;3577:6;3395:9;;3388:17;3395:9;;3388:17;3414:9;;3407:17;3385:40;3414:9;3407:17;3385:40;3599:15;3288:153;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:286:21:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:21;;209:43;;199:71;;266:1;263;256:12;593:423;635:3;673:5;667:12;700:6;695:3;688:19;725:1;735:162;749:6;746:1;743:13;735:162;;;811:4;867:13;;;863:22;;857:29;839:11;;;835:20;;828:59;764:12;735:162;;;739:3;942:1;935:4;926:6;921:3;917:16;913:27;906:38;1005:4;998:2;994:7;989:2;981:6;977:15;973:29;968:3;964:39;960:50;953:57;;;593:423;;;;:::o;1021:220::-;1170:2;1159:9;1152:21;1133:4;1190:45;1231:2;1220:9;1216:18;1208:6;1190:45;:::i;1515:131::-;-1:-1:-1;;;;;1590:31:21;;1580:42;;1570:70;;1636:1;1633;1626:12;1651:134;1719:20;;1748:31;1719:20;1748:31;:::i;1790:156::-;1856:20;;1916:4;1905:16;;1895:27;;1885:55;;1936:1;1933;1926:12;1951:529;2033:6;2041;2049;2057;2110:3;2098:9;2089:7;2085:23;2081:33;2078:53;;;2127:1;2124;2117:12;2078:53;2166:9;2153:23;2185:31;2210:5;2185:31;:::i;:::-;2235:5;-1:-1:-1;2259:36:21;2291:2;2276:18;;2259:36;:::i;:::-;2249:46;;2314:36;2346:2;2335:9;2331:18;2314:36;:::i;:::-;2304:46;;2402:2;2391:9;2387:18;2374:32;2415:33;2440:7;2415:33;:::i;:::-;1951:529;;;;-1:-1:-1;1951:529:21;;-1:-1:-1;;1951:529:21:o;2485:456::-;2567:6;2575;2583;2591;2644:3;2632:9;2623:7;2619:23;2615:33;2612:53;;;2661:1;2658;2651:12;2612:53;2700:9;2687:23;2719:31;2744:5;2719:31;:::i;:::-;2769:5;-1:-1:-1;2793:36:21;2825:2;2810:18;;2793:36;:::i;:::-;2783:46;;2848:36;2880:2;2869:9;2865:18;2848:36;:::i;:::-;2485:456;;;;-1:-1:-1;2838:46:21;;2931:2;2916:18;2903:32;;-1:-1:-1;;2485:456:21:o;2946:317::-;3012:6;3020;3073:2;3061:9;3052:7;3048:23;3044:32;3041:52;;;3089:1;3086;3079:12;3041:52;3128:9;3115:23;3147:31;3172:5;3147:31;:::i;:::-;3197:5;-1:-1:-1;3221:36:21;3253:2;3238:18;;3221:36;:::i;:::-;3211:46;;2946:317;;;;;:::o;3268:163::-;3335:20;;3395:10;3384:22;;3374:33;;3364:61;;3421:1;3418;3411:12;3436:460;3517:6;3525;3533;3541;3594:3;3582:9;3573:7;3569:23;3565:33;3562:53;;;3611:1;3608;3601:12;3562:53;3650:9;3637:23;3669:31;3694:5;3669:31;:::i;:::-;3719:5;-1:-1:-1;3743:36:21;3775:2;3760:18;;3743:36;:::i;:::-;3733:46;;3798:36;3830:2;3819:9;3815:18;3798:36;:::i;:::-;3788:46;;3853:37;3886:2;3875:9;3871:18;3853:37;:::i;:::-;3843:47;;3436:460;;;;;;;:::o;4868:247::-;4927:6;4980:2;4968:9;4959:7;4955:23;4951:32;4948:52;;;4996:1;4993;4986:12;4948:52;5035:9;5022:23;5054:31;5079:5;5054:31;:::i;5120:533::-;5209:6;5217;5225;5233;5241;5294:3;5282:9;5273:7;5269:23;5265:33;5262:53;;;5311:1;5308;5301:12;5262:53;5350:9;5337:23;5369:31;5394:5;5369:31;:::i;:::-;5419:5;-1:-1:-1;5443:36:21;5475:2;5460:18;;5443:36;:::i;:::-;5433:46;;5498:36;5530:2;5519:9;5515:18;5498:36;:::i;:::-;5488:46;;5553:37;5586:2;5575:9;5571:18;5553:37;:::i;:::-;5543:47;;5609:38;5642:3;5631:9;5627:19;5609:38;:::i;:::-;5599:48;;5120:533;;;;;;;;:::o;5658:179::-;5725:20;;-1:-1:-1;;;;;5774:38:21;;5764:49;;5754:77;;5827:1;5824;5817:12;5842:460;5923:6;5931;5939;5947;6000:3;5988:9;5979:7;5975:23;5971:33;5968:53;;;6017:1;6014;6007:12;5968:53;6056:9;6043:23;6075:31;6100:5;6075:31;:::i;:::-;6125:5;-1:-1:-1;6149:36:21;6181:2;6166:18;;6149:36;:::i;:::-;6139:46;;6204:36;6236:2;6225:9;6221:18;6204:36;:::i;:::-;6194:46;;6259:37;6292:2;6281:9;6277:18;6259:37;:::i;6307:386::-;6392:6;6445:2;6433:9;6424:7;6420:23;6416:32;6413:52;;;6461:1;6458;6451:12;6413:52;6501:9;6488:23;6534:18;6526:6;6523:30;6520:50;;;6566:1;6563;6556:12;6520:50;6589:22;;6645:3;6627:16;;;6623:26;6620:46;;;6662:1;6659;6652:12;7275:277;7479:3;7464:19;;7492:54;7468:9;7528:6;-1:-1:-1;;;;;7054:2:21;7046:5;7040:12;7036:21;7031:3;7024:34;7119:2;7111:4;7104:5;7100:16;7094:23;7090:32;7083:4;7078:3;7074:14;7067:56;;7184:6;7176:4;7169:5;7165:16;7159:23;7155:36;7148:4;7143:3;7139:14;7132:60;7255:4;7248:5;7244:16;7238:23;7231:31;7224:39;7217:4;7212:3;7208:14;7201:63;6908:362;;;7557:184;7615:6;7668:2;7656:9;7647:7;7643:23;7639:32;7636:52;;;7684:1;7681;7674:12;7636:52;7707:28;7725:9;7707:28;:::i;7746:367::-;7809:8;7819:6;7873:3;7866:4;7858:6;7854:17;7850:27;7840:55;;7891:1;7888;7881:12;7840:55;-1:-1:-1;7914:20:21;;7957:18;7946:30;;7943:50;;;7989:1;7986;7979:12;7943:50;8026:4;8018:6;8014:17;8002:29;;8086:3;8079:4;8069:6;8066:1;8062:14;8054:6;8050:27;8046:38;8043:47;8040:67;;;8103:1;8100;8093:12;8040:67;7746:367;;;;;:::o;8118:855::-;8236:6;8244;8252;8260;8268;8276;8329:3;8317:9;8308:7;8304:23;8300:33;8297:53;;;8346:1;8343;8336:12;8297:53;8385:9;8372:23;8404:31;8429:5;8404:31;:::i;:::-;8454:5;-1:-1:-1;8478:36:21;8510:2;8495:18;;8478:36;:::i;:::-;8468:46;;8533:36;8565:2;8554:9;8550:18;8533:36;:::i;:::-;8523:46;;8621:2;8610:9;8606:18;8593:32;8634:33;8659:7;8634:33;:::i;:::-;8686:7;-1:-1:-1;8744:3:21;8729:19;;8716:33;8772:18;8761:30;;8758:50;;;8804:1;8801;8794:12;8758:50;8843:70;8905:7;8896:6;8885:9;8881:22;8843:70;:::i;:::-;8118:855;;;;-1:-1:-1;8118:855:21;;-1:-1:-1;8118:855:21;;8932:8;;8118:855;-1:-1:-1;;;8118:855:21:o;9171:712::-;9279:6;9287;9295;9303;9311;9364:3;9352:9;9343:7;9339:23;9335:33;9332:53;;;9381:1;9378;9371:12;9332:53;9420:9;9407:23;9439:31;9464:5;9439:31;:::i;:::-;9489:5;-1:-1:-1;9513:36:21;9545:2;9530:18;;9513:36;:::i;:::-;9503:46;;9568:36;9600:2;9589:9;9585:18;9568:36;:::i;:::-;9558:46;;9655:2;9644:9;9640:18;9627:32;9682:18;9674:6;9671:30;9668:50;;;9714:1;9711;9704:12;9668:50;9753:70;9815:7;9806:6;9795:9;9791:22;9753:70;:::i;:::-;9171:712;;;;-1:-1:-1;9171:712:21;;-1:-1:-1;9842:8:21;;9727:96;9171:712;-1:-1:-1;;;9171:712:21:o;9888:642::-;10053:2;10105:21;;;10175:13;;10078:18;;;10197:22;;;10024:4;;10053:2;10276:15;;;;10250:2;10235:18;;;10024:4;10319:185;10333:6;10330:1;10327:13;10319:185;;;10408:13;;10401:21;10394:29;10382:42;;10479:15;;;;10444:12;;;;10355:1;10348:9;10319:185;;;-1:-1:-1;10521:3:21;;9888:642;-1:-1:-1;;;;;;9888:642:21:o;10644:1259::-;11050:3;11045;11041:13;11033:6;11029:26;11018:9;11011:45;10992:4;11075:2;11113:3;11108:2;11097:9;11093:18;11086:31;11140:46;11181:3;11170:9;11166:19;11158:6;11140:46;:::i;:::-;11234:9;11226:6;11222:22;11217:2;11206:9;11202:18;11195:50;11268:33;11294:6;11286;11268:33;:::i;:::-;11332:2;11317:18;;11310:34;;;-1:-1:-1;;;;;11381:32:21;;11375:3;11360:19;;11353:61;11401:3;11430:19;;11423:35;;;11495:22;;;11489:3;11474:19;;11467:51;11567:13;;11589:22;;;11665:15;;;;-1:-1:-1;11627:15:21;;;;-1:-1:-1;11708:169:21;11722:6;11719:1;11716:13;11708:169;;;11783:13;;11771:26;;11852:15;;;;11817:12;;;;11744:1;11737:9;11708:169;;;-1:-1:-1;11894:3:21;;10644:1259;-1:-1:-1;;;;;;;;;;;;10644:1259:21:o;12090:127::-;12151:10;12146:3;12142:20;12139:1;12132:31;12182:4;12179:1;12172:15;12206:4;12203:1;12196:15;12222:344;12289:2;12283:9;12331:3;12319:16;;12365:18;12350:34;;12386:22;;;12347:62;12344:185;;;12451:10;12446:3;12442:20;12439:1;12432:31;12486:4;12483:1;12476:15;12514:4;12511:1;12504:15;12344:185;12545:2;12538:22;12222:344;:::o;12571:159::-;12638:20;;12698:6;12687:18;;12677:29;;12667:57;;12720:1;12717;12710:12;12735:118;12821:5;12814:13;12807:21;12800:5;12797:32;12787:60;;12843:1;12840;12833:12;12858:796;12922:5;12970:4;12958:9;12953:3;12949:19;12945:30;12942:50;;;12988:1;12985;12978:12;12942:50;13021:2;13015:9;13063:4;13055:6;13051:17;13134:6;13122:10;13119:22;13098:18;13086:10;13083:34;13080:62;13077:185;;;13184:10;13179:3;13175:20;13172:1;13165:31;13219:4;13216:1;13209:15;13247:4;13244:1;13237:15;13077:185;13278:2;13271:22;13311:6;-1:-1:-1;13311:6:21;13341:28;13359:9;13341:28;:::i;:::-;13333:6;13326:44;13403:37;13436:2;13425:9;13421:18;13403:37;:::i;:::-;13398:2;13390:6;13386:15;13379:62;13474:37;13507:2;13496:9;13492:18;13474:37;:::i;:::-;13469:2;13461:6;13457:15;13450:62;13564:2;13553:9;13549:18;13536:32;13577:30;13599:7;13577:30;:::i;:::-;13635:2;13623:15;;;;13616:32;12858:796;;-1:-1:-1;;12858:796:21:o;13659:248::-;13753:6;13806:3;13794:9;13785:7;13781:23;13777:33;13774:53;;;13823:1;13820;13813:12;13774:53;13846:55;13893:7;13882:9;13846:55;:::i;14011:2109::-;14092:12;;-1:-1:-1;;;;;10601:31:21;10589:44;;14156:4;14149:5;14145:16;14139:23;14171:46;14211:4;14206:3;14202:14;14188:12;1313:4;1302:16;1290:29;;1246:75;14171:46;;14265:4;14258:5;14254:16;14248:23;14280:48;14322:4;14317:3;14313:14;14297;1313:4;1302:16;1290:29;;1246:75;14280:48;;14376:4;14369:5;14365:16;14359:23;14391:50;14435:4;14430:3;14426:14;14410;-1:-1:-1;;;;;10601:31:21;10589:44;;10535:104;14391:50;;14489:4;14482:5;14478:16;14472:23;14504:49;14547:4;14542:3;14538:14;14522;-1:-1:-1;;;;;6763:38:21;6751:51;;6698:110;14504:49;;14601:4;14594:5;14590:16;14584:23;14616:49;14659:4;14654:3;14650:14;14634;13988:10;13977:22;13965:35;;13912:94;14616:49;;14713:4;14706:5;14702:16;14696:23;14728:49;14771:4;14766:3;14762:14;14746;13988:10;13977:22;13965:35;;13912:94;14728:49;;14825:4;14818:5;14814:16;14808:23;14840:49;14883:4;14878:3;14874:14;14858;13988:10;13977:22;13965:35;;13912:94;14840:49;-1:-1:-1;14908:6:21;14951:14;;;14945:21;13988:10;13977:22;;;15009:12;;;13965:35;;;;15041:6;15084:14;;;15078:21;13977:22;;;15142:12;;;13965:35;15174:6;15217:14;;;15211:21;6889:6;6878:18;15275:12;;;6866:31;15307:6;15351:14;;;15345:21;1313:4;1302:16;15409:12;;;1290:29;15441:6;15485:14;;;15479:21;375:13;368:21;15542:12;;;356:34;15574:6;15618:14;;;15612:21;375:13;368:21;15675:12;;;356:34;15707:6;15749:14;;;15743:21;15729:12;;;15722:43;15784:6;15826:14;;;15820:21;15806:12;;;15799:43;15861:6;15905:14;;;15899:21;-1:-1:-1;;;;;10601:31:21;15965:12;;;10589:44;15998:6;16042:15;;;16036:22;375:13;;368:21;16100:13;;;356:34;16067:47;305:91;16125:708;16348:2;16400:21;;;16470:13;;16373:18;;;16492:22;;;16319:4;;16348:2;16571:15;;;;16545:2;16530:18;;;16319:4;16614:193;16628:6;16625:1;16622:13;16614:193;;;16677:46;16719:3;16710:6;16704:13;16677:46;:::i;:::-;16782:15;;;;16752:6;16743:16;;;;;16650:1;16643:9;16614:193;;16838:318;16939:6;16947;17000:3;16988:9;16979:7;16975:23;16971:33;16968:53;;;17017:1;17014;17007:12;16968:53;17040:27;17057:9;17040:27;:::i;:::-;17030:37;;17086:64;17142:7;17137:2;17126:9;17122:18;17086:64;:::i;17582:460::-;17663:6;17671;17679;17687;17740:3;17728:9;17719:7;17715:23;17711:33;17708:53;;;17757:1;17754;17747:12;17708:53;17796:9;17783:23;17815:31;17840:5;17815:31;:::i;:::-;17865:5;-1:-1:-1;17889:36:21;17921:2;17906:18;;17889:36;:::i;:::-;17879:46;;17944:36;17976:2;17965:9;17961:18;17944:36;:::i;:::-;17934:46;;17999:37;18032:2;18021:9;18017:18;17999:37;:::i;18244:1233::-;18333:6;18386:3;18374:9;18365:7;18361:23;18357:33;18354:53;;;18403:1;18400;18393:12;18354:53;18429:17;;:::i;:::-;18469:29;18488:9;18469:29;:::i;:::-;18462:5;18455:44;18531:37;18564:2;18553:9;18549:18;18531:37;:::i;:::-;18526:2;18519:5;18515:14;18508:61;18601:37;18634:2;18623:9;18619:18;18601:37;:::i;:::-;18596:2;18589:5;18585:14;18578:61;18671:37;18704:2;18693:9;18689:18;18671:37;:::i;:::-;18666:2;18659:5;18655:14;18648:61;18742:38;18775:3;18764:9;18760:19;18742:38;:::i;:::-;18736:3;18729:5;18725:15;18718:63;18814:38;18847:3;18836:9;18832:19;18814:38;:::i;:::-;18808:3;18801:5;18797:15;18790:63;18886:38;18919:3;18908:9;18904:19;18886:38;:::i;:::-;18880:3;18873:5;18869:15;18862:63;18986:3;18975:9;18971:19;18958:33;18952:3;18945:5;18941:15;18934:58;19011:3;19046:36;19078:2;19067:9;19063:18;19046:36;:::i;:::-;19030:14;;;19023:60;19102:3;19137:38;19156:18;;;19137:38;:::i;:::-;19121:14;;;19114:62;19195:3;19230:36;19247:18;;;19230:36;:::i;:::-;19214:14;;;19207:60;19286:3;19321:38;19340:18;;;19321:38;:::i;:::-;19305:14;;;19298:62;19379:3;19427:18;;;19414:32;19398:14;;;19391:56;;;;-1:-1:-1;19309:5:21;18244:1233;-1:-1:-1;18244:1233:21:o;19482:387::-;19555:6;19563;19571;19624:2;19612:9;19603:7;19599:23;19595:32;19592:52;;;19640:1;19637;19630:12;19592:52;19679:9;19666:23;19698:31;19723:5;19698:31;:::i;:::-;19748:5;-1:-1:-1;19772:36:21;19804:2;19789:18;;19772:36;:::i;:::-;19762:46;;19827:36;19859:2;19848:9;19844:18;19827:36;:::i;:::-;19817:46;;19482:387;;;;;:::o;19874:250::-;20060:3;20045:19;;20073:45;20049:9;20100:6;20073:45;:::i;20129:523::-;20208:6;20216;20224;20232;20285:3;20273:9;20264:7;20260:23;20256:33;20253:53;;;20302:1;20299;20292:12;20253:53;20341:9;20328:23;20360:31;20385:5;20360:31;:::i;:::-;20410:5;-1:-1:-1;20434:36:21;20466:2;20451:18;;20434:36;:::i;:::-;20424:46;;20489:36;20521:2;20510:9;20506:18;20489:36;:::i;:::-;20479:46;;20577:2;20566:9;20562:18;20549:32;20590:30;20612:7;20590:30;:::i;20657:533::-;20746:6;20754;20762;20770;20778;20831:3;20819:9;20810:7;20806:23;20802:33;20799:53;;;20848:1;20845;20838:12;20799:53;20887:9;20874:23;20906:31;20931:5;20906:31;:::i;:::-;20956:5;-1:-1:-1;20980:36:21;21012:2;20997:18;;20980:36;:::i;:::-;20970:46;;21035:36;21067:2;21056:9;21052:18;21035:36;:::i;:::-;21025:46;;21090:37;21123:2;21112:9;21108:18;21090:37;:::i;:::-;21080:47;;21146:38;21179:3;21168:9;21164:19;21146:38;:::i;23072:182::-;23129:6;23182:2;23170:9;23161:7;23157:23;23153:32;23150:52;;;23198:1;23195;23188:12;23150:52;23221:27;23238:9;23221:27;:::i;23626:184::-;23684:6;23737:2;23725:9;23716:7;23712:23;23708:32;23705:52;;;23753:1;23750;23743:12;23705:52;23776:28;23794:9;23776:28;:::i;24068:545::-;24161:4;24167:6;24227:11;24214:25;24321:2;24317:7;24306:8;24290:14;24286:29;24282:43;24262:18;24258:68;24248:96;;24340:1;24337;24330:12;24248:96;24367:33;;24419:20;;;-1:-1:-1;24462:18:21;24451:30;;24448:50;;;24494:1;24491;24484:12;24448:50;24527:4;24515:17;;-1:-1:-1;24578:1:21;24574:14;;;24558;24554:35;24544:46;;24541:66;;;24603:1;24600;24593:12;24991:184;25061:6;25114:2;25102:9;25093:7;25089:23;25085:32;25082:52;;;25130:1;25127;25120:12;25082:52;-1:-1:-1;25153:16:21;;24991:184;-1:-1:-1;24991:184:21:o;25180:1637::-;25467:4;25455:17;;;25437:36;;25509:17;;25504:2;25489:18;;25482:45;25554:13;;13988:10;13977:22;25584:2;25569:18;;13965:35;25424:3;25409:19;;25642:2;25630:15;;25624:22;25619:2;25604:18;;25597:50;25694:2;25682:15;;25676:22;-1:-1:-1;;;;;10601:31:21;;25755:3;25740:19;;10589:44;-1:-1:-1;25809:2:21;25797:15;;25791:22;13988:10;13977:22;;25871:3;25856:19;;13965:35;-1:-1:-1;25925:3:21;25913:16;;25907:23;13988:10;13977:22;;25988:3;25973:19;;13965:35;-1:-1:-1;26042:3:21;26030:16;;26024:23;13988:10;13977:22;;26105:3;26090:19;;13965:35;26056:54;26159:3;26151:6;26147:16;26141:23;26183:3;26195:54;26245:2;26234:9;26230:18;26214:14;-1:-1:-1;;;;;10601:31:21;10589:44;;10535:104;26195:54;26298:3;26290:6;26286:16;26280:23;26258:45;;26322:3;26334:51;26381:2;26370:9;26366:18;26350:14;375:13;368:21;356:34;;305:91;26334:51;26410:15;;;26404:22;26445:3;26464:18;;;26457:30;;;;26512:15;;;26506:22;26547:3;26566:18;;;26559:30;;;;26614:15;;;26608:22;26649:3;26668:18;;;26661:30;;;;26734:15;;;26728:22;26722:3;26707:19;;26700:51;26794:15;;;26788:22;26782:3;26767:19;;;26760:51;;;;25180:1637;;-1:-1:-1;;;25180:1637:21:o;26822:127::-;26883:10;26878:3;26874:20;26871:1;26864:31;26914:4;26911:1;26904:15;26938:4;26935:1;26928:15;26954:355;27225:4;27213:17;;27195:36;;27182:3;27167:19;;27240:63;27299:2;27284:18;;27276:6;-1:-1:-1;;;;;7054:2:21;7046:5;7040:12;7036:21;7031:3;7024:34;7119:2;7111:4;7104:5;7100:16;7094:23;7090:32;7083:4;7078:3;7074:14;7067:56;;7184:6;7176:4;7169:5;7165:16;7159:23;7155:36;7148:4;7143:3;7139:14;7132:60;7255:4;7248:5;7244:16;7238:23;7231:31;7224:39;7217:4;7212:3;7208:14;7201:63;6908:362;;;27663:1818;27948:4;27936:17;;;27918:36;;27990:17;;27985:2;27970:18;;27963:45;28036:13;;-1:-1:-1;;;;;10601:31:21;28066:2;28051:18;;10589:44;27905:3;27890:19;;28117:2;28105:15;;28099:22;-1:-1:-1;;;;;6763:38:21;;28177:2;28162:18;;6751:51;-1:-1:-1;28230:2:21;28218:15;;28212:22;13988:10;13977:22;;28292:3;28277:19;;13965:35;-1:-1:-1;28346:2:21;28334:15;;28328:22;13988:10;13977:22;;28408:3;28393:19;;13965:35;-1:-1:-1;28462:3:21;28450:16;;28444:23;13988:10;13977:22;;28525:3;28510:19;;13965:35;-1:-1:-1;28579:3:21;28567:16;;28561:23;13988:10;13977:22;;28642:3;28627:19;;13965:35;28593:54;28696:3;28688:6;28684:16;28678:23;28720:3;28732:53;28781:2;28770:9;28766:18;28750:14;6889:6;6878:18;6866:31;;6813:90;28732:53;28822:3;28810:16;;28804:23;28846:3;28865:18;;;28858:30;;;;28925:15;;;28919:22;;-1:-1:-1;28960:3:21;;28972:52;29005:18;;;28919:22;1313:4;1302:16;1290:29;;1246:75;28972:52;29061:15;;29055:22;;-1:-1:-1;29096:3:21;29108:54;29143:18;;;29055:22;-1:-1:-1;;;;;10601:31:21;10589:44;;10535:104;29108:54;29199:15;;;29193:22;;-1:-1:-1;29234:3:21;;29246:52;29279:18;;;29193:22;1313:4;1302:16;1290:29;;1246:75;29246:52;29335:15;;29329:22;-1:-1:-1;;;;;10601:31:21;29410:3;29395:19;;10589:44;29458:15;;;29452:22;29446:3;29431:19;;;29424:51;;;;27663:1818;;-1:-1:-1;;;27663:1818:21:o;30822:251::-;30892:6;30945:2;30933:9;30924:7;30920:23;30916:32;30913:52;;;30961:1;30958;30951:12;30913:52;30993:9;30987:16;31012:31;31037:5;31012:31;:::i;31357:245::-;31424:6;31477:2;31465:9;31456:7;31452:23;31448:32;31445:52;;;31493:1;31490;31483:12;31445:52;31525:9;31519:16;31544:28;31566:5;31544:28;:::i;31607:521::-;31684:4;31690:6;31750:11;31737:25;31844:2;31840:7;31829:8;31813:14;31809:29;31805:43;31785:18;31781:68;31771:96;;31863:1;31860;31853:12;31771:96;31890:33;;31942:20;;;-1:-1:-1;31985:18:21;31974:30;;31971:50;;;32017:1;32014;32007:12;31971:50;32050:4;32038:17;;-1:-1:-1;32081:14:21;32077:27;;;32067:38;;32064:58;;;32118:1;32115;32108:12
Swarm Source
ipfs://82a9fe6d3c01d9f8932f133836ed974fec48211730542b3dc9d954d491f40651
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.