Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Multichain Info
No addresses found
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
416950 | 55 days ago | Contract Creation | 0 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:
MintFeeOracle
Compiler Version
v0.8.10+commit.fc410830
ZkSolc Version
v1.5.6
Optimization Enabled:
Yes with Mode z
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.10; import "./interfaces/IMintFeeOracle.sol"; import "./interfaces/IAbridgedMintVector.sol"; import "./mechanics/interfaces/IMechanicMintManagerView.sol"; import "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "../utils/FullMath.sol"; import "../utils/IUniswapV3PoolState.sol"; import "./referrals/IReferralManagerView.sol"; import "../erc1155/interfaces/IERC1155Standard.sol"; /** * @title MintManager's mint fee oracle * @author highlight.xyz */ contract MintFeeOracle is UUPSUpgradeable, OwnableUpgradeable { /** * @notice Throw when an action is unauthorized */ error Unauthorized(); /** * @notice Throw when an ERC20 is invalid */ error InvalidERC20(); /** * @notice Throw when an ERC20 config is invalid */ error InvalidERC20Config(); /** * @notice Throw when caller is not the MintManager */ error NotMintManager(); /** * @notice Throw when an invalid ether value is sent in when processing an ether mint fee cap */ error InvalidEtherMintFeeCap(); /** * @notice Throw when sending ether fails */ error EtherSendFailed(); /** * @notice Throw when a mint vector's expected type is false */ error InvalidVectorType(); /** * @notice Throw when resolved referrer is invalid */ error InvalidReferrer(); /** * @notice Config for allowlisted ERC20s * @param baseMintFee Base fee fee amount per token (if price isn't real-time) * @param realTimeOracle Address of real time oracle to query if price is real-time */ struct ERC20Config { uint96 baseMintFee; address realTimeOracle; } /** * @notice MintManager */ address private _mintManager; /** * @notice Mint fee subsidized config (vector + user) */ mapping(bytes32 => bool) private _subsidizedMintConfig; /** * @notice Gasless mechanic address */ address private _gaslessMechanicAddress; /** * @notice Allowlisted ERC20s -> mint fee */ mapping(address => ERC20Config) private _allowlistedERC20s; /** * @notice When true, creator rewards is enabled */ bool private _creatorRewardsEnabled; /** * @notice Constants for uniswap price calculation */ uint256 public constant ETH_WEI = 10 ** 18; uint256 public constant FULL_MATH_SHIFT = 1 << 192; /** * @notice Backup referral manager */ address private _backupReferralManager; /** * @notice Backup referral manager */ address private _backupDiscreteDutchAuctionMechanic; /** * @notice Backup referral manager */ address private _backupRankedAuctionMechanic; /** * @notice Emitted when a referrer is paid out a portion of the mint fee * @param vectorId Vector ID * @param referrer Referrer * @param currency Currency * @param referralPayout Amount paid out to referrer */ event ReferralPayout( bytes32 indexed vectorId, address indexed referrer, address indexed currency, uint256 referralPayout ); /** * @notice Only let the mint manager call */ modifier onlyMintManager() { if (msg.sender != _mintManager) { _revert(NotMintManager.selector); } _; } /* solhint-disable no-empty-blocks */ /** * @notice Initialize contract */ function initialize( address mintManager, address platform, address gaslessMechanic, address backupReferralManager, address backupDiscreteDutchAuctionMechanic, address backupRankedAuctionMechanic ) external initializer { __Ownable_init(); _transferOwnership(platform); _mintManager = mintManager; _gaslessMechanicAddress = gaslessMechanic; _backupReferralManager = backupReferralManager; _backupDiscreteDutchAuctionMechanic = backupDiscreteDutchAuctionMechanic; _backupRankedAuctionMechanic = backupRankedAuctionMechanic; } /** * @notice Set an allowlisted erc20 config * @param erc20 ERC20 address * @param config ERC20 config */ function setAllowlistedERC20Config(address erc20, ERC20Config calldata config) external onlyOwner { if ( !(config.baseMintFee != 0 && config.realTimeOracle == address(0)) && !(config.baseMintFee == 0 && config.realTimeOracle != address(0)) ) { _revert(InvalidERC20Config.selector); } _allowlistedERC20s[erc20] = config; } /** * @notice Delist an allowlisted erc20 config * @param erc20 ERC20 address */ function delistERC20(address erc20) external onlyOwner { delete _allowlistedERC20s[erc20]; } /** * @notice Set mint manager */ function setMintManager(address newMintManager) external onlyOwner { _mintManager = newMintManager; } /** * @notice Set backup referral manager */ function setBackupReferralManager(address newBackupReferralManager) external onlyOwner { _backupReferralManager = newBackupReferralManager; } /** * @notice Set backup discrete dutch auction mechanic */ function setBackupDiscreteDutchAuctionMechanic(address newBackupDiscreteDutchAuctionMechanic) external onlyOwner { _backupDiscreteDutchAuctionMechanic = newBackupDiscreteDutchAuctionMechanic; } /** * @notice Set backup ranked auction mechanic */ function setBackupRankedAuctionMechanic(address newBackupRankedAuctionMechanic) external onlyOwner { _backupRankedAuctionMechanic = newBackupRankedAuctionMechanic; } /** * @notice Set gasless mechanic */ function setGaslessMechanic(address newGaslessMechanic) external onlyOwner { _gaslessMechanicAddress = newGaslessMechanic; } /** * @notice Set creator rewards enabled */ function setCreatorRewardsEnabled(bool creatorRewardsEnabled) external onlyOwner { _creatorRewardsEnabled = creatorRewardsEnabled; } /** * @notice Subsidize mint fee for a mint config (vector + sender) */ function subsidizeMintConfig(bytes32 vectorId, address minter) external onlyOwner { bytes32 mintConfig = _encodeMintConfig(vectorId, minter); require(!_subsidizedMintConfig[mintConfig], "Already subsidized"); _subsidizedMintConfig[mintConfig] = true; } /** * @notice Subsidize mint fee for a mint config (vector + sender) */ function unsubsidizeMintVector(bytes32 vectorId, address minter) external onlyOwner { bytes32 mintConfig = _encodeMintConfig(vectorId, minter); require(_subsidizedMintConfig[mintConfig], "Not already subsidized"); _subsidizedMintConfig[mintConfig] = false; } /** * @notice Withdraw native gas token owed to platform */ function withdrawNativeGasToken(uint256 amountToWithdraw, address payable recipient) external onlyOwner { (bool sentToPlatform, ) = recipient.call{ value: amountToWithdraw }(""); if (!sentToPlatform) { _revert(EtherSendFailed.selector); } } /** * @notice Withdraw ERC20 owed to platform */ function withdrawERC20(address currency, uint256 amountToWithdraw, address recipient) external onlyOwner { IERC20(currency).transfer(recipient, amountToWithdraw); } /* solhint-disable code-complexity */ /** * @notice See {IMintFeeOracle-processClassicVectorMintFeeCap} */ function processClassicVectorMintFeeCap( bytes32 vectorId, bool payoutCreatorReward, address vectorPaymentRecipient, address currency, uint256 amount, address minter, bool is1155 ) external payable onlyMintManager returns (uint256) { if (currency == address(0)) { if (msg.value != amount) { _revert(InvalidEtherMintFeeCap.selector); } } address referralManager = _referralManager(); if (referralManager == minter) { uint256 referralPayout = (amount * 10) / 100; // get referrer via referral manager address referrer = IReferralManagerView(referralManager).getCurrentReferrer(vectorId); if (referrer != address(0)) { if (currency == address(0)) { (bool sentToRecipient, ) = payable(referrer).call{ value: referralPayout }(""); if (!sentToRecipient) { _revert(EtherSendFailed.selector); } } else { IERC20(currency).transfer(referrer, referralPayout); } emit ReferralPayout(vectorId, referrer, currency, referralPayout); } } if (payoutCreatorReward) { uint256 creatorPayout = is1155 ? ((amount * 8) / 10) : amount / 2; if (currency == address(0)) { (bool sentToRecipient, ) = vectorPaymentRecipient.call{ value: creatorPayout }(""); if (!sentToRecipient) { _revert(EtherSendFailed.selector); } } else { IERC20(currency).transfer(vectorPaymentRecipient, creatorPayout); } return creatorPayout; } return 0; } /* solhint-enable code-complexity */ /** * @notice See {IMintFeeOracle-getClassicVectorMintFeeCap} */ function getClassicVectorMintFeeCap( bytes32 vectorId, uint256 numToMint, address minter, address currency, address collectionContract ) external view returns (uint256, bool) { bool is1155 = _is1155(collectionContract); if (_isFeeSubsidized(vectorId, minter)) { return (0, is1155); } if (currency == address(0)) { return (_nativeGasTokenMintFee(is1155) * numToMint, is1155); } else { return (_getClassicVectorERC20MintFeeCap(currency, numToMint, is1155), is1155); } } /** * @notice See {IMintFeeOracle-getMechanicMintFee} */ function getMechanicMintFee( bytes32 mechanicVectorId, uint32 numToMint, address mechanic, address minter, address collectionContract ) external view returns (uint256) { if (_isMintFeeWaivedMechanic(mechanic) || _isFeeSubsidized(mechanicVectorId, minter)) { return 0; } else { return _nativeGasTokenMintFee(collectionContract) * uint256(numToMint); } } /** * @notice Get public vector mint fee (optimized for offchain querying) */ function getPublicVectorMintFee( uint256 vectorId, uint256 numToMint, address minter ) external view returns (uint256, address) { if (_isFeeSubsidized(bytes32(vectorId), minter)) { return (0, address(0)); } IAbridgedMintVector.AbridgedVector memory _vector = IAbridgedMintVector(_mintManager).getAbridgedVector( vectorId ); if (_vector.contractAddress == address(0)) { _revert(InvalidVectorType.selector); } if (_vector.currency != address(0)) { return ( _getClassicVectorERC20MintFeeCap(_vector.currency, numToMint, _vector.contractAddress), _vector.currency ); } else { return (_nativeGasTokenMintFee(_vector.contractAddress) * uint256(numToMint), address(0)); } } /** * @notice Get gated vector mint fee (optimized for offchain querying) */ function getGatedVectorMintFee( bytes32 vectorId, uint256 numToMint, address minter, address currency, address collectionContract ) external view returns (uint256, address) { if (_isFeeSubsidized(vectorId, minter)) { return (0, currency); } if (currency != address(0)) { return (_getClassicVectorERC20MintFeeCap(currency, numToMint, collectionContract), currency); } return (_nativeGasTokenMintFee(collectionContract) * uint256(numToMint), address(0)); } /** * @notice Get mechanic vector mint fee (optimized for offchain querying) */ function getMechanicVectorMintFee( bytes32 vectorId, uint256 numToMint, address minter ) external view returns (uint256, address) { IMechanicData.MechanicVectorMetadata memory _mechanicMetadata = IMechanicMintManagerView(_mintManager) .mechanicVectorMetadata(vectorId); if (_mechanicMetadata.contractAddress == address(0)) { _revert(InvalidVectorType.selector); } if (_isMintFeeWaivedMechanic(_mechanicMetadata.mechanic) || _isFeeSubsidized(vectorId, minter)) { return (0, address(0)); } return (_nativeGasTokenMintFee(_mechanicMetadata.contractAddress) * uint256(numToMint), address(0)); } /** * @notice Limit upgrades of contract to MintFeeOracle owner * @param // New implementation address */ function _authorizeUpgrade(address) internal override onlyOwner {} /** * @dev For more efficient reverts. */ function _revert(bytes4 errorSelector) internal pure { assembly { mstore(0x00, errorSelector) revert(0x00, 0x04) } } /** * @notice Return if mint fee is subsidized for a mint config * @param vectorId ID of vector * @param minter Original minter address */ function _isFeeSubsidized(bytes32 vectorId, address minter) private view returns (bool) { return _subsidizedMintConfig[_encodeMintConfig(vectorId, minter)]; } /** * @notice Encode a mint config * @param vectorId ID of vector * @param minter Original minter address */ function _encodeMintConfig(bytes32 vectorId, address minter) private pure returns (bytes32) { return keccak256(abi.encodePacked(vectorId, minter)); } function _getClassicVectorERC20MintFeeCap( address currency, uint256 numToMint, address collectionContract ) private view returns (uint256) { ERC20Config memory config = _allowlistedERC20s[currency]; uint256 divisor = _is1155(collectionContract) ? 2 : 1; if (config.baseMintFee != 0) { return (config.baseMintFee / divisor) * numToMint; } else if (config.realTimeOracle != address(0)) { (uint160 sqrtPriceX96, , , , , , ) = IUniswapV3PoolState(config.realTimeOracle).slot0(); return _nativeGasTokenMintFee(collectionContract) * sqrtPriceX96ToUint(sqrtPriceX96) * numToMint; } else { _revert(InvalidERC20.selector); } } function _getClassicVectorERC20MintFeeCap( address currency, uint256 numToMint, bool is1155 ) private view returns (uint256) { ERC20Config memory config = _allowlistedERC20s[currency]; uint256 divisor = is1155 ? 2 : 1; if (config.baseMintFee != 0) { return (config.baseMintFee / divisor) * numToMint; } else if (config.realTimeOracle != address(0)) { (uint160 sqrtPriceX96, , , , , , ) = IUniswapV3PoolState(config.realTimeOracle).slot0(); return _nativeGasTokenMintFee(is1155) * sqrtPriceX96ToUint(sqrtPriceX96) * numToMint; } else { _revert(InvalidERC20.selector); } } /* solhint-disable code-complexity */ function _isMintFeeWaivedMechanic(address mechanic) private view returns (bool) { // RAM, DDAM // we don't hit mint fee oracle in case of gasless mechanic if (block.chainid == 1) { return mechanic == 0xDFEe0Ed4A217F37b3FA87624eE00fe5685bDc509 || mechanic == 0x94Fa6e7Fc2555aDA63eA56cfFF425558360F0074; } else if (block.chainid == 8453) { return mechanic == 0x922E9f8cc491fACBd403afa143AA53ee9146474C || mechanic == 0xA748BE280C9a00edaF7d04076FE8A93c59e95B03; } else if (block.chainid == 10) { return mechanic == 0xb207774Ac4E32eCE47771e64BDE5ec3894C1De6b || mechanic == 0x15753e20667961fB30d5aa92e2255B876568BE7e; } else if (block.chainid == 42161) { return mechanic == 0x7f75358787f880506c5dc6100386F77be8DE0A30 || mechanic == 0x3a2aFe86E594540cbf3eA345dd29e09228f186D2; } else if (block.chainid == 7777777) { return mechanic == 0x0AFB6566C836D1C4788cD2b54Bd9cA0158CC2D3D || mechanic == 0xf12A4018647DD2275072967Fd5F3ac5Fef7a0471; } else if (block.chainid == 137) { return mechanic == 0x4CCB72E7E0Cd948aF50bC7Bf598Fc4E027b70f98 || mechanic == 0xAE22Cd8052D64e7C2aF6B5E3045Fab0a86C8334C; } else if (block.chainid == 11155111) { return mechanic == 0xa2D14CA9985De170db128c8CB74Cecb35eEAF47E || mechanic == 0xceBc3B3134FbEF95ED13AEcdF997D4371d022385; } else if (block.chainid == 84532) { return mechanic == 0x9958F83F383CA150BB2252B4275D3e3051be469F || mechanic == 0x4821B6e9aC0CCC590acCe2442bb6BB32388C1CB7; } else if (block.chainid == 984122) { return mechanic == 0x5AA1C7F5f9d2e7F2664d3C1f454560C6DaBED6c8 || mechanic == 0x9c602CE508E41ccAF2cF997D93A9FbE0166D8aE6; } else if (block.chainid == 5000) { return mechanic == 0xd8f0A3AA4067be3D70a5B46A795Ad9dF9E65Cd3C || mechanic == 0xaF4d61951A425BA60ac1E7EA6d51e92d2F4748E4; } else if (block.chainid == 534352) { return mechanic == 0xF6C67C7bb7018E4609d571023196A4682FdA6F2f || mechanic == 0xE019FF8033d9C761985A3EE1fa5d97Cc9Cf6d5c0; } else if (block.chainid == 324) { return mechanic == 0x89640D083837d9487e4E1c2122aCc1adaf0E5654 || mechanic == 0xc1c701D7A488b46fF095Ec4094DDd5aB78C9421E; } else if (block.chainid == 360) { return mechanic == 0x8c23711a0536397C261Bf83Ec474B9aAf05C549B || mechanic == 0xd8f0A3AA4067be3D70a5B46A795Ad9dF9E65Cd3C; } else if (block.chainid == 7560) { return mechanic == 0x8c23711a0536397C261Bf83Ec474B9aAf05C549B || mechanic == 0x526fe4Ed6f23f34a97015E41f469fD54f37036f5; } else if (block.chainid == 543210) { return mechanic == 0x99F80FF8C7607E8E6b6A998E9389DcaEc97BA9c9 || mechanic == 0xD5B168f790582255c9c82cB65193A009cD6C2c67; } else if (block.chainid == 2741) { return mechanic == 0x6B590EA2e6CcB5011617c3a09bb29eBDa8459875 || mechanic == 0xE91dCebFE7F3E0B2D59b67f196Fb33e339007c46; } return mechanic == _backupDiscreteDutchAuctionMechanic || mechanic == _backupRankedAuctionMechanic || mechanic == _gaslessMechanicAddress; } /** * @notice Get the referral manager */ function _referralManager() private view returns (address) { if (block.chainid == 1) { return 0xD3C63951b2Ed18e8d92B5b251C3B636A45A547d0; } else if (block.chainid == 8453) { return 0xd9E58978808d17F99ccCEAb5195B052E972c0188; } else if (block.chainid == 10) { return 0x9CF5B12D2e2a88083647Ff2Fe0610F818b28eC77; } else if (block.chainid == 7777777) { return 0x7Cb2cecFCFFdccE0bf69366e52caec6BD719CD44; } else if (block.chainid == 42161) { return 0x617b2383D93909590fAC0b2aaa547EC5615d82eF; } else if (block.chainid == 137) { return 0x6fd07d4B5fd7093762Fb2f278769aa7e2511d45c; } else if (block.chainid == 84532) { return 0x4619b9673241eB41B642Dc04371100d238b73fFE; } else if (block.chainid == 11155111) { return 0xd33c1bE264bb98F86e18CD816D5fd44e97cb7163; } else if (block.chainid == 984122) { return 0x9491aA1c2f46319A645637c4105f4199B251e4dD; } else if (block.chainid == 5000) { return 0xAFfC7C9BfB48FFD2a580e1a0d36f8cc7D45Dcb58; } else if (block.chainid == 534352) { return 0x4821B6e9aC0CCC590acCe2442bb6BB32388C1CB7; } else if (block.chainid == 324) { return 0x4b189127A784de57bDcDb59E0Ab18086e0b7a1BC; } else if (block.chainid == 360) { return 0xe2CE42156E8456704fbEA047419404858E9324Af; } else if (block.chainid == 7560) { return 0xF76d8B2aFB77f663d420F827fCa7bCc1b419515F; } else if (block.chainid == 543210) { return 0x24d7F95783F5F5Ed37BCbbE303A14bE0627DFC2e; } else if (block.chainid == 2741) { return 0xc189E4b2C3eBf75A56fafB5697f82C73376B6549; } else { return _backupReferralManager; } } /** * @notice Get the native gas token mint fee for the chain */ function _nativeGasTokenMintFee(address collectionContract) private view returns (uint256) { uint256 divisor = _is1155(collectionContract) ? 2 : 1; if (block.chainid == 137) { return 2265000000000000000 / divisor; } else if (block.chainid == 984122) { return 500000000000000000 / divisor; } else if (block.chainid == 5000) { return 3500000000000000000 / divisor; } else { return 800000000000000 / divisor; } } /** * @notice Get the native gas token mint fee for the chain */ function _nativeGasTokenMintFee(bool is1155) private view returns (uint256) { uint256 divisor = is1155 ? 2 : 1; if (block.chainid == 137) { return 2265000000000000000 / divisor; } else if (block.chainid == 984122) { return 500000000000000000 / divisor; } else if (block.chainid == 5000) { return 3500000000000000000 / divisor; } else { return 800000000000000 / divisor; } } /** * @notice Convert uniswap sqrtX96 price * @dev token0 always assumed to be ETH */ function sqrtPriceX96ToUint(uint160 sqrtPriceX96) private pure returns (uint256) { return FullMath.mulDiv(uint256(sqrtPriceX96) * uint256(sqrtPriceX96), ETH_WEI, FULL_MATH_SHIFT); } /** * @notice Return if collection is an ERC1155 contract */ function _is1155(address collectionContract) private view returns (bool) { try IERC1155Standard(collectionContract).highlightContractStandardHash() returns (bytes32 standardHash) { return standardHash == 0x3a9654d81ac4dafbb9a2fb1cd3efa3de2783ae40b06b17a456bf5922ed02a3a7; } catch Error(string memory reason) { return false; } catch { return false; } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.10; /* solhint-disable max-line-length */ /// @title Contains 512-bit math functions /// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision /// @dev Handles "phantom overflow" i.e., allows multiplication and division where an intermediate value overflows 256 bits library FullMath { /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 /// @param a The multiplicand /// @param b The multiplier /// @param denominator The divisor /// @return result The 256-bit result /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv function mulDiv(uint256 a, uint256 b, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = a * b // Compute the product mod 2**256 and mod 2**256 - 1 // then use the Chinese Remainder Theorem to reconstruct // the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2**256 + prod0 uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(a, b, not(0)) prod0 := mul(a, b) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division if (prod1 == 0) { require(denominator > 0); assembly { result := div(prod0, denominator) } return result; } // Make sure the result is less than 2**256. // Also prevents denominator == 0 require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0] // Compute remainder using mulmod uint256 remainder; assembly { remainder := mulmod(a, b, denominator) } // Subtract 256 bit number from 512 bit number assembly { prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator // Compute largest power of two divisor of denominator. // Always >= 1. uint256 twos = (0 - denominator) & denominator; // Divide denominator by power of two assembly { denominator := div(denominator, twos) } // Divide [prod1 prod0] by the factors of two assembly { prod0 := div(prod0, twos) } // Shift in bits from prod1 into prod0. For this we need // to flip `twos` such that it is 2**256 / twos. // If twos is zero, then it becomes one assembly { twos := add(div(sub(0, twos), twos), 1) } prod0 |= prod1 * twos; // Invert denominator mod 2**256 // Now that denominator is an odd number, it has an inverse // modulo 2**256 such that denominator * inv = 1 mod 2**256. // Compute the inverse by starting with a seed that is correct // correct for four bits. That is, denominator * inv = 1 mod 2**4 uint256 inv = (3 * denominator) ^ 2; // Now use Newton-Raphson iteration to improve the precision. // Thanks to Hensel's lifting lemma, this also works in modular // arithmetic, doubling the correct bits in each step. inv *= 2 - denominator * inv; // inverse mod 2**8 inv *= 2 - denominator * inv; // inverse mod 2**16 inv *= 2 - denominator * inv; // inverse mod 2**32 inv *= 2 - denominator * inv; // inverse mod 2**64 inv *= 2 - denominator * inv; // inverse mod 2**128 inv *= 2 - denominator * inv; // inverse mod 2**256 // Because the division is now exact we can divide by multiplying // with the modular inverse of denominator. This will give us the // correct result modulo 2**256. Since the precoditions guarantee // that the outcome is less than 2**256, this is the final result. // We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inv; return result; } } /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 /// @param a The multiplicand /// @param b The multiplier /// @param denominator The divisor /// @return result The 256-bit result function mulDivRoundingUp(uint256 a, uint256 b, uint256 denominator) internal pure returns (uint256 result) { unchecked { result = mulDiv(a, b, denominator); if (mulmod(a, b, denominator) > 0) { require(result < type(uint256).max); result++; } } } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.10; /* solhint-disable max-line-length */ /// @title Pool state that can change /// @notice These methods compose the pool's state, and can change with any frequency including multiple times /// per transaction interface IUniswapV3PoolState { /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas /// when accessed externally. /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value /// tick The current tick of the pool, i.e. according to the last tick transition that was run. /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick /// boundary. /// observationIndex The index of the last oracle observation that was written, /// observationCardinality The current maximum number of observations stored in the pool, /// observationCardinalityNext The next maximum number of observations, to be updated when the observation. /// feeProtocol The protocol fee for both tokens of the pool. /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0 /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee. /// unlocked Whether the pool is currently locked to reentrancy function slot0() external view returns ( uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked ); /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool /// @dev This value can overflow the uint256 function feeGrowthGlobal0X128() external view returns (uint256); /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool /// @dev This value can overflow the uint256 function feeGrowthGlobal1X128() external view returns (uint256); /// @notice The amounts of token0 and token1 that are owed to the protocol /// @dev Protocol fees will never exceed uint128 max in either token function protocolFees() external view returns (uint128 token0, uint128 token1); /// @notice The currently in range liquidity available to the pool /// @dev This value has no relationship to the total liquidity across all ticks function liquidity() external view returns (uint128); /// @notice Look up information about a specific tick in the pool /// @param tick The tick to look up /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or /// tick upper, /// liquidityNet how much liquidity changes when the pool price crosses the tick, /// feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0, /// feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1, /// tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick /// secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick, /// secondsOutside the seconds spent on the other side of the tick from the current tick, /// initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false. /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0. /// In addition, these values are only relative and must be used only in comparison to previous snapshots for /// a specific position. function ticks( int24 tick ) external view returns ( uint128 liquidityGross, int128 liquidityNet, uint256 feeGrowthOutside0X128, uint256 feeGrowthOutside1X128, int56 tickCumulativeOutside, uint160 secondsPerLiquidityOutsideX128, uint32 secondsOutside, bool initialized ); /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information function tickBitmap(int16 wordPosition) external view returns (uint256); /// @notice Returns the information about a position by the position's key /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper /// @return _liquidity The amount of liquidity in the position, /// Returns feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke, /// Returns feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke, /// Returns tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke, /// Returns tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke function positions( bytes32 key ) external view returns ( uint128 _liquidity, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, uint128 tokensOwed0, uint128 tokensOwed1 ); /// @notice Returns data about a specific observation index /// @param index The element of the observations array to fetch /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time /// ago, rather than at a specific index in the array. /// @return blockTimestamp The timestamp of the observation, /// Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp, /// Returns secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp, /// Returns initialized whether the observation has been initialized and the values are safe to use function observations( uint256 index ) external view returns ( uint32 blockTimestamp, int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128, bool initialized ); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; /** * @title MintManager interface for onchain abridged mint vectors * @author highlight.xyz */ interface IAbridgedMintVector { /** * @notice On-chain mint vector (stored data) * @param contractAddress NFT smart contract address * @param startTimestamp When minting opens on vector * @param endTimestamp When minting ends on vector * @param paymentRecipient Payment recipient * @param maxTotalClaimableViaVector Max number of tokens that can be minted via vector * @param totalClaimedViaVector Total number of tokens minted via vector * @param currency Currency used for payment. Native gas token, if zero address * @param tokenLimitPerTx Max number of tokens that can be minted in one transaction * @param maxUserClaimableViaVector Max number of tokens that can be minted by user via vector * @param pricePerToken Price that has to be paid per minted token * @param editionId Edition ID, if vector is for edition based collection * @param editionBasedCollection If vector is for an edition based collection * @param requireDirectEOA Require minters to directly be EOAs * @param allowlistRoot Root of merkle tree with allowlist */ struct AbridgedVectorData { uint160 contractAddress; uint48 startTimestamp; uint48 endTimestamp; uint160 paymentRecipient; uint48 maxTotalClaimableViaVector; uint48 totalClaimedViaVector; uint160 currency; uint48 tokenLimitPerTx; uint48 maxUserClaimableViaVector; uint192 pricePerToken; uint48 editionId; bool editionBasedCollection; bool requireDirectEOA; bytes32 allowlistRoot; } /** * @notice On-chain mint vector (public) - See {AbridgedVectorData} */ struct AbridgedVector { address contractAddress; uint48 startTimestamp; uint48 endTimestamp; address paymentRecipient; uint48 maxTotalClaimableViaVector; uint48 totalClaimedViaVector; address currency; uint48 tokenLimitPerTx; uint48 maxUserClaimableViaVector; uint192 pricePerToken; uint48 editionId; bool editionBasedCollection; bool requireDirectEOA; bytes32 allowlistRoot; } /** * @notice Config defining what fields to update * @param updateStartTimestamp If 1, update startTimestamp * @param updateEndTimestamp If 1, update endTimestamp * @param updatePaymentRecipient If 1, update paymentRecipient * @param updateMaxTotalClaimableViaVector If 1, update maxTotalClaimableViaVector * @param updateTokenLimitPerTx If 1, update tokenLimitPerTx * @param updateMaxUserClaimableViaVector If 1, update maxUserClaimableViaVector * @param updatePricePerToken If 1, update pricePerToken * @param updateCurrency If 1, update currency * @param updateRequireDirectEOA If 1, update requireDirectEOA * @param updateMetadata If 1, update MintVector metadata */ struct UpdateAbridgedVectorConfig { uint16 updateStartTimestamp; uint16 updateEndTimestamp; uint16 updatePaymentRecipient; uint16 updateMaxTotalClaimableViaVector; uint16 updateTokenLimitPerTx; uint16 updateMaxUserClaimableViaVector; uint8 updatePricePerToken; uint8 updateCurrency; uint8 updateRequireDirectEOA; uint8 updateMetadata; } /** * @notice Creates on-chain vector * @param _vector Vector to create */ function createAbridgedVector(AbridgedVectorData memory _vector) external; /** * @notice Updates on-chain vector * @param vectorId ID of vector to update * @param _newVector New vector details * @param updateConfig Number encoding what fields to update * @param pause Pause / unpause vector * @param flexibleData Flexible data in vector metadata */ function updateAbridgedVector( uint256 vectorId, AbridgedVector calldata _newVector, UpdateAbridgedVectorConfig calldata updateConfig, bool pause, uint128 flexibleData ) external; /** * @notice Pauses or unpauses an on-chain mint vector * @param vectorId ID of abridged vector to pause * @param pause True to pause, False to unpause * @param flexibleData Flexible data that can be interpreted differently */ function setAbridgedVectorMetadata(uint256 vectorId, bool pause, uint128 flexibleData) external; /** * @notice Get on-chain abridged vector * @param vectorId ID of abridged vector to get */ function getAbridgedVector(uint256 vectorId) external view returns (AbridgedVector memory); /** * @notice Get on-chain abridged vector metadata * @param vectorId ID of abridged vector to get */ function getAbridgedVectorMetadata(uint256 vectorId) external view returns (bool, uint128); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; /** * @title MintManager interface for a mint fee oracle * @author highlight.xyz */ interface IMintFeeOracle { /** * @notice Process the mint fee for a classic mv * @param vectorId Vector ID * @param payoutCreatorReward Payout creator reward * @param vectorPaymentRecipient Vector payment recipient * @param currency Mint fee currency currency * @param amount Sale amount * @param minter Minter address * @param is1155 If collection contract is an 1155 */ function processClassicVectorMintFeeCap( bytes32 vectorId, bool payoutCreatorReward, address vectorPaymentRecipient, address currency, uint256 amount, address minter, bool is1155 ) external payable returns (uint256); /** * @notice Get the mint fee cap for a classic mv * @param vectorId Vector ID (bytes32) * @param numToMint Number of tokens to mint in this transaction * @param minter Minter address * @param currency Sale currency * @param collectionContract Collection NFT contract */ function getClassicVectorMintFeeCap( bytes32 vectorId, uint256 numToMint, address minter, address currency, address collectionContract ) external view returns (uint256, bool); /** * @notice Get the mint fee for a mechanic mint mv * @param vectorId Vector ID * @param numToMint Number of tokens to mint in this transaction * @param mechanic Address of mechanic facilitating mint * @param minter Address minting * @param collectionContract Collection NFT contract */ function getMechanicMintFee( bytes32 vectorId, uint32 numToMint, address mechanic, address minter, address collectionContract ) external view returns (uint256); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; interface IReferralManagerView { /** * @notice Get referrer for a tx */ function getCurrentReferrer(bytes32 vectorId) external view returns (address); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; interface IERC1155Standard { /** * @notice Return Highlight contract standard hash */ function highlightContractStandardHash() external view returns (bytes32); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; import "./IMechanicData.sol"; interface IMechanicMintManagerView is IMechanicData { /** * @notice Get a mechanic vector's metadata * @param mechanicVectorId Global mechanic vector ID */ function mechanicVectorMetadata(bytes32 mechanicVectorId) external view returns (MechanicVectorMetadata memory); /** * @notice Returns whether an address is a valid platform executor * @param _executor Address to be checked */ function isPlatformExecutor(address _executor) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822.sol"; import "../ERC1967/ERC1967Upgrade.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade { /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate the implementation's compatibility when performing an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. * * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function upgradeTo(address newImplementation) public virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. * * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; /** * @notice Defines a mechanic's metadata on the MintManager */ interface IMechanicData { /** * @notice A mechanic's metadata * @param contractAddress Collection contract address * @param editionId Edition ID if the collection is edition based * @param mechanic Address of mint mechanic contract * @param isEditionBased True if collection is edition based * @param isChoose True if collection uses a collector's choice mint paradigm * @param paused True if mechanic vector is paused */ struct MechanicVectorMetadata { address contractAddress; uint96 editionId; address mechanic; bool isEditionBased; bool isChoose; bool paused; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822Proxiable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) pragma solidity ^0.8.0; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeacon.sol"; import "../../interfaces/IERC1967.sol"; import "../../interfaces/draft-IERC1822.sol"; import "../../utils/Address.sol"; import "../../utils/StorageSlot.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ */ abstract contract ERC1967Upgrade is IERC1967 { // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { Address.functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlot.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlot.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( Address.isContract(IBeacon(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol) pragma solidity ^0.8.0; /** * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. * * _Available since v4.8.3._ */ interface IERC1967 { /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Emitted when the beacon is changed. */ event BeaconUpgraded(address indexed beacon); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } }
{ "optimizer": { "enabled": true, "mode": "z" }, "outputSelection": { "*": { "*": [ "abi" ] } }, "detectMissingLibraries": false, "forceEVMLA": false, "enableEraVMExtensions": false, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"EtherSendFailed","type":"error"},{"inputs":[],"name":"InvalidERC20","type":"error"},{"inputs":[],"name":"InvalidERC20Config","type":"error"},{"inputs":[],"name":"InvalidEtherMintFeeCap","type":"error"},{"inputs":[],"name":"InvalidReferrer","type":"error"},{"inputs":[],"name":"InvalidVectorType","type":"error"},{"inputs":[],"name":"NotMintManager","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"vectorId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"referrer","type":"address"},{"indexed":true,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"uint256","name":"referralPayout","type":"uint256"}],"name":"ReferralPayout","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"ETH_WEI","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FULL_MATH_SHIFT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc20","type":"address"}],"name":"delistERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"vectorId","type":"bytes32"},{"internalType":"uint256","name":"numToMint","type":"uint256"},{"internalType":"address","name":"minter","type":"address"},{"internalType":"address","name":"currency","type":"address"},{"internalType":"address","name":"collectionContract","type":"address"}],"name":"getClassicVectorMintFeeCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"vectorId","type":"bytes32"},{"internalType":"uint256","name":"numToMint","type":"uint256"},{"internalType":"address","name":"minter","type":"address"},{"internalType":"address","name":"currency","type":"address"},{"internalType":"address","name":"collectionContract","type":"address"}],"name":"getGatedVectorMintFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"mechanicVectorId","type":"bytes32"},{"internalType":"uint32","name":"numToMint","type":"uint32"},{"internalType":"address","name":"mechanic","type":"address"},{"internalType":"address","name":"minter","type":"address"},{"internalType":"address","name":"collectionContract","type":"address"}],"name":"getMechanicMintFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"vectorId","type":"bytes32"},{"internalType":"uint256","name":"numToMint","type":"uint256"},{"internalType":"address","name":"minter","type":"address"}],"name":"getMechanicVectorMintFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vectorId","type":"uint256"},{"internalType":"uint256","name":"numToMint","type":"uint256"},{"internalType":"address","name":"minter","type":"address"}],"name":"getPublicVectorMintFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"mintManager","type":"address"},{"internalType":"address","name":"platform","type":"address"},{"internalType":"address","name":"gaslessMechanic","type":"address"},{"internalType":"address","name":"backupReferralManager","type":"address"},{"internalType":"address","name":"backupDiscreteDutchAuctionMechanic","type":"address"},{"internalType":"address","name":"backupRankedAuctionMechanic","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"vectorId","type":"bytes32"},{"internalType":"bool","name":"payoutCreatorReward","type":"bool"},{"internalType":"address","name":"vectorPaymentRecipient","type":"address"},{"internalType":"address","name":"currency","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"minter","type":"address"},{"internalType":"bool","name":"is1155","type":"bool"}],"name":"processClassicVectorMintFeeCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc20","type":"address"},{"components":[{"internalType":"uint96","name":"baseMintFee","type":"uint96"},{"internalType":"address","name":"realTimeOracle","type":"address"}],"internalType":"struct MintFeeOracle.ERC20Config","name":"config","type":"tuple"}],"name":"setAllowlistedERC20Config","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newBackupDiscreteDutchAuctionMechanic","type":"address"}],"name":"setBackupDiscreteDutchAuctionMechanic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newBackupRankedAuctionMechanic","type":"address"}],"name":"setBackupRankedAuctionMechanic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newBackupReferralManager","type":"address"}],"name":"setBackupReferralManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"creatorRewardsEnabled","type":"bool"}],"name":"setCreatorRewardsEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newGaslessMechanic","type":"address"}],"name":"setGaslessMechanic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newMintManager","type":"address"}],"name":"setMintManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"vectorId","type":"bytes32"},{"internalType":"address","name":"minter","type":"address"}],"name":"subsidizeMintConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"vectorId","type":"bytes32"},{"internalType":"address","name":"minter","type":"address"}],"name":"unsubsidizeMintVector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"currency","type":"address"},{"internalType":"uint256","name":"amountToWithdraw","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"withdrawERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountToWithdraw","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"name":"withdrawNativeGasToken","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
9c4d535b0000000000000000000000000000000000000000000000000000000000000000010003a7db7f7a998e96e20a19267aa044c91feedb25d92cbf1eded87db391fd00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x0003000000000002000d000000000002000000000301034f0000006001100270000002fd011001970002000000130355000100000003035500000001002001900000000002000416000000010b000039000000550000c13d0000008004000039000000400040043f000000040010008c000003ee0000413d000000000403043b000000e009400270000002ff0090009c000000620000613d000003000090009c000000660000613d000003010090009c00000004043003700000006a0000613d000003020090009c0000002405300370000000ab0000613d000003030090009c000001430000613d000003040090009c00000044063003700000014f0000613d000003050090009c0000018c0000613d000003060090009c0000019d0000613d000003070090009c000001a70000613d000003080090009c000001ae0000613d000003090090009c00000064083003700000008407300370000000a40a300370000000650c000039000001c00000613d0000030a0090009c000002130000613d0000030b0090009c0000022d0000613d0000030c0090009c000002570000613d0000030d0090009c000002620000613d0000030e0090009c0000026d0000613d0000030f0090009c000002760000613d000003100090009c000002970000613d000003110090009c000002c10000613d000003120090009c000002d00000613d000003130090009c000002e80000613d000003140090009c000002f40000613d000003150090009c0000030e0000613d000003160090009c0000037b0000613d000003170090009c000003cd0000613d000003180090009c000003e70000613d000003190090009c000003ee0000c13d000000000002004b000003ee0000c13d000100520000003d00000b860000013d0000031b0110019700000067020000390000025d0000013d000000a001000039000000400010043f000000000002004b000003ee0000c13d0000000001000410000000800010043f00000140000004430000016000100443000000200100003900000100001004430000012000b00443000002fe0100004100000bf10001042e000000000002004b000003ee0000c13d0000031a01000041000002720000013d000000000002004b000003ee0000c13d0000036701000041000002720000013d000000240010008c000003ee0000413d000000000002004b000003ee0000c13d000000000104043b000a00000001001d0000031b0010009c000003ee0000213d000100740000003d00000b760000013d0000035c020000410bf00b200000040f0009031b0010019b0000000001000410000000090010006c0000000001000039000000010100c0390bf007ad0000040f0000035f01000041000000000101041a0000031b01100197000000090010006c000000000100003900000001010060390bf007bc0000040f0bf0077f0000040f000000400400043d000003660040009c000005de0000813d0000002002400039000000400020043f00000000000404350000036001000041000000000101041a000000ff00100190000004d50000c13d000700000002001d000000400500043d0000036101000041000000000015043500000000010004140000000a02000029000000040020008c000004f70000613d000900000004001d000000040400003900000020060000390000000a020000290000000003050019000800000005001d00000008050000290bf007280000040f00000008050000290000000904000029000000000001004b000004f70000c13d000000400200043d000a00000002001d0000032401000041000000000012043500000004012000390bf007da0000040f0000000a030000290000000002310049000004510000013d000000440010008c000003ee0000413d000000000204043b000a00000002001d0000031b0020009c000003ee0000213d000000000405043b0000031d0040009c000003ee0000213d0000002302400039000000000012004b000003ee0000813d0000000405400039000000000253034f000000000202043b0000031d0020009c000005de0000213d0000001f06200039000000200700008a000000000676016f0000003f06600039000000000676016f000003260060009c000005de0000213d0000008006600039000000400060043f000000800020043f00000000042400190000002404400039000000000014004b000003ee0000213d0000002001500039000000000313034f000000200100008a00000000041201700000001f0520018f000000a001400039000000d70000613d000000a006000039000000000703034f000000007807043c0000000006860436000000000016004b000000d30000c13d000000000005004b000000df0000613d000000000343034f00000003045002100000000005010433000100de0000003d00000be80000013d0000000000310435000000a0012000390000000000010435000100e30000003d00000b760000013d0000035c020000410bf00b200000040f0009031b0010019b0000000001000410000000090010006c0000000001000039000000010100c0390bf007ad0000040f0000035f01000041000000000101041a0000031b01100197000000090010006c000000000100003900000001010060390bf007bc0000040f0bf0077f0000040f0000036001000041000000000101041a000000ff00100190000004d50000c13d000000400200043d0000036101000041000900000002001d000000000012043500000000010004140000000a02000029000000040020008c000001070000613d000000040400003900000020060000390000000a02000029000000090300002900000000050300190bf007280000040f000000000001004b000000a20000613d00000000010000310000001f02100039000000200300008a000000000332016f00000009040000290000000902300029000000000032004b000000000300003900000001030040390000031d0020009c000005de0000213d0000000100300190000005de0000c13d000000400020043f0000031e0010009c000003ee0000213d000000200010008c000003ee0000413d00000000010404330000035f0010009c0001011d0000003d00000bc40000013d000002fd0010009c000900000001001d000002fd0100804100000040011002100000000002000414000002fd0020009c000002fd02008041000000c002200210000000000112019f00000333011001c70000800d02000039000000020300003900000362040000410000000a050000290bf00b3e0000040f0000000100200190000003ee0000613d0000000901000029000003630010009c000005de0000213d00000009030000290000006001300039000000400010043f00000040013000390000036402000041000000000021043500000020013000390000036502000041000000000021043500000027010000390000000000130435000000800400043d00000000010004140000000a02000029000000040020008c000006670000c13d00000001010000390000066a0000013d000000000002004b000003ee0000c13d000101470000003d00000b760000013d0000035c020000410bf00b200000040f0000031b011001970000000002000410000000000012004b000003ef0000c13d0000035f01000041000002720000013d000000640010008c000003ee0000413d000000000002004b000003ee0000c13d000000000104043b000a00000001001d0000031b0010009c000003ee0000213d000000000106043b000900000001001d0000031b0010009c000003ee0000213d000000000105043b000800000001001d0bf0077f0000040f000000400500043d0000002401500039000000080200002900000000002104350000035501000041000000000015043500000004015000390000000902000029000000000021043500000000010004140000000a02000029000000040020008c000001740000613d000000440400003900000020060000390000000003050019000a00000005001d0000000a050000290bf007040000040f0000000a05000029000000000001004b0000041d0000613d00000000020000310000001f01200039000000200300008a000000000331016f0000000001530019000000000031004b000000000300003900000001030040390000031d0010009c000005de0000213d0000000100300190000005de0000c13d000000400010043f0000031e0020009c000003ee0000213d000000200020008c000003ee0000413d0000000002050433000000000002004b0000000003000039000000010300c039000000000032004b000002f10000613d000003ee0000013d000000440010008c000003ee0000413d000000000002004b000003ee0000c13d000000000105043b000a00000001001d0000031b0010009c000003ee0000213d000101960000003d00000b660000013d0000042d0000c13d00000044013000390000035b020000410000000000210435000000240130003900000016020000390000044a0000013d000000000002004b000003ee0000c13d000101a10000003d00000b860000013d00000008011002100000032f011001970000006903000039000000000203041a00000330022001970000026a0000013d000000000002004b000003ee0000c13d000101ab0000003d00000b860000013d0000031b011001970000006a020000390000025d0000013d000000240010008c000003ee0000413d000000000002004b000003ee0000c13d000000000204043b000000000002004b0000000001000039000000010100c039000a00000002001d000000000012004b000003ee0000c13d0bf0077f0000040f0000006903000039000000000103041a000001000200008a000000000121016f0000000a011001af0000026b0000013d000000e40010008c000003ee0000413d000000000104043b000900000001001d000000000405043b000000000004004b0000000001000039000000010100c039000a00000004001d000000000014004b000003ee0000c13d000000000106043b000800000001001d0000031b0010009c000003ee0000213d000000000108043b000700000001001d0000031b0010009c000003ee0000213d000000000107043b000600000001001d00000000010a043b000500000001001d0000031b0010009c000003ee0000213d000000c401300370000000000301043b000000000003004b0000000001000039000000010100c039000400000003001d000000000013004b000003ee0000c13d000000000100041100000000030c041a0000031b03300197000000000031004b000005620000c13d000000070000006b000001ea0000c13d000000060020006c0000058a0000c13d0000800b01000039000000040300003900000000040004150000000d0440008a00000005044002100000033c020000410bf00b200000040f000000010010008c000005a10000613d0000000a0010008c000005a30000613d000000890010008c000005a50000613d000001440010008c000005a70000613d000001680010008c000005a90000613d00000ab50010008c000005ab0000613d000013880010008c000005ad0000613d00001d880010008c000005af0000613d0000033e0010009c000005b10000613d0000a4b10010008c000005b30000613d0000033f0010009c000005b50000613d000003400010009c000005b70000613d000003410010009c000005b90000613d000003420010009c000005bb0000613d000003430010009c000005bd0000613d000021050010008c000005bf0000c13d0000035201000041000005c30000013d000000000002004b000003ee0000c13d0bf0077f0000040f0000003301000039000000000201041a0000032e03200197000000000031041b000000400100043d000002fd0010009c000002fd0100804100000040011002100000000003000414000002fd0030009c000002fd03008041000000c003300210000000000113019f0000031b0520019700000333011001c70000800d020000390000000303000039000003390400004100000000060000190bf00b3e0000040f0000000100200190000002f00000c13d000003ee0000013d000000000002004b000003ee0000c13d0bf007680000040f000900000001001d000600000002001d000800000003001d000700000004001d00000000010500190bf00a1e0000040f000a00000001001d000000090100002900000008020000290001023b0000003d00000b5c0000013d0000000a0100002900000000020000190000024e0000c13d00000007010000290000031b01100198000004320000c13d0000000a010000290bf009e20000040f000000000001004b000000000200001900000006030000290000024c0000613d000000010200008a00000000021200d9000000000032004b00000000020100190000030a0000413d00000000023200a90000000a01000029000000000001004b0000000003000039000000010300c039000000400100043d0000002004100039000000000034043500000000002104350000004002000039000002f20000013d000000000002004b000003ee0000c13d0001025b0000003d00000b860000013d0000031b011001970000006b02000039000000000302041a0000032e03300197000000000113019f000000000012041b000002f00000013d000000000002004b000003ee0000c13d000102660000003d00000b860000013d0000031b011001970000006503000039000000000203041a0000032e02200197000000000112019f000000000013041b000002f00000013d000000000002004b000003ee0000c13d0000003301000039000000000101041a0000031b01100197000000800010043f00000080010000390000002002000039000002f20000013d000000640010008c000003ee0000413d000000000002004b000003ee0000c13d000000000104043b000a00000001001d0000031b0010009c000003ee0000213d0bf0077f0000040f00000001010003670000002402100370000000000202043b000900000002001d000003280020009c000003ee0000213d0000004401100370000000000201043b000000090000006b000004d80000c13d0000031b0020009c000003ee0000213d0000000001020019000000000002004b000004dd0000613d000800000001001d0000000a01000029000102920000003d00000b7f0000013d0000000802000029000000600220021000000009022001af000000000021041b000002f00000013d000000a40010008c000003ee0000413d000000000002004b000003ee0000c13d000000000105043b000a00000001001d000002fd0010009c000003ee0000213d000000000104043b000900000001001d000000000106043b0000031b0010009c000003ee0000213d000000000208043b000800000002001d0000031b0020009c000003ee0000213d000000000207043b000700000002001d0000031b0020009c000003ee0000213d0bf009320000040f000000000001004b0000000002000019000002be0000c13d00000009010000290000000802000029000102b40000003d00000ba80000013d000002be0000c13d00000007010000290bf009ce0000040f000000000001004b000002bd0000613d000000010200008a00000000021200d90000000a0020006c0000030a0000413d0000000a021000b9000000400100043d0000000000210435000002740000013d000000440010008c000003ee0000413d000000000002004b000003ee0000c13d000000000105043b000a00000001001d0000031b0010009c000003ee0000213d000102cb0000003d00000b660000013d000004450000c13d000001000400008a000000000242016f00000001022001bf0000042f0000013d000000440010008c000003ee0000413d000000000002004b000003ee0000c13d000000000105043b000a00000001001d0000031b0010009c000003ee0000213d00090000000b001d000000000104043b000800000001001d0bf0077f0000040f000000400300043d00000000010004140000000a04000029000000040040008c000004f00000613d0000000805000029000000000005004b000004df0000c13d0000000002040019000102e70000003d00000be30000013d000004ef0000013d000000000002004b000003ee0000c13d000102ec0000003d00000b860000013d0000031b01100197000102ef0000003d00000b7f0000013d000000000001041b000000400100043d000000000200001900000000030000190bf00b020000040f000000000002004b000003ee0000c13d0bf007680000040f000900000002001d0000000002030019000a00000004001d000800000005001d000102fd0000003d00000b5c0000013d000003fc0000c13d0000000a010000290000031b00100198000004530000c13d00000008010000290bf009ce0000040f000000000001004b00000009030000290000045a0000613d000000010200008a00000000021200d9000000000032004b0000045a0000813d0000035901000041000000000010043f0000001101000039000005e10000013d000000c40010008c000003ee0000413d000000000002004b000003ee0000c13d000000000104043b000a00000001001d0000031b0010009c000003ee0000213d000000000105043b000900000001001d0000031b0010009c000003ee0000213d000000000106043b000800000001001d0000031b0010009c000003ee0000213d000000000108043b000700000001001d0000031b0010009c000003ee0000213d000000000107043b000600000001001d0000031b0010009c000003ee0000213d00000000010a043b000500000001001d0000031b0010009c000003ee0000213d0000000001000415000400000001001d000000000300041a0000ffff003001900000033f0000613d0000000001000410000b00000001001d0000800201000039000300000003001d000000240300003900000000040004150000000b0440008a00000005044002100000032b020000410bf00b200000040f0000000303000029000000ff0230018f000000010020008c0000058c0000c13d000000000001004b0000058c0000c13d0000ff0000300190000001000100008a000000000113016f00000001011001bf000000000010041b000005640000c13d0000ffff0200008a000000000121016f00000100011001bf000000000010041b0001034b0000003d00000bcb0000013d0000032e011001970000000a011001af000000000012041b0000006701000039000000000201041a0000032e0220019700000008022001af000000000021041b000000070100002900000008011002100000032f011001970000006903000039000000000203041a0000033002200197000000000112019f000000000013041b0000006a01000039000000000201041a0000032e0220019700000006022001af000000000021041b0000006b01000039000000000201041a0000032e0220019700000005022001af000000000021041b0000ff010100008a000000000200041a000000000112016f000000000010041b000000400100043d00000001030000390000000000310435000002fd0010009c000002fd0100804100000040011002100000000002000414000002fd0020009c000002fd02008041000000c002200210000000000112019f00000331011001c70000800d0200003900000332040000410bf00b3e0000040f0000000100200190000003ee0000613d000005860000013d000000640010008c000003ee0000413d000000000002004b000003ee0000c13d000000000106043b000a00000001001d0000031b0010009c000003ee0000213d000000000105043b000800000001001d00000000020c041a000000000304043b0000032501000041000000800010043f000900000003001d000000840030043f00000000010004140000031b02200197000000040020008c000003960000613d00000024040000390000008003000039000000c00600003900000000050300190bf007280000040f000000000001004b0000041d0000613d00000000010000310000001f02100039000000200300008a000000000232016f000003260020009c000005de0000213d0000008003200039000700000003001d000000400030043f0000031e0010009c000003ee0000213d000000c00010008c000003ee0000413d0000000701000029000003270010009c000005de0000213d0000014001200039000000400010043f000000800300043d0000031b0030009c000003ee0000213d00000007010000290000000000310435000000a00100043d000003280010009c000003ee0000213d000000a0042000390000000000140435000000c00100043d0000031b0010009c000003ee0000213d000000c0042000390000000000140435000000e00400043d000103ba0000003d00000ba30000013d000003ee0000c13d000000e0052000390000000000450435000001000400043d000103c00000003d00000ba30000013d000003ee0000c13d00000100052000390000000000450435000001200400043d000103c60000003d00000ba30000013d000003ee0000c13d00000120022000390000000000420435000000000003004b0000064f0000c13d0000032901000041000004f40000013d000000240010008c000003ee0000413d000000000002004b000003ee0000c13d000000000104043b000a00000001001d0000031b0010009c000003ee0000213d0bf0077f0000040f0000000a01000029000000000001004b000004580000c13d000000400100043d0000006402100039000003220300004100000000003204350000004402100039000003230300004100000000003204350000002402100039000000260300003900000000003204350000032402000041000103e60000003d00000bd20000013d000003fa0000013d000000640010008c000003ee0000413d000000000002004b000003ee0000c13d000000000206043b0000031b0020009c000003fe0000a13d00000bda0000013d0000032401000041000000800010043f0000002001000039000000840010043f0000003801000039000000a40010043f0000035d01000041000000c40010043f0000035e01000041000000e40010043f000000800100003900000084020000390bf00afa0000040f0000000001000019000004560000013d000000000105043b000900000001001d000000000104043b000a00000001001d000104040000003d00000b5c0000013d000000000100001900000000020000190000045d0000c13d0000006501000039000000000201041a000000400500043d0000031c010000410000000001150436000800000001001d00000004015000390000000a03000029000000000031043500000000010004140000031b02200197000000040020008c000004640000613d0000002404000039000001c0060000390000000003050019000a00000005001d0000000a050000290bf007280000040f0000000a05000029000000000001004b000004640000c13d00000002040003670000000002000031000104210000003d00000bba0000013d000004280000613d000000000704034f0000000008010019000000007907043c0000000008980436000000000038004b000004240000c13d000000000006004b0000042c0000613d0001042c0000003d00000b8b0000013d0bf00afa0000040f000001000400008a000000000242016f000000000021041b0000000001030019000002f10000013d000104340000003d00000b7f0000013d000000400300043d000003360030009c000005de0000213d0000004002300039000000400020043f000000000101041a000000200430003900000060021002700000000000240435000003280410019800000000004304350000000a03000029000005320000c13d000003280010009c000005370000213d0000033801000041000004f40000013d00000044013000390000033402000041000000000021043500000024013000390000001202000039000000000021043500000324010000410000000000130435000000040130003900000020020000390000000000210435000000640200003900000000010300190bf00afa0000040f000000090200002900000008030000290bf008bc0000040f0000000a020000290000045c0000013d0bf007930000040f000002f00000013d00000000013100a900000000020000190000031b02200197000000400300043d00000020043000390000000000240435000000000013043500000040020000390000000001030019000002f20000013d000104660000003d00000b530000013d0000031d0020009c000005de0000213d0000000100300190000005de0000c13d000000400020043f0000031e0010009c000003ee0000213d000001c00010008c000003ee0000413d0000031f0020009c000005de0000213d0000000006050019000001c001200039000000400010043f00000000030504330000031b0030009c000003ee0000213d000000000132043600000008040000290000000004040433000003200040009c000003ee0000213d000000000041043500000040016000390000000001010433000003200010009c000003ee0000213d00000040042000390000000000140435000000600160003900000000010104330000031b0010009c000003ee0000213d0000006004200039000000000014043500000080016000390000000001010433000003200010009c000003ee0000213d00000080042000390000000000140435000000a0016000390000000001010433000003200010009c000003ee0000213d000000a0042000390000000000140435000000c00160003900000000010104330000031b0010009c000003ee0000213d000000c004200039000a00000004001d0000000000140435000000e0046000390000000004040433000003200040009c000003ee0000213d000000e005200039000000000045043500000100046000390000000004040433000003200040009c000003ee0000213d0000010005200039000000000045043500000120046000390000000004040433000003210040009c000003ee0000213d0000012005200039000000000045043500000140046000390000000004040433000003200040009c000003ee0000213d0000014005200039000000000045043500000160046000390000000004040433000104b80000003d00000ba30000013d000003ee0000c13d0000016005200039000000000045043500000180046000390000000004040433000104bf0000003d00000ba30000013d000003ee0000c13d00000180052000390000000000450435000001a002200039000001a00460003900000000040404330000000000420435000000000003004b000003cb0000613d000000000001004b000006ff0000c13d00000000010300190bf009ce0000040f000000000001004b000004d20000613d000000010200008a00000000021200d9000000090020006c0000030a0000413d00000009011000b900000000020000190000045d0000013d0000000a010000290bf007e70000040f000002f00000013d0000031b0020009c000003ee0000213d000000000002004b00000000010000190000028e0000613d0000033501000041000004f40000013d000002fd0030009c000002fd030080410000004002300210000002fd0010009c000002fd01008041000000c001100210000000000121019f00000333011001c70000800902000039000000000305001900000000050000190bf00b3e0000040f0000006003100270000002fd0030019d0002000000010355000000010120018f000900000001001d0bf008030000040f000000090000006b000002f00000c13d0000035801000041000000000010043f0000032a0100004100000bf200010430000104f90000003d00000b530000013d0000031d0020009c000005de0000213d0000000100300190000005de0000c13d000900000004001d000000400020043f0000031e0010009c000003ee0000213d000000200010008c000003ee0000413d00000000010504330000035f0010009c000105070000003d00000bc40000013d000002fd0010009c000800000001001d000002fd0100804100000040011002100000000002000414000002fd0020009c000002fd02008041000000c002200210000000000112019f00000333011001c70000800d02000039000000020300003900000362040000410000000a050000290bf00b3e0000040f0000000100200190000003ee0000613d00000009010000290000000001010433000000000001004b000002f00000613d0000000801000029000003630010009c0000000903000029000005de0000213d00000008040000290000006001400039000000400010043f00000040014000390000036402000041000000000021043500000020014000390000036502000041000000000021043500000027010000390000000000140435000000000403043300000000010004140000000a02000029000000040020008c000005960000c13d0000000101000039000005990000013d000000000003004b0000000001000039000000010100c0390000000001140231000002440000013d000000400500043d000003370100004100000000001504350000000001000414000000040020008c000005460000613d0000000404000039000000e0060000390000000003050019000900000005001d00000009050000290bf007280000040f0000000905000029000000000001004b0000041d0000613d000105480000003d00000b530000013d0000031d0020009c000005de0000213d0000000100300190000005de0000c13d000000400020043f000000000251001900000000010500190bf008920000040f000900000001001d0000000a010000290bf009e20000040f000800000001001d00000009010000290bf009f50000040f0000000804000029000000000004004b00000006030000290000055e0000613d000000010200008a00000000024200d9000000000012004b0000030a0000413d00000000014100aa0000000002000019000002470000c13d0000024c0000013d0000033a01000041000004f40000013d0000000801300270000000ff0110018f000300000001001d0bf0086e0000040f00000003010000290bf0086e0000040f0001056c0000003d00000bcb0000013d0000032e011001970000000a011001af000000000012041b0000006701000039000000000201041a0000032e0220019700000008022001af000000000021041b000000070100002900000008011002100000032f011001970000006903000039000000000203041a0000033002200197000000000112019f000000000013041b0000006a01000039000000000201041a0000032e0220019700000006022001af000000000021041b0000006b01000039000000000201041a0000032e0220019700000005022001af000000000021041b000000000100041500000004011000690000000001000002000002f00000013d0000033b01000041000004f40000013d000000400100043d00000064021000390000032c03000041000000000032043500000044021000390000032d03000041000000000032043500000024021000390000002e03000039000003e20000013d0000000a0200002900000007030000290bf0074c0000040f000900000001001d0bf008030000040f00000000030100190000000a01000029000000090200002900000008040000290bf008330000040f000002f00000013d0000033d01000041000005c30000013d0000035101000041000005c30000013d0000034e01000041000005c30000013d0000034801000041000005c30000013d0000034701000041000005c30000013d0000034401000041000005c30000013d0000034a01000041000005c30000013d0000034601000041000005c30000013d0000034c01000041000005c30000013d0000034f01000041000005c30000013d0000034d01000041000005c30000013d0000034901000041000005c30000013d0000034501000041000005c30000013d0000034b01000041000005c30000013d0000035001000041000005c30000013d0000006901000039000000000101041a00000008011002700000031b01100197000000050010006c000005f10000c13d0000000601000029000003530010009c0000030a0000813d0000035401000041000000800010043f0000000901000029000000840010043f00000000010004140000000502000029000000040020008c000005d80000613d000000240400003900000080030000390000002006000039000000050200002900000000050300190bf007280000040f000000000001004b0000041d0000613d00000000020000310000001f01200039000000200300008a000000000331016f000003260030009c000005e40000a13d0000035901000041000000000010043f0000004101000039000000040010043f0000035a0100004100000bf2000104300000008001300039000500000001001d000000400010043f0000031e0020009c000003ee0000213d000000200020008c000003ee0000413d000000800100043d000300000001001d0000031b0010009c000003ee0000213d000000030000006b000006880000c13d0000000a0000006b000a00000000001d000005f70000c13d000000400100043d0000000a02000029000002bf0000013d000000040000006b000005fc0000c13d00000006010000290000000101100270000006020000013d0000000601000029000003570010009c0000030a0000213d000000060100002900000003011002100000000a0110011a000a00000001001d000000400100043d000900000001001d000000070000006b0000060d0000c13d00000000010004140000000802000029000000040020008c0000061c0000c13d0000000101000039000006830000013d000000090300002900000024013000390000000a0200002900000000002104350000035501000041000000000013043500000004013000390000000802000029000000000021043500000000010004140000000702000029000000040020008c000006230000c13d0000000002000031000006370000013d0000000a0000006b000006710000c13d00000008020000290000000903000029000106220000003d00000be30000013d000006830000013d000000440400003900000020060000390000000702000029000000090300002900000000050300190bf007040000040f0000000002000031000000000001004b000006370000c13d00000002040003670001062f0000003d00000bba0000013d000004280000613d000000000704034f0000000008010019000000007907043c0000000008980436000000000038004b000006320000c13d000004280000013d0000001f01200039000000200300008a000000000331016f0000000901300029000000000031004b000000000300003900000001030040390000031d0010009c000005de0000213d0000000100300190000005de0000c13d000000400010043f0000031e0020009c000003ee0000213d000000200020008c000003ee0000413d00000009010000290000000001010433000000000001004b0000000002000039000000010200c039000000000021004b000003ee0000c13d000005f40000013d0bf009320000040f000000000001004b0000000002000019000006630000c13d00000009010000290000000a02000029000106570000003d00000ba80000013d000006630000c13d000000070100002900000000010104330000031b011001970bf009ce0000040f000000000001004b000006620000613d000000010200008a00000000021200d9000000080020006c0000030a0000413d00000008021000b9000000400100043d00000000022104360000000000020435000002550000013d000000a0030000390000000a020000290bf0074c0000040f000800000001001d0bf008030000040f00000000030100190000000a01000029000000080200002900000009040000290000059f0000013d0000000902000029000002fd0020009c000002fd020080410000004002200210000002fd0010009c000002fd01008041000000c001100210000000000121019f00000333011001c700008009020000390000000a03000029000000080400002900000000050000190bf00b3e0000040f0000006003100270000002fd0030019d0002000000010355000000010120018f000900000001001d0bf008030000040f000000090000006b000004f30000613d000005f40000013d00000006010000290002000a00100122000000070000006b000006920000c13d00000000010004140000000302000029000000040020008c000006b30000c13d0000000101000039000006e50000013d000003550100004100000005040000290000000000140435000000a4013000390000000204000029000000000041043500000084013000390000000304000029000000000041043500000000010004140000000704000029000000040040008c000006be0000613d000000440400003900000020060000390000000702000029000000050300002900000000050300190bf007040000040f0000000002000031000000000001004b000006bb0000c13d0000000204000367000106ab0000003d00000bba0000013d000004280000613d000000000704034f0000000008010019000000007907043c0000000008980436000000000038004b000006ae0000c13d000004280000013d00000006020000290000000a0020008c000006d30000813d00000003020000290000000503000029000106ba0000003d00000be30000013d000006e50000013d0000001f01200039000000200300008a000000000331016f0000000501300029000000000031004b000000000300003900000001030040390000031d0010009c000005de0000213d0000000100300190000005de0000c13d000000400010043f0000031e0020009c000003ee0000213d000000200020008c000003ee0000413d00000005020000290000000002020433000000000002004b0000000003000039000000010300c039000000000032004b000003ee0000c13d000006ea0000013d0000000502000029000002fd0020009c000002fd020080410000004002200210000002fd0010009c000002fd01008041000000c001100210000000000121019f00000333011001c700008009020000390000000203000029000000030400002900000000050000190bf00b3e0000040f0000006003100270000002fd0030019d0002000000010355000000010120018f000500000001001d0bf008030000040f000000050000006b000004f30000613d000000400100043d00000002020000290000000000210435000002fd0010009c000002fd0100804100000040011002100000000002000414000002fd0020009c000002fd02008041000000c002200210000000000112019f00000331011001c70000800d02000039000000040300003900000356040000410000000905000029000000030600002900000007070000290bf00b3e0000040f0000000100200190000003ee0000613d000005f10000013d00000009020000290bf008bc0000040f0000000a0200002900000000020204330000045c0000013d0003000000000002000300000006001d000200000005001d000002fd0030009c000002fd030080410000004003300210000002fd0040009c000002fd040080410000006004400210000000000334019f000002fd0010009c000002fd01008041000000c001100210000000000113019f0bf00b3e0000040f00000002090000290000006003100270000002fd03300197000000030030006c000000030400002900000000040340190000001f0540018f00000368064001980000000004690019000007220000613d000000000701034f000000007807043c0000000009890436000000000049004b0000071e0000c13d000000010220018f000000000005004b000007270000613d000107270000003d00000b970000013d00000bc00000013d0003000000000002000300000006001d000200000005001d000002fd0030009c000002fd030080410000004003300210000002fd0040009c000002fd040080410000006004400210000000000334019f000002fd0010009c000002fd01008041000000c001100210000000000113019f0bf00b430000040f00000002090000290000006003100270000002fd03300197000000030030006c000000030400002900000000040340190000001f0540018f00000368064001980000000004690019000007460000613d000000000701034f000000007807043c0000000009890436000000000049004b000007420000c13d000000010220018f000000000005004b0000074b0000613d0001074b0000003d00000b970000013d00000bc00000013d000002fd0030009c000002fd030080410000004003300210000002fd0040009c000002fd040080410000006004400210000000000334019f000002fd0010009c000002fd01008041000000c001100210000000000113019f0bf00b480000040f0000006003100270000002fd0030019d0002000000010355000000010120018f000000000001042d0000031e0010009c000007670000213d000000230010008c000007670000a13d00000004010000390000000101100367000000000101043b0000031b0010009c000007670000213d000000000001042d00000bda0000013d0000031e0010009c0000077e0000213d000000a30010008c0000077e0000a13d00000001050003670000002401500370000000000201043b0000000401500370000000000101043b0000004403500370000000000303043b0000031b0030009c0000077e0000213d0000006404500370000000000404043b0000031b0040009c0000077e0000213d0000008405500370000000000505043b0000031b0050009c0000077e0000213d000000000001042d00000bda0000013d0000003301000039000000000101041a0000031b011001970000000002000411000000000021004b000007860000c13d000000000001042d000000400100043d000000440210003900000369030000410000000000320435000003240200004100000000002104350000002402100039000000200300003900000000003204350000000402100039000000000032043500000064020000390bf00afa0000040f00000000060100190000031b011001970000003302000039000000000302041a0000032e04300197000000000114019f000000000012041b000000400100043d000002fd0010009c000002fd0100804100000040011002100000000002000414000002fd0020009c000002fd02008041000000c002200210000000000112019f0000031b0530019700000333011001c70000800d02000039000000030300003900000339040000410bf00b3e0000040f0000000100200190000007ac0000613d000000000001042d00000bda0000013d000000000001004b000007b00000613d000000000001042d000000400100043d00000064021000390000036a03000041000000000032043500000044021000390000036b03000041000000000032043500000024021000390000002c030000390000000000320435000003240200004100000b4d0000013d000000000001004b000007bf0000613d000000000001042d000000400100043d00000064021000390000036c03000041000000000032043500000044021000390000036b03000041000000000032043500000024021000390000002c030000390000000000320435000003240200004100000b4d0000013d000000000001004b000007ce0000613d000000000001042d000000400100043d00000064021000390000036d03000041000000000032043500000044021000390000036e030000410000000000320435000000240210003900000029030000390000000000320435000003240200004100000b4d0000013d00000060021000390000036f03000041000000000032043500000040021000390000037003000041000000000032043500000020021000390000002e030000390000000000320435000000200200003900000000002104350000008001100039000000000001042d0003000000000002000200000001001d000107eb0000003d00000bdc0000013d0000032b020000410bf00b200000040f000000000001004b000007f70000613d00000002010000290000031b011001970000035f02000041000000000302041a0000032e03300197000000000113019f000000000012041b000000000001042d000000400100043d00000064021000390000037103000041000000000032043500000044021000390000037203000041000000000032043500000024021000390000002d030000390000000000320435000003240200004100000b4d0000013d000100000000000200000000020000320000082b0000613d000003730020009c0000082d0000813d0000001f01200039000000200300008a000000000131016f0000003f01100039000000000431016f000000400100043d0000000004410019000000000014004b000000000500003900000001050040390000031d0040009c0000082d0000213d00000001005001900000082d0000c13d000000400040043f000000000621043600000000033201700000001f0420018f00000000023600190000000205000367000008220000613d000000000705034f000000007807043c0000000006860436000000000026004b0000081e0000c13d000000000004004b0000082c0000613d000000000335034f00000003044002100000000005020433000108290000003d00000be80000013d0000000000320435000000000001042d0000006001000039000000000001042d0000035901000041000000000010043f0000004101000039000000040010043f0000035a0100004100000bf2000104300003000000000002000000000603001900000000050200190000000032030434000000000005004b000008450000613d000000000002004b000008430000c13d0001083d0000003d00000bdc0000013d0000032b02000041000200000006001d0bf00b200000040f0000000206000029000000000001004b000008620000613d0000000001060019000000000001042d000000000002004b000008580000c13d000000400100043d00000324020000410001084b0000003d00000bd20000013d00000024031000390000000042040434000000000023043500000044031000390000000005000019000000000025004b0000085a0000813d00000000065300190000000007540019000000000707043300000000007604350000002005500039000008500000013d00000000010300190bf00afa0000040f0000085d0000a13d000000000323001900000000000304350000001f02200039000000200300008a000000000232016f00000044022000390bf00afa0000040f000000400100043d00000044021000390000037403000041000000000032043500000024021000390000001d03000039000000000032043500000324020000410001086c0000003d00000bd20000013d00000064020000390bf00afa0000040f000000000001004b000008710000613d000000000001042d000000400100043d00000064021000390000037503000041000000000032043500000044021000390000037603000041000000000032043500000024021000390000002b030000390000000000320435000003240200004100000b4d0000013d00000000030100190000006001200210000000400200043d00000040042000390000000000140435000000340100003900000000011204360000000000310435000003770020009c0000088c0000813d0000006003200039000000400030043f00000000020204330bf00b0c0000040f000000000001042d0000035901000041000000000010043f0000004101000039000000040010043f0000035a0100004100000bf20001043000000000021200490000031e0020009c000008bb0000213d000000df0020008c000008bb0000a13d00000000320104340000031b0020009c000008bb0000213d00000000030304330000037800300198000003790400004100000000040060190000037a05300197000000000454019f000000000043004b000008bb0000c13d000000400310003900000000030304330000ffff0030008c000008bb0000213d000000600310003900000000030304330000ffff0030008c000008bb0000213d000000800310003900000000030304330000ffff0030008c000008bb0000213d000000a0031000390000000003030433000000ff0030008c000008bb0000213d000000c0011000390000000001010433000000000001004b0000000003000039000000010300c039000000000031004b000008bb0000c13d0000000001020019000000000001042d00000bda0000013d0005000000000002000500000003001d000400000002001d0000031b01100197000108c20000003d00000b7f0000013d000000400200043d0000037b0020009c000009110000813d0000000004020019000300000002001d0000004002200039000000400020043f000000000101041a00000020034000390000006002100270000200000003001d00000000002304350000032801100197000000000014043500000005010000290bf00a1e0000040f000000030200002900000000020204330000032802200198000008e10000613d000000000001004b0000000001000039000000010100c039000000000112023100000004030000290000090e0000613d000000010200008a00000000021200d9000000000032004b0000090f0000813d000009150000013d000000020100002900000000010104330000031b021001980000091b0000613d000000400500043d000003370100004100000000001504350000000001000414000000040020008c000008f40000613d0000000404000039000000e0060000390000000003050019000300000005001d00000003050000290bf007280000040f0000000305000029000000000001004b0000091f0000613d000108f60000003d00000b530000013d0000031d0020009c000009110000213d0000000100300190000009110000c13d000000400020043f000000000251001900000000010500190bf008920000040f000300000001001d00000005010000290bf009ce0000040f000500000001001d00000003010000290bf009f50000040f0000000504000029000000000004004b00000004030000290000090c0000613d000000010200008a00000000024200d9000000000012004b000009150000413d00000000014100aa000008dc0000c13d000000000100001900000000013100a9000000000001042d0000035901000041000000000010043f0000004101000039000009180000013d0000035901000041000000000010043f0000001101000039000000040010043f0000035a0100004100000bf2000104300000033801000041000000000010043f0000032a0100004100000bf2000104300000000204000367000000200100008a000000000200003100000000051201700000001f0620018f000000400100043d00000000035100190000092d0000613d000000000704034f0000000008010019000000007907043c0000000008980436000000000038004b000009290000c13d000000000006004b000009310000613d000109310000003d00000b8b0000013d0bf00afa0000040f0003000000000002000109350000003d00000bb30000013d0000033c020000410bf00b200000040f000000010010008c0000095d0000613d0000000a0010008c000009630000613d000000890010008c000009690000613d000001440010008c0000096f0000613d000001680010008c000009750000613d00000ab50010008c0000097b0000613d000013880010008c000009810000613d00001d880010008c000009870000613d000021050010008c0000098d0000613d0000a4b10010008c000009930000613d0000033f0010009c000009990000613d000003400010009c0000099f0000613d000003410010009c000009a50000613d000003420010009c000009ab0000613d000003430010009c000009b10000613d0000033e0010009c000009b70000c13d00000002010000290000031b011001970000038b0010009c000009b50000613d0000038c0010009c000009ca0000013d00000002010000290000031b01100197000003970010009c000009b50000613d000003980010009c000009ca0000013d00000002010000290000031b01100197000003930010009c000009b50000613d000003940010009c000009ca0000013d00000002010000290000031b011001970000038d0010009c000009b50000613d0000038e0010009c000009ca0000013d00000002010000290000031b01100197000003830010009c000009b50000613d000003840010009c000009ca0000013d00000002010000290000031b01100197000003800010009c000009b50000613d000003820010009c000009ca0000013d00000002010000290000031b011001970000037c0010009c000009b50000613d0000037d0010009c000009ca0000013d00000002010000290000031b01100197000003820010009c000009b50000613d000003870010009c000009ca0000013d00000002010000290000031b01100197000003800010009c000009b50000613d000003810010009c000009ca0000013d00000002010000290000031b01100197000003950010009c000009b50000613d000003960010009c000009ca0000013d00000002010000290000031b01100197000003910010009c000009b50000613d000003920010009c000009ca0000013d00000002010000290000031b011001970000038a0010009c000009b50000613d000003490010009c000009ca0000013d00000002010000290000031b01100197000003850010009c000009b50000613d000003860010009c000009ca0000013d00000002010000290000031b011001970000037e0010009c000009b50000613d0000037f0010009c000009ca0000013d00000002010000290000031b01100197000003880010009c000009b50000613d000003890010009c000009ca0000013d00000002010000290000031b011001970000038f0010009c000009c90000c13d0000000101000039000009cc0000013d000000010100003900000002020000290000031b022001970000006a03000039000000000303041a0000031b03300197000000000032004b000009cc0000613d0000006b03000039000000000303041a0000031b03300197000000000032004b000009cc0000613d0000006701000039000000000101041a0000031b01100197000000000012004b000009ca0000013d000003900010009c00000000010000390000000101006039000000010110018f000000000001042d00030000000000020bf00a1e0000040f000109d20000003d00000bb30000013d0000033c020000410bf00b200000040f000000890010008c000009de0000613d0000000002010019000013880010008c000009e00000613d0000039901000041000003420020009c000009e10000c13d0000039b01000041000009e10000013d0000039c01000041000009e10000013d0000039a0100004100000bd70000013d0003000000000002000109e50000003d00000bb30000013d0000033c020000410bf00b200000040f000000890010008c000009f10000613d0000000002010019000013880010008c000009f30000613d0000039901000041000003420020009c000009f40000c13d0000039b01000041000009f40000013d0000039c01000041000009f40000013d0000039a0100004100000bd70000013d00030000000000020000031b01100198000009fc0000613d000000010200008a00000000021200d9000000000012004b00000a170000413d00000000011100a9000300000001001d000000010200008a0bf00a9f0000040f00000003040000290000031a034000d1000000000131004b00000000020000390000000102004039000000000121004b00000a090000c13d000000c001300270000000000001042d000200000003001d000100000001001d000003670010009c00000a1d0000813d000000000104001900000367020000410bf00a9f0000040f000000020110006b0000000102000029000000010220408a000000c0011002700000004002200210000000000112019f000000000001042d0000035901000041000000000010043f0000001101000039000000040010043f0000035a0100004100000bf20001043000000bda0000013d00030000000000020000000002010019000000400300043d0000039d0100004100000000001304350000000005000415000000030550008a000000050550021000000000010004140000031b02200197000000040020008c00000a350000613d00000004040000390000002006000039000100000003001d00000001050000290bf007280000040f00000001030000290000000005000415000000020550008a0000000505500210000000000001004b00000a4d0000613d00000000010000310000001f02100039000000200400008a000000000442016f0000000002340019000000000042004b000000000400003900000001040040390000031d0020009c00000a980000213d000000010040019000000a980000c13d000000400020043f0000031e0010009c00000a9e0000213d0000001f0010008c00000a9e0000a13d00000000010304330000000502500270000000000201001f000003a00010009c00000000010000390000000101006039000000000001042d0000000003000031000000040230008c000000000100001900000a4c0000413d000000000100043d0000039e011001970000000204000367000000000504043b0000039f05500197000000000115019f000000000010043f000000440030008c00000a960000413d0000039f01100197000003240010009c000000000100001900000a4c0000c13d0000000406400370000000200400008a00000000074201700000001f0820018f000000400500043d000000000175001900000a6b0000613d000000000906034f000000000a050019000000009b09043c000000000aba043600000000001a004b00000a670000c13d000000000008004b00000a780000613d000000000676034f0000000307800210000000000801043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f000000000061043500000000060504330000031d0060009c00000a960000213d0000002401600039000000000031004b000000000100001900000a4c0000213d000000000756001900000000030704330000031d0030009c000000000100001900000a4c0000213d000000000125001900000000023700190000002002200039000000000012004b000000000100001900000a4c0000213d00000000013600190000003f01100039000000000241016f0000000001520019000000000021004b000000000200003900000001020040390000031d0010009c00000a980000213d000000010020019000000a980000c13d000000400010043f0000000001000019000000000001042d0000035901000041000000000010043f0000004101000039000000040010043f0000035a0100004100000bf20001043000000bda0000013d000000000002004b00000aa80000613d0000031a3020012900000000102100d9000003a10020009c00000aaa0000213d00000000011300a900000000102100d9000000000001042d0000000001000019000000000001042d000003670020009c000000c0040000390000008004004039000000000542022f00000040040000390000008004004039000003a20050009c000000200440808a0000002005508270000003a30050009c000000100440808a0000001005508270000001000050008c000000080440808a0000000805508270000000100050008c000000040440808a0000000405508270000000040050008c00000000060500190000000206608270000000020700008a0000000008600089000000020060008c0000000008078019000000040050008c000000020440808a00000000351300a90000000001480019000000ff0410018f00000000034301cf000000010400008a000000000441013f000000ff0440018f0000000106500270000000000446022f000000000643019f00000000021201cf000000800320027000000000983600d900000000051501cf0000008007500270000003a104200197000003a40080009c00000adc0000213d000000000a4800a9000000800b900210000000000b7b019f0000000000ba004b00000ae00000a13d0000000009390019000000010880008a000003a10090009c00000ad50000413d000003a10880019700000000082800a90000008006600210000000000676019f000000000686004900000000873600d9000003a105500197000003a40070009c00000aee0000213d00000000094700a9000000800a800210000000000a5a019f0000000000a9004b00000af20000a13d0000000008380019000000010770008a000003a10080009c00000ae70000413d000003a10370019700000000022300a90000008003600210000000000353019f0000000002230049000000000112022f000000000001042d000000000001042f000002fd0010009c000002fd010080410000004001100210000002fd0020009c000002fd020080410000006002200210000000000112019f00000bf200010430000002fd0010009c000002fd010080410000004001100210000002fd0020009c000002fd020080410000006002200210000000000112019f000000e002300210000000000121019f00000bf10001042e000002fd0010009c000002fd010080410000004001100210000002fd0020009c000002fd020080410000006002200210000000000112019f0000000002000414000002fd0020009c000002fd02008041000000c002200210000000000112019f00000333011001c700008010020000390bf00b430000040f000000010020019000000b1f0000613d000000000101043b000000000001042d00000bda0000013d00000000050100190000000000200443000000050030008c00000b2e0000413d000000040100003900000000020000190000000506200210000000000664001900000005066002700000000006060031000000000161043a0000000102200039000000000031004b00000b260000413d000002fd0030009c000002fd0300804100000060013002100000000002000414000002fd0020009c000002fd02008041000000c002200210000000000112019f000003a5011001c700000000020500190bf00b430000040f000000010020019000000b3d0000613d000000000101043b000000000001042d000000000001042f00000b41002104210000000102000039000000000001042d0000000002000019000000000001042d00000b46002104230000000102000039000000000001042d0000000002000019000000000001042d00000b4b002104250000000102000039000000000001042d0000000002000019000000000001042d000000000021043500000004021000390000002003000039000000000032043500000084020000390bf00afa0000040f00000000010000310000001f02100039000000200300008a000000000332016f0000000002530019000000000032004b00000000030000390000000103004039000000010000013b0bf0087d0000040f000000000010043f0000006601000039000000200010043f000000400200003900000000010000190bf00b0c0000040f000000000101041a000000ff00100190000000010000013b000000000104043b000900000001001d0bf0077f0000040f00000009010000290000000a020000290bf0087d0000040f000000000010043f0000006601000039000000200010043f000000400200003900000000010000190bf00b0c0000040f000000400300043d000000000201041a000000ff00200190000000010000013b0000000001000412000d00000001001d000c00000000003d0000800501000039000000440300003900000000040004150000000d0440008a0000000504400210000000010000013b000000000010043f0000006801000039000000200010043f000000400200003900000000010000190bf00b0c0000040f000000010000013b0bf0075d0000040f000a00000001001d0bf0077f0000040f0000000a01000029000000010000013b000000000454034f0000000305600210000000000603043300000000065601cf000000000656022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000464019f0000000000430435000000010000013b000000000661034f0000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f0000000000540435000000010000013b000000000004004b0000000005000039000000010500c039000000000054004b000000010000013b0bf0087d0000040f000000000010043f0000006601000039000000200010043f000000400200003900000000010000190bf00b0c0000040f000000000101041a000000ff001001900000000002000019000000010000013b000200000001001d0000800b0100003900000004030000390000000004000415000000030440008a0000000504400210000000010000013b000000200100008a00000000051201700000001f0620018f000000400100043d0000000003510019000000010000013b000000000003001f00020000000103550000000001020019000000000001042d000000000100003900000001010060390bf007cb0000040f0000000a010000290bf007e70000040f000000400100043d000000010000013b00000000010004110bf007930000040f00000009010000290bf007930000040f0000006502000039000000000102041a000000010000013b0000000000210435000000040210003900000020030000390000000000320435000000010000013b000000020000006b000000010110c270000000000001042d000000000100001900000bf200010430000300000001001d000080020100003900000024030000390000000004000415000000030440008a0000000504400210000000010000013b0000000004000019000000000500001900000000060000190bf007040000040f000000010000013b00000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f000000010000013b00000bf00000043200000bf10001042e00000bf200010430000000000000000000000000000000000000000000000000000000000000000000000000ffffffff000000020000000000000000000000000000008000000100000000000000000000000000000000000000000000000000000000000000000000000000fe1e8e7e000000000000000000000000000000000000000000000000000000002dda7bc5000000000000000000000000000000000000000000000000000000003659cfe6000000000000000000000000000000000000000000000000000000004f1ef2860000000000000000000000000000000000000000000000000000000052d1902d000000000000000000000000000000000000000000000000000000005fc3ea0b0000000000000000000000000000000000000000000000000000000062a31a090000000000000000000000000000000000000000000000000000000062e03bcc00000000000000000000000000000000000000000000000000000000639c93da000000000000000000000000000000000000000000000000000000006478cd98000000000000000000000000000000000000000000000000000000006f18e93f00000000000000000000000000000000000000000000000000000000715018a60000000000000000000000000000000000000000000000000000000076c1989300000000000000000000000000000000000000000000000000000000860caf0a000000000000000000000000000000000000000000000000000000008830eac0000000000000000000000000000000000000000000000000000000008da5cb5b000000000000000000000000000000000000000000000000000000009247ef90000000000000000000000000000000000000000000000000000000009690ca56000000000000000000000000000000000000000000000000000000009cab9ce800000000000000000000000000000000000000000000000000000000b2a3a9a000000000000000000000000000000000000000000000000000000000b8fd5cf500000000000000000000000000000000000000000000000000000000bde5703f00000000000000000000000000000000000000000000000000000000cc2a9a5b00000000000000000000000000000000000000000000000000000000d636953800000000000000000000000000000000000000000000000000000000f2fde38b00000000000000000000000000000000000000000000000000000000f67dcf88000000000000000000000000000000000000000000000000000000002d6829b20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000ffffffffffffffffffffffffffffffffffffffff8a320d6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000fffffffffffffe3f0000000000000000000000000000000000000000000000000000ffffffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff64647265737300000000000000000000000000000000000000000000000000004f776e61626c653a206e6577206f776e657220697320746865207a65726f206108c379a0000000000000000000000000000000000000000000000000000000000410501800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7f000000000000000000000000000000000000000000000000ffffffffffffff3f0000000000000000000000000000000000000000fffffffffffffffffffffffff8e6d1750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000001806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b83647920696e697469616c697a6564000000000000000000000000000000000000496e697469616c697a61626c653a20636f6e747261637420697320616c726561ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffff0000000000000000000000000000000000000000ff02000000000000000000000000000000000000200000000000000000000000007f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024980200000000000000000000000000000000000000000000000000000000000000416c726561647920737562736964697a65640000000000000000000000000000c186c41a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffbf3850c7bd00000000000000000000000000000000000000000000000000000000765096e8000000000000000000000000000000000000000000000000000000008be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09a04794d0000000000000000000000000000000000000000000000000000000086b071e4000000000000000000000000000000000000000000000000000000009a8a0592ac89c5ad3bc6df8224c17b485976f597df104ee20d0df415241f670b000000000000000000000000d3c63951b2ed18e8d92b5b251c3b636a45a547d00000000000000000000000000000000000000000000000000000000000aa36a70000000000000000000000000000000000000000000000000000000000014a34000000000000000000000000000000000000000000000000000000000008275000000000000000000000000000000000000000000000000000000000000849ea00000000000000000000000000000000000000000000000000000000000f043a000000000000000000000000000000000000000000000000000000000076adf1000000000000000000000000c189e4b2c3ebf75a56fafb5697f82c73376b654900000000000000000000000024d7f95783f5f5ed37bcbbe303a14be0627dfc2e000000000000000000000000f76d8b2afb77f663d420f827fca7bcc1b419515f000000000000000000000000e2ce42156e8456704fbea047419404858e9324af0000000000000000000000004b189127a784de57bdcdb59e0ab18086e0b7a1bc0000000000000000000000004821b6e9ac0ccc590acce2442bb6bb32388c1cb7000000000000000000000000affc7c9bfb48ffd2a580e1a0d36f8cc7d45dcb580000000000000000000000009491aa1c2f46319a645637c4105f4199b251e4dd000000000000000000000000d33c1be264bb98f86e18cd816d5fd44e97cb71630000000000000000000000004619b9673241eb41b642dc04371100d238b73ffe0000000000000000000000006fd07d4b5fd7093762fb2f278769aa7e2511d45c000000000000000000000000617b2383d93909590fac0b2aaa547ec5615d82ef0000000000000000000000007cb2cecfcffdcce0bf69366e52caec6bd719cd440000000000000000000000009cf5b12d2e2a88083647ff2fe0610f818b28ec77000000000000000000000000d9e58978808d17f99ccceab5195b052e972c0188199999999999999999999999999999999999999999999999999999999999999a0a9d031500000000000000000000000000000000000000000000000000000000a9059cbb0000000000000000000000000000000000000000000000000000000001bf363dbade8c9713473bfb336069d6c556e904f84103f174b5ef48865719691ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9ad3872000000000000000000000000000000000000000000000000000000004e487b710000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000004e6f7420616c726561647920737562736964697a656400000000000000000000310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e555550535570677261646561626c653a206d757374206e6f742062652063616c6c6564207468726f7567682064656c656761746563616c6c0000000000000000360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd914352d1902d00000000000000000000000000000000000000000000000000000000bc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b000000000000000000000000000000000000000000000000ffffffffffffff9f206661696c656400000000000000000000000000000000000000000000000000416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c000000000000000000000000000000000000000000000000ffffffffffffffe0000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffe04f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657264656c656761746563616c6c000000000000000000000000000000000000000046756e6374696f6e206d7573742062652063616c6c6564207468726f756768206163746976652070726f787900000000000000000000000000000000000000006961626c6555554944000000000000000000000000000000000000000000000045524331393637557067726164653a20756e737570706f727465642070726f786f6e206973206e6f74205555505300000000000000000000000000000000000045524331393637557067726164653a206e657720696d706c656d656e746174696f74206120636f6e747261637400000000000000000000000000000000000000455243313936373a206e657720696d706c656d656e746174696f6e206973206e0000000000000000000000000000000000000000000000010000000000000000416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006e697469616c697a696e67000000000000000000000000000000000000000000496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069000000000000000000000000000000000000000000000000ffffffffffffffa00000000000000000000000000000000000000000000000000000000000800000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000000000000007fffff000000000000000000000000000000000000000000000000ffffffffffffffc00000000000000000000000006b590ea2e6ccb5011617c3a09bb29ebda8459875000000000000000000000000e91dcebfe7f3e0b2d59b67f196fb33e339007c4600000000000000000000000099f80ff8c7607e8e6b6a998e9389dcaec97ba9c9000000000000000000000000d5b168f790582255c9c82cb65193a009cd6c2c670000000000000000000000008c23711a0536397c261bf83ec474b9aaf05c549b000000000000000000000000526fe4ed6f23f34a97015e41f469fd54f37036f5000000000000000000000000d8f0a3aa4067be3d70a5b46a795ad9df9e65cd3c00000000000000000000000089640d083837d9487e4e1c2122acc1adaf0e5654000000000000000000000000c1c701d7a488b46ff095ec4094ddd5ab78c9421e000000000000000000000000f6c67c7bb7018e4609d571023196a4682fda6f2f000000000000000000000000e019ff8033d9c761985a3ee1fa5d97cc9cf6d5c0000000000000000000000000af4d61951a425ba60ac1e7ea6d51e92d2f4748e40000000000000000000000005aa1c7f5f9d2e7f2664d3c1f454560c6dabed6c80000000000000000000000009c602ce508e41ccaf2cf997d93a9fbe0166d8ae60000000000000000000000009958f83f383ca150bb2252b4275d3e3051be469f000000000000000000000000a2d14ca9985de170db128c8cb74cecb35eeaf47e000000000000000000000000cebc3b3134fbef95ed13aecdf997d4371d0223850000000000000000000000004ccb72e7e0cd948af50bc7bf598fc4e027b70f98000000000000000000000000ae22cd8052d64e7c2af6b5e3045fab0a86c8334c0000000000000000000000000afb6566c836d1c4788cd2b54bd9ca0158cc2d3d000000000000000000000000f12a4018647dd2275072967fd5f3ac5fef7a04710000000000000000000000007f75358787f880506c5dc6100386f77be8de0a300000000000000000000000003a2afe86e594540cbf3ea345dd29e09228f186d2000000000000000000000000b207774ac4e32ece47771e64bde5ec3894c1de6b00000000000000000000000015753e20667961fb30d5aa92e2255b876568be7e000000000000000000000000922e9f8cc491facbd403afa143aa53ee9146474c000000000000000000000000a748be280c9a00edaf7d04076fe8a93c59e95b03000000000000000000000000dfee0ed4a217f37b3fa87624ee00fe5685bdc50900000000000000000000000094fa6e7fc2555ada63ea56cfff425558360f00740000000000000000000000000000000000000000000000000002d79883d2000000000000000000000000000000000000000000000000000030927f74c9de000000000000000000000000000000000000000000000000000006f05b59d3b200000000000000000000000000000000000000000000000000001f6ee57fe0428000cbab0bd30000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000003a9654d81ac4dafbb9a2fb1cd3efa3de2783ae40b06b17a456bf5922ed02a3a700000000000000000000000000000000ffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000fffffffffffffffffffffffffffffffe0200000200000000000000000000000000000000000000000000000000000000c93fc8de50ac49b02e25688ab64383c04c82cb8f10b990b0d8e184f0090cb4d6
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.