Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
415463 | 46 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:
AuctionManager
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: Unlicensed pragma solidity 0.8.10; import { IMinimalForwarder } from "./interfaces/IMinimalForwarder.sol"; import { IAuctionManager } from "./interfaces/IAuctionManager.sol"; import { IOwnable } from "./interfaces/IOwnable.sol"; import { IERC721GeneralMint } from "../erc721/interfaces/IERC721GeneralMint.sol"; import { IERC721EditionMint } from "../erc721/interfaces/IERC721EditionMint.sol"; import { IERC721EditionsStartId } from "../erc721/interfaces/IERC721EditionsStartId.sol"; import "../utils/EIP712Upgradeable.sol"; import { SafeMath } from "@openzeppelin/contracts/utils/math/SafeMath.sol"; import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import { IERC721, IERC165 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { ERC721Holder } from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; import { ERC1155Holder } from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol"; import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; /** * @title Manages auctions * @notice Facilitates lion's share of auctions on HL * @dev Does not support meta-transactions at the moment. * Will support, if a need arises. Otherwise, save some gas without. * @author highlight.xyz */ contract AuctionManager is IAuctionManager, ReentrancyGuardUpgradeable, EIP712Upgradeable, OwnableUpgradeable, UUPSUpgradeable, ERC721Holder, ERC1155Holder { using ECDSA for bytes32; using SafeMath for uint256; using EnumerableSet for EnumerableSet.AddressSet; /** * @notice Tracks number of bids made per user per auction */ mapping(bytes32 => mapping(address => uint256)) public auctionBids; /** * @notice Tracks auction ids to auctions */ mapping(bytes32 => IAuctionManager.EnglishAuction) private _auctions; /** * @notice Tracks auction ids to data about current highest bidder on respective auction */ mapping(bytes32 => IAuctionManager.HighestBidderData) private _highestBidders; /** * @notice Trusted minimal forwarder on collections */ address private _collectionMinimalForwarder; /** * @notice Cut of winning bids taken by platform, in basis points */ uint256 private _platformCutBPS; /** * @notice Platform receiving portion of payment */ address payable private _platform; /** * @notice Platform transaction executors */ EnumerableSet.AddressSet internal _platformExecutors; /** * @notice Tracks auction ids to the edition auction data for the auction */ mapping(bytes32 => IAuctionManager.EditionAuction) private _auctionEditions; /** * @notice Emitted when platform executor is added or removed * @param executor Changed executor * @param added True if executor was added and false otherwise */ event PlatformExecutorChanged(address indexed executor, bool indexed added); /** * @notice Require that the specified auction does not exist (auction id is not being used) * @param auctionId ID of auction being checked */ modifier auctionNonExistent(bytes32 auctionId) { require(_auctions[auctionId].state == AuctionState.NON_EXISTENT, "Auction id used"); _; } /** * @notice Require that the specified auction exists and it is in the LIVE_ON_CHAIN state * @param auctionId ID of auction being checked */ modifier auctionIsLiveOnChain(bytes32 auctionId) { require(_auctions[auctionId].state == AuctionState.LIVE_ON_CHAIN, "Not live"); _; } /** * @notice Require that caller is auction owner * @param auctionId ID of auction who's owner is checked */ modifier onlyAuctionOwner(bytes32 auctionId) { require(_auctions[auctionId].owner == msg.sender, "Not auction owner"); _; } /** * @notice Require that caller is a collection's owner or the collection itself * @param auction Auction for collection */ modifier onlyCollectionOrCollectionOwner(IAuctionManager.EnglishAuction memory auction) { require( auction.collection == msg.sender || IOwnable(auction.collection).owner() == msg.sender, "Not collection owner or collection" ); _; } /** * @notice Require that caller is the auction's current highest bidder * @param auctionId Auction ID */ modifier onlyHighestBidder(bytes32 auctionId) { require(_highestBidders[auctionId].bidder == msg.sender, "Not current highest bidder"); _; } /* solhint-disable no-empty-blocks */ receive() external payable {} fallback() external payable {} /** * @notice Initialize the contract * @param platform Platform * @param collectionMinimalForwarder Trusted minimal forwarder on collections * @param initialUpgrader Initial account able to upgrade contract * @param initialExecutor Initial account to seed executors with */ function initialize( address payable platform, address collectionMinimalForwarder, address initialUpgrader, address initialExecutor ) external initializer { _platform = platform; _collectionMinimalForwarder = collectionMinimalForwarder; _platformCutBPS = 500; _platformExecutors.add(initialExecutor); __EIP721Upgradeable_initialize("AuctionManager", "1.0.0"); __ReentrancyGuard_init(); __Ownable_init(); _transferOwnership(initialUpgrader); } /** * @notice Add platform executor. Expected to be protected by a smart contract wallet. * @param _executor Platform executor to add */ function addPlatformExecutor(address _executor) external onlyOwner { require(_executor != address(0), "Cannot set to null address"); require(_platformExecutors.add(_executor), "Already added"); emit PlatformExecutorChanged(_executor, true); } /** * @notice Deprecate platform executor. Expected to be protected by a smart contract wallet. * @param _executor Platform executor to deprecate */ function deprecatePlatformExecutor(address _executor) external onlyOwner { require(_platformExecutors.remove(_executor), "Not deprecated"); emit PlatformExecutorChanged(_executor, false); } /** * @notice See {IAuctionManager-createAuctionForNewToken} */ function createAuctionForNewToken( bytes32 auctionId, IAuctionManager.EnglishAuction memory auction ) external override nonReentrant onlyCollectionOrCollectionOwner(auction) { _createAuction(auctionId, auction, true); } /** * @notice See {IAuctionManager-createAuctionForNewEdition} */ function createAuctionForNewEdition( bytes32 auctionId, IAuctionManager.EnglishAuction memory auction, uint256 editionId ) external override nonReentrant onlyCollectionOrCollectionOwner(auction) auctionNonExistent(auctionId) { auction.mintWhenReserveMet = true; auction.state = AuctionState.LIVE_ON_CHAIN; _auctions[auctionId] = auction; _auctionEditions[auctionId] = IAuctionManager.EditionAuction(true, editionId); emit EnglishAuctionCreated( auctionId, auction.owner, auction.collection, auction.tokenId, auction.currency, auction.paymentRecipient, auction.endTime ); } /** * @notice See {IAuctionManager-createAuctionForExistingToken} */ function createAuctionForExistingToken( bytes32 auctionId, IAuctionManager.EnglishAuction memory auction ) external override nonReentrant onlyCollectionOrCollectionOwner(auction) { IERC721(auction.collection).safeTransferFrom(auction.owner, address(this), auction.tokenId); _createAuction(auctionId, auction, false); } /** * @notice See {IAuctionManager-createAuctionForExistingTokenWithMetaTxPacket} */ function createAuctionForExistingTokenWithMetaTxPacket( bytes32 auctionId, IAuctionManager.EnglishAuction memory auction, IMinimalForwarder.ForwardRequest calldata req, bytes calldata requestSignature ) external override nonReentrant onlyCollectionOrCollectionOwner(auction) { IMinimalForwarder(_collectionMinimalForwarder).execute(req, requestSignature); _createAuction(auctionId, auction, false); } /** * @notice See {IAuctionManager-bid} */ function bid( IAuctionManager.Claim calldata claim, bytes calldata claimSignature, address preferredNftRecipient ) external payable override auctionIsLiveOnChain(claim.auctionId) nonReentrant { IAuctionManager.EnglishAuction memory auction = _auctions[claim.auctionId]; IAuctionManager.HighestBidderData memory currentHighestBidderData = _highestBidders[claim.auctionId]; // validate validity of time, update value require(block.timestamp <= auction.endTime, "Auction expired"); bool timeExtended = false; if (block.timestamp.add(claim.buffer) > auction.endTime) { auction.endTime = block.timestamp.add(claim.buffer); _auctions[claim.auctionId].endTime = auction.endTime; timeExtended = true; } // handle last highest bid bool firstBid = true; if (currentHighestBidderData.bidder != address(0)) { firstBid = false; _processLastHighestBid(currentHighestBidderData, auction.currency); } _processGatedMintClaim( claim, auction.currency, claimSignature, currentHighestBidderData, preferredNftRecipient ); // if mintOnReserve and this is first valid bid, mint via general interface if (firstBid && auction.mintWhenReserveMet) { // mint new nft and put it into escrow if this auction doesn't have an nft in escrow yet IAuctionManager.EditionAuction memory editionAuction = _auctionEditions[claim.auctionId]; if (editionAuction.used == true) { IERC721EditionMint(auction.collection).mintOneToRecipient(editionAuction.editionId, address(this)); } else { auction.tokenId = IERC721GeneralMint(auction.collection).mintOneToOneRecipient(address(this)); } _auctions[claim.auctionId].tokenId = auction.tokenId; } // emit correct events emit Bid( claim.auctionId, claim.claimer, firstBid, auction.collection, auction.tokenId, claim.bidPrice, timeExtended, preferredNftRecipient, auction.endTime ); if (timeExtended) { emit TimeLengthened(claim.auctionId, auction.tokenId, auction.collection, claim.buffer, auction.endTime); } } /** * @notice See {IAuctionManager-fulfillAuction} */ function fulfillAuction(bytes32 auctionId) external override auctionIsLiveOnChain(auctionId) nonReentrant { IAuctionManager.EnglishAuction memory auction = _auctions[auctionId]; IAuctionManager.HighestBidderData memory highestBidderData = _highestBidders[auctionId]; IAuctionManager.EditionAuction memory editionData = _auctionEditions[auctionId]; require(block.timestamp > auction.endTime && auction.endTime != 0, "Auction hasn't ended"); // send nft to recipient as preferred by winning bidder // use edition to transfer (calculate tokenId on the fly) uint256 tokenId = auction.tokenId; if (editionData.used) { tokenId = IERC721EditionsStartId(auction.collection).editionStartId(editionData.editionId); } try IERC721(auction.collection).safeTransferFrom( address(this), highestBidderData.preferredNFTRecipient, tokenId ) {} catch { // encourage fulfiller to urge highest bidder to update their preferred nft recipient revert("Preferred nft recipient is an invalid receiver"); } // send winning bid to payment recipient on auction and platform uint256 platformCut = highestBidderData.amount.mul(_platformCutBPS).div(10000); uint256 recipientCut = highestBidderData.amount.sub(platformCut); if (auction.currency == address(0)) { (bool sentToRecipient, bytes memory dataRecipient) = auction.paymentRecipient.call{ value: recipientCut }( "" ); require(sentToRecipient, "Failed to send native gas token to payment recipient"); if (platformCut > 0) { (bool sentToPlatform, bytes memory dataPlatform) = _platform.call{ value: platformCut }(""); require(sentToPlatform, "Failed to send native gas token to platform"); } } else { IERC20(auction.currency).transfer(auction.paymentRecipient, recipientCut); if (platformCut > 0) { IERC20(auction.currency).transfer(_platform, platformCut); } } emit AuctionWon( auctionId, auction.tokenId, auction.collection, auction.owner, highestBidderData.bidder, auction.paymentRecipient, highestBidderData.preferredNFTRecipient, auction.currency, highestBidderData.amount, uint256(10000).sub(_platformCutBPS) ); _auctions[auctionId].state = AuctionState.FULFILLED; } function cleanup() external { bytes32 auc6Id = 0x3635643538626564343763383530306366376633383630310000000000000000; bytes32 auc1Id = 0x3635643537656362626539653766323466383839393738340000000000000000; // handle sending of money of auc1 IAuctionManager.EnglishAuction memory auction = _auctions[auc1Id]; require(auction.state != AuctionState.FULFILLED, "a"); IAuctionManager.HighestBidderData memory highestBidderData = _highestBidders[auc1Id]; uint256 platformCut = highestBidderData.amount; require(platformCut == 30000000000000000, "a.5"); (bool sentToPlatform, bytes memory dataPlatform) = _platform.call{ value: platformCut }(""); require(sentToPlatform, "Failed to send native gas token to platform"); // handle sending nft of auc6 IAuctionManager.EnglishAuction memory auctionAuc6 = _auctions[auc6Id]; require(auctionAuc6.state == AuctionState.FULFILLED, "b"); IAuctionManager.HighestBidderData memory highestBidderDataAuc6 = _highestBidders[auc6Id]; IAuctionManager.EditionAuction memory editionData = _auctionEditions[auc6Id]; require(editionData.editionId == 6, "c"); uint256 tokenId = IERC721EditionsStartId(auction.collection).editionStartId(editionData.editionId); require(tokenId == 7, "d"); IERC721(auction.collection).safeTransferFrom( address(this), highestBidderDataAuc6.preferredNFTRecipient, tokenId ); } /** * @notice See {IAuctionManager-cancelAuctionOnChain} */ function cancelAuctionOnChain( bytes32 auctionId ) external override nonReentrant auctionIsLiveOnChain(auctionId) onlyAuctionOwner(auctionId) { IAuctionManager.EnglishAuction memory auction = _auctions[auctionId]; IAuctionManager.HighestBidderData memory highestBidderData = _highestBidders[auctionId]; require(highestBidderData.bidder == address(0), "Reserve price met already"); // if the auction manager has the nft in escrow, return it if (!auction.mintWhenReserveMet) { IERC721(auction.collection).safeTransferFrom(address(this), auction.owner, auction.tokenId); } _auctions[auctionId].state = AuctionState.CANCELLED_ON_CHAIN; emit AuctionCanceledOnChain(auctionId, auction.owner, auction.collection, auction.tokenId); } /** * @notice See {IAuctionManager-updatePaymentRecipient} */ function updatePaymentRecipient( bytes32 auctionId, address payable newPaymentRecipient ) external onlyAuctionOwner(auctionId) auctionIsLiveOnChain(auctionId) { _auctions[auctionId].paymentRecipient = newPaymentRecipient; emit PaymentRecipientUpdated(auctionId, _auctions[auctionId].owner, newPaymentRecipient); } /** * @notice See {IAuctionManager-updatePreferredNFTRecipient} */ function updatePreferredNFTRecipient( bytes32 auctionId, address newPreferredNFTRecipient ) external onlyHighestBidder(auctionId) auctionIsLiveOnChain(auctionId) { _highestBidders[auctionId].preferredNFTRecipient = newPreferredNFTRecipient; emit PreferredNFTRecipientUpdated(auctionId, _auctions[auctionId].owner, newPreferredNFTRecipient); } /** * @notice See {IAuctionManager-updatePlatform} */ function updatePlatform(address payable newPlatform) external onlyOwner { _platform = newPlatform; emit PlatformUpdated(newPlatform); } /** * @notice See {IAuctionManager-updatePlatformCut} */ function updatePlatformCut(uint256 newCutBPS) external onlyOwner { _platformCutBPS = newCutBPS; } /** * @notice See {IAuctionManager-updateEndTime} */ function updateEndTime( bytes32 auctionId, uint256 newEndTime ) external onlyAuctionOwner(auctionId) auctionIsLiveOnChain(auctionId) { require(_highestBidders[auctionId].bidder == address(0), "Can't update after first valid bid"); _auctions[auctionId].endTime = newEndTime; emit EndTimeUpdated(auctionId, _auctions[auctionId].owner, newEndTime); } /** * @notice See {IAuctionManager-verifyClaim} */ function verifyClaim( Claim calldata claim, bytes calldata claimSignature, address expectedMsgSender ) external view auctionIsLiveOnChain(claim.auctionId) returns (bool) { address signer = _claimSigner(claim, claimSignature); IAuctionManager.HighestBidderData memory currentHighestBidderData = _highestBidders[claim.auctionId]; uint256 currentNumClaimsByUser = auctionBids[claim.auctionId][claim.claimer]; _validateUnwrappedClaim(currentNumClaimsByUser, claim, currentHighestBidderData, signer, expectedMsgSender); return true; } /** * @notice See {IAuctionManager-getFullAuctionData} */ function getFullAuctionData( bytes32 auctionId ) external view returns ( IAuctionManager.EnglishAuction memory, IAuctionManager.HighestBidderData memory, IAuctionManager.EditionAuction memory ) { return (_auctions[auctionId], _highestBidders[auctionId], _auctionEditions[auctionId]); } /** * @notice See {IAuctionManager-getFullAuctionsData} */ function getFullAuctionsData( bytes32[] calldata auctionIds ) external view returns ( IAuctionManager.EnglishAuction[] memory, IAuctionManager.HighestBidderData[] memory, IAuctionManager.EditionAuction[] memory ) { uint256 auctionIdsLength = auctionIds.length; IAuctionManager.EnglishAuction[] memory auctions = new IAuctionManager.EnglishAuction[](auctionIdsLength); IAuctionManager.HighestBidderData[] memory highestBiddersData = new IAuctionManager.HighestBidderData[]( auctionIdsLength ); IAuctionManager.EditionAuction[] memory auctionEditions = new IAuctionManager.EditionAuction[]( auctionIdsLength ); for (uint256 i = 0; i < auctionIdsLength; i++) { bytes32 auctionId = auctionIds[i]; EnglishAuction memory _tempAuction = _auctions[auctionId]; HighestBidderData memory _tempHighestBidders = _highestBidders[auctionId]; EditionAuction memory _tempAuctionEditions = _auctionEditions[auctionId]; auctions[i] = _tempAuction; highestBiddersData[i] = _tempHighestBidders; auctionEditions[i] = _tempAuctionEditions; } return (auctions, highestBiddersData, auctionEditions); } /** * @notice Returns platform executors */ function platformExecutors() external view returns (address[] memory) { return _platformExecutors.values(); } /** * @notice See {UUPSUpgradeable-_authorizeUpgrade} * @param // New implementation to upgrade to */ function _authorizeUpgrade(address) internal override onlyOwner {} /** * @notice Process, verify, and update the state of a gated auction bid claim * @param claim Claim * @param currency Auction currency * @param claimSignature Signed + encoded claim * @param currentHighestBidderData Data of current highest bidder / bid * @param preferredNftRecipient Current highest bidder's preferred NFT recipient if their bid wins */ function _processGatedMintClaim( IAuctionManager.Claim calldata claim, address currency, bytes calldata claimSignature, IAuctionManager.HighestBidderData memory currentHighestBidderData, address preferredNftRecipient ) private { _verifyClaimAndUpdateData(claim, claimSignature, currentHighestBidderData, preferredNftRecipient); // make payments if (currency == address(0)) { // keep native gas token value on contract require(msg.value >= claim.bidPrice, "Invalid native gas token payment"); } else { IERC20(currency).transferFrom(claim.claimer, address(this), claim.bidPrice); } } /** * @notice Send the last highest bid back to the bidder * @param currentHighestBidderData Data of the last highest bid * @param currency Auction currency */ function _processLastHighestBid( IAuctionManager.HighestBidderData memory currentHighestBidderData, address currency ) private { if (currency == address(0)) { (bool sentToRecipient, bytes memory dataRecipient) = currentHighestBidderData.bidder.call{ value: currentHighestBidderData.amount }(""); require(sentToRecipient, "Failed to send Ether to last highest bidder"); } else { IERC20(currency).transfer(currentHighestBidderData.bidder, currentHighestBidderData.amount); } } /** * @notice Verify, and update the state of a gated bid claim * @param claim Claim * @param signature Signed + encoded claim * @param currentHighestBidderData Data of current highest bidder / bid * @param preferredNftRecipient Current highest bidder's preferred NFT recipient if their bid wins */ function _verifyClaimAndUpdateData( Claim calldata claim, bytes calldata signature, IAuctionManager.HighestBidderData memory currentHighestBidderData, address preferredNftRecipient ) private { address signer = _claimSigner(claim, signature); uint256 currentNumClaimsByUser = auctionBids[claim.auctionId][claim.claimer]; _validateUnwrappedClaim(currentNumClaimsByUser, claim, currentHighestBidderData, signer, msg.sender); // update claim state auctionBids[claim.auctionId][claim.claimer] = currentNumClaimsByUser + 1; // update highest bidder data _highestBidders[claim.auctionId] = IAuctionManager.HighestBidderData( claim.claimer, preferredNftRecipient, claim.bidPrice ); } /** * @notice Create an auction * @param auctionId Auction ID * @param auction Details of auction to create * @param newToken True if this auction will mint a new token when reserve price is met */ function _createAuction( bytes32 auctionId, IAuctionManager.EnglishAuction memory auction, bool newToken ) private auctionNonExistent(auctionId) { auction.mintWhenReserveMet = newToken; auction.state = AuctionState.LIVE_ON_CHAIN; _auctions[auctionId] = auction; emit EnglishAuctionCreated( auctionId, auction.owner, auction.collection, auction.tokenId, auction.currency, auction.paymentRecipient, auction.endTime ); } /** * @notice Returns true if account passed in is a platform executor * @param _executor Account being checked */ function _isPlatformExecutor(address _executor) private view returns (bool) { return _platformExecutors.contains(_executor); } /** * @notice Recover claim signature signer * @param claim Claim * @param signature Claim signature */ function _claimSigner( IAuctionManager.Claim calldata claim, bytes calldata signature ) private view returns (address) { return _hashTypedDataV4(keccak256(_claimABIEncoded(claim))).recover(signature); } /** * @notice Validate an unwrapped claim * @param currentNumClaimsByUser Current number of claims by claimer * @param claim Claim * @param currentHighestBidderData Data of current highest bidder / bid * @param signer Claim signature signer * @param msgSender Message sender */ function _validateUnwrappedClaim( uint256 currentNumClaimsByUser, Claim calldata claim, IAuctionManager.HighestBidderData memory currentHighestBidderData, address signer, address msgSender ) private view { require(msgSender == claim.claimer, "Sender not claimer"); require(_isPlatformExecutor(signer), "Claim signer not executor"); require( currentHighestBidderData.bidder != address(0) || claim.bidPrice >= claim.reservePrice, "Reserve price not met" ); require(claim.claimExpiryTimestamp >= block.timestamp, "Claim expired"); require( claim.maxClaimsPerAccount == 0 || currentNumClaimsByUser < claim.maxClaimsPerAccount, "Exceeded max claims for account" ); if (claim.minimumIncrementPerBidPctBPS == 0) { require(claim.bidPrice > currentHighestBidderData.amount, "Bid not higher"); } else { require( claim.bidPrice >= currentHighestBidderData.amount.add( currentHighestBidderData.amount.mul(claim.minimumIncrementPerBidPctBPS).div(10000) ), "Bid not big enough of a jump" ); } } /** * @notice Return abi-encoded claim * @param claim Claim */ function _claimABIEncoded(Claim calldata claim) private pure returns (bytes memory) { return abi.encode( _getClaimTypeHash(), claim.auctionId, claim.bidPrice, claim.reservePrice, claim.maxClaimsPerAccount, claim.claimExpiryTimestamp, claim.buffer, claim.minimumIncrementPerBidPctBPS, claim.claimer ); } /* solhint-disable max-line-length */ /** * @notice Get claim typehash */ function _getClaimTypeHash() private pure returns (bytes32) { return keccak256( "Claim(bytes32 auctionId,uint256 bidPrice,uint256 reservePrice,uint256 maxClaimsPerAccount,uint256 claimExpiryTimestamp,uint256 buffer,uint256 minimumIncrementPerBidPctBPS,address claimer)" ); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.10; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; /** * @author OpenZeppelin, modified by highlight.xyz to make compliant to upgradeable contracts * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * _Available since v3.4._ */ /* solhint-disable */ abstract contract EIP712Upgradeable is Initializable { /* solhint-disable var-name-mixedcase */ // Cache the domain separator, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private _CACHED_DOMAIN_SEPARATOR; uint256 private _CACHED_CHAIN_ID; bytes32 private _HASHED_NAME; bytes32 private _HASHED_VERSION; bytes32 private _TYPE_HASH; /* solhint-enable var-name-mixedcase */ /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ function __EIP721Upgradeable_initialize(string memory name, string memory version) internal onlyInitializing { bytes32 hashedName = keccak256(bytes(name)); bytes32 hashedVersion = keccak256(bytes(version)); /* solhint-disable max-line-length */ bytes32 typeHash = keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ); /* solhint-enable max-line-length */ _HASHED_NAME = hashedName; _HASHED_VERSION = hashedVersion; _CACHED_CHAIN_ID = block.chainid; _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion); _TYPE_HASH = typeHash; } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (block.chainid == _CACHED_CHAIN_ID) { return _CACHED_DOMAIN_SEPARATOR; } else { return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION); } } function _buildDomainSeparator(bytes32 typeHash, bytes32 name, bytes32 version) private view returns (bytes32) { return keccak256(abi.encode(typeHash, name, version, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", _domainSeparatorV4(), structHash)); } }
// SPDX-License-Identifier: Unlicensed pragma solidity 0.8.10; /** * @title Minimal forwarder interface * @author highlight.xyz */ interface IMinimalForwarder { struct ForwardRequest { address from; address to; uint256 value; uint256 gas; uint256 nonce; bytes data; } function execute( ForwardRequest calldata req, bytes calldata signature ) external payable returns (bool, bytes memory); function getNonce(address from) external view returns (uint256); function verify(ForwardRequest calldata req, bytes calldata signature) external view returns (bool); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; /** * @notice Mint interface on editions contracts * @author highlight.xyz */ interface IERC721EditionMint { /** * @notice Mints one NFT to one recipient * @param editionId Edition to mint the NFT on * @param recipient Recipient of minted NFT */ function mintOneToRecipient(uint256 editionId, address recipient) external returns (uint256); /** * @notice Mints an amount of NFTs to one recipient * @param editionId Edition to mint the NFTs on * @param recipient Recipient of minted NFTs * @param amount Amount of NFTs minted */ function mintAmountToRecipient(uint256 editionId, address recipient, uint256 amount) external returns (uint256); /** * @notice Mints one NFT each to a number of recipients * @param editionId Edition to mint the NFTs on * @param recipients Recipients of minted NFTs */ function mintOneToRecipients(uint256 editionId, address[] memory recipients) external returns (uint256); /** * @notice Mints an amount of NFTs each to a number of recipients * @param editionId Edition to mint the NFTs on * @param recipients Recipients of minted NFTs * @param amount Amount of NFTs minted per recipient */ function mintAmountToRecipients( uint256 editionId, address[] memory recipients, uint256 amount ) external returns (uint256); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; /** * @notice General721 mint interface * @author highlight.xyz */ interface IERC721GeneralMint { /** * @notice Mint one token to one recipient * @param recipient Recipient of minted NFT */ function mintOneToOneRecipient(address recipient) external returns (uint256); /** * @notice Mint an amount of tokens to one recipient * @param recipient Recipient of minted NFTs * @param amount Amount of NFTs minted */ function mintAmountToOneRecipient(address recipient, uint256 amount) external; /** * @notice Mint one token to multiple recipients. Useful for use-cases like airdrops * @param recipients Recipients of minted NFTs */ function mintOneToMultipleRecipients(address[] calldata recipients) external; /** * @notice Mint the same amount of tokens to multiple recipients * @param recipients Recipients of minted NFTs * @param amount Amount of NFTs minted to each recipient */ function mintSameAmountToMultipleRecipients(address[] calldata recipients, uint256 amount) external; /** * @notice Mint a chosen token id to a single recipient * @param recipient Recipient of chosen NFT * @param tokenId ID of NFT to mint */ function mintSpecificTokenToOneRecipient(address recipient, uint256 tokenId) external; /** * @notice Mint chosen token ids to a single recipient * @param recipient Recipient of chosen NFT * @param tokenIds IDs of NFTs to mint */ function mintSpecificTokensToOneRecipient(address recipient, uint256[] calldata tokenIds) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; /** * @author highlight.xyz */ interface IERC721EditionsStartId { /** * @notice Get an edition's start id */ function editionStartId(uint256 editionId) external view returns (uint256); }
// SPDX-License-Identifier: Unlicensed pragma solidity 0.8.10; import { IMinimalForwarder } from "./IMinimalForwarder.sol"; /** * @title Interface for AuctionManager * @notice Defines behaviour encapsulated in AuctionManager * @author highlight.xyz */ interface IAuctionManager { /** * @notice The state an auction is in * @param NON_EXISTENT Default state of auction pre-creation * @param LIVE_ON_CHAIN State of auction after creation but before the auction ends or is cancelled * @param CANCELLED_ON_CHAIN State of auction after auction is cancelled * @param FULFILLED State of auction after winning bid has been dispersed and NFT has left escrow */ enum AuctionState { NON_EXISTENT, LIVE_ON_CHAIN, CANCELLED_ON_CHAIN, FULFILLED } /** * @notice The data structure containing all fields on an English Auction that need to be on-chain * @param collection The collection hosting the auctioned NFT * @param currency The currency bids must be made in * @param owner The auction owner * @param paymentRecipient The recipient account of the winning bid * @param endTime When the auction will tentatively end. Is 0 if first bid hasn't been made * @param tokenId The ID of the NFT being auctioned * @param mintWhenReserveMet If true, new NFT will be minted when reserve crossing bid is made * @param state Auction state */ struct EnglishAuction { address collection; address currency; address owner; address payable paymentRecipient; uint256 endTime; uint256 tokenId; // if nft already exists bool mintWhenReserveMet; AuctionState state; } /** * @notice Used for information about auctions on editions * @param used True if the auction is for an auction on an edition * @param editionId ID of the edition used for this auction */ struct EditionAuction { bool used; uint256 editionId; } /** * @notice Data required for a bidder to make a bid. Claims are signed, hashed and validated, acting as bid keys * @param auctionId ID of auction * @param bidPrice Price that bidder is bidding * @param reservePrice Price that bidder must bid greater than. Only relevant for the first bid on an auction * @param maxClaimsPerAccount Max bids that an account can make on an auction. Unlimited if 0 * @param claimExpiryTimestamp Time when claim expires * @param buffer Minimum time that must be left in an auction after a bid is made * @param minimumIncrementPerBidPctBPS Minimum % that a bid must be higher than the previous highest bid by, * in basis points * @param claimer Account that can use the claim */ struct Claim { bytes32 auctionId; uint256 bidPrice; uint256 reservePrice; uint256 maxClaimsPerAccount; uint256 claimExpiryTimestamp; uint256 buffer; uint256 minimumIncrementPerBidPctBPS; address payable claimer; } /** * @notice Structure hosting highest bidder info * @param bidder Bidder with current highest bid * @param preferredNFTRecipient The account that the current highest bidder wants the NFT to go to if they win. * Useful for non-transferable NFTs being auctioned. * @param amount Amount of current highest bid */ struct HighestBidderData { address payable bidder; address preferredNFTRecipient; uint256 amount; } /** * @notice Emitted when an english auction is created * @param auctionId ID of auction * @param owner Auction owner * @param collection Collection that NFT being auctioned is on * @param tokenId ID of NFT being auctioned * @param currency The currency bids must be made in * @param paymentRecipient The recipient account of the winning bid * @param endTime Auction end time */ event EnglishAuctionCreated( bytes32 indexed auctionId, address indexed owner, address indexed collection, uint256 tokenId, address currency, address paymentRecipient, uint256 endTime ); /** * @notice Emitted when a valid bid is made on an auction * @param auctionId ID of auction * @param bidder Bidder with new highest bid * @param firstBid True if this is the first bid, ie. first bid greater than reserve price * @param collection Collection that NFT being auctioned is on * @param tokenId ID of NFT being auctioned * @param value Value of bid * @param timeLengthened True if this bid extended the end time of the auction (by being bid >= endTime - buffer) * @param preferredNFTRecipient The account that the current highest bidder wants the NFT to go to if they win. * Useful for non-transferable NFTs being auctioned. * @param endTime The current end time of the auction */ event Bid( bytes32 indexed auctionId, address indexed bidder, bool indexed firstBid, address collection, uint256 tokenId, uint256 value, bool timeLengthened, address preferredNFTRecipient, uint256 endTime ); /** * @notice Emitted when an auction's end time is extended * @param auctionId ID of auction * @param tokenId ID of NFT being auctioned * @param collection Collection that NFT being auctioned is on * @param buffer Minimum time that must be left in an auction after a bid is made * @param newEndTime New end time of auction */ event TimeLengthened( bytes32 indexed auctionId, uint256 indexed tokenId, address indexed collection, uint256 buffer, uint256 newEndTime ); /** * @notice Emitted when an auction is won, and its terms are fulfilled * @param auctionId ID of auction * @param tokenId ID of NFT being auctioned * @param collection Collection that NFT being auctioned is on * @param owner Auction owner * @param winner Winning bidder * @param paymentRecipient The recipient account of the winning bid * @param nftRecipient The account receiving the auctioned NFT * @param currency The currency bids were made in * @param amount Winning bid value * @param paymentRecipientPctBPS The percentage of the winning bid going to the paymentRecipient, in basis points */ event AuctionWon( bytes32 indexed auctionId, uint256 indexed tokenId, address indexed collection, address owner, address winner, address paymentRecipient, address nftRecipient, address currency, uint256 amount, uint256 paymentRecipientPctBPS ); /** * @notice Emitted when an auction is cancelled on-chain (before any valid bids have been made). * @param auctionId ID of auction * @param owner Auction owner * @param collection Collection that NFT was being auctioned on * @param tokenId ID of NFT that was being auctioned */ event AuctionCanceledOnChain( bytes32 indexed auctionId, address indexed owner, address indexed collection, uint256 tokenId ); /** * @notice Emitted when the payment recipient of an auction is updated * @param auctionId ID of auction * @param owner Auction owner * @param newPaymentRecipient New payment recipient of auction */ event PaymentRecipientUpdated( bytes32 indexed auctionId, address indexed owner, address indexed newPaymentRecipient ); /** * @notice Emitted when the preferred NFT recipient of an auctionbid is updated * @param auctionId ID of auction * @param owner Auction owner * @param newPreferredNFTRecipient New preferred nft recipient of auction */ event PreferredNFTRecipientUpdated( bytes32 indexed auctionId, address indexed owner, address indexed newPreferredNFTRecipient ); /** * @notice Emitted when the end time of an auction is updated * @param auctionId ID of auction * @param owner Auction owner * @param newEndTime New end time */ event EndTimeUpdated(bytes32 indexed auctionId, address indexed owner, uint256 indexed newEndTime); /** * @notice Emitted when the platform is updated * @param newPlatform New platform */ event PlatformUpdated(address newPlatform); /** * @notice Create an auction that mints the NFT being auctioned into escrow (mints the next NFT on the collection) * @param auctionId ID of auction * @param auction The auction details */ function createAuctionForNewToken(bytes32 auctionId, EnglishAuction memory auction) external; /** * @notice Create an auction that mints an edition being auctioned into escrow (mints the next NFT on the edition) * @param auctionId ID of auction * @param auction The auction details */ function createAuctionForNewEdition( bytes32 auctionId, IAuctionManager.EnglishAuction memory auction, uint256 editionId ) external; /** * @notice Create an auction for an existing NFT * @param auctionId ID of auction * @param auction The auction details */ function createAuctionForExistingToken(bytes32 auctionId, EnglishAuction memory auction) external; /** * @notice Create an auction for an existing NFT, with atomic transfer approval meta-tx packets * @param auctionId ID of auction * @param auction The auction details * @param req The request containing the call to transfer the auctioned NFT into escrow * @param requestSignature The signed request */ function createAuctionForExistingTokenWithMetaTxPacket( bytes32 auctionId, IAuctionManager.EnglishAuction memory auction, IMinimalForwarder.ForwardRequest calldata req, bytes calldata requestSignature ) external; /** * @notice Update the payment recipient for an auction * @param auctionId ID of auction being updated * @param newPaymentRecipient New payment recipient on the auction */ function updatePaymentRecipient(bytes32 auctionId, address payable newPaymentRecipient) external; /** * @notice Update the preferred nft recipient of a bid * @param auctionId ID of auction being updated * @param newPreferredNFTRecipient New nft recipient on the auction bid */ function updatePreferredNFTRecipient(bytes32 auctionId, address newPreferredNFTRecipient) external; /** * @notice Makes a bid on an auction * @param claim Claim needed to make the bid * @param claimSignature Claim signature to be unwrapped and validated * @param preferredNftRecipient Bidder's preferred recipient of NFT if they win auction */ function bid( IAuctionManager.Claim calldata claim, bytes calldata claimSignature, address preferredNftRecipient ) external payable; /** * @notice Fulfill auction and disperse winning bid / auctioned NFT. * @dev Anyone can call this function * @param auctionId ID of auction to fulfill */ function fulfillAuction(bytes32 auctionId) external; /** * @notice "Cancels" an auction on-chain, if a valid bid hasn't been made yet. Transfers NFT back to auction owner * @param auctionId ID of auction being "cancelled" */ function cancelAuctionOnChain(bytes32 auctionId) external; /** * @notice Updates the platform account receiving a portion of winning bids * @param newPlatform New account to receive portion */ function updatePlatform(address payable newPlatform) external; /** * @notice Updates the platform cut * @param newCutBPS New account to receive portion */ function updatePlatformCut(uint256 newCutBPS) external; /** * @notice Update an auction's end time before first valid bid is made on auction * @param auctionId Auction ID * @param newEndTime New end time */ function updateEndTime(bytes32 auctionId, uint256 newEndTime) external; /** * @notice Verifies the validity of a claim, simulating call to bid() * @param claim Claim needed to make the bid * @param claimSignature Claim signature to be unwrapped and validated * @param expectedMsgSender Expected msg.sender when bid() is called, that is being simulated */ function verifyClaim( Claim calldata claim, bytes calldata claimSignature, address expectedMsgSender ) external view returns (bool); /** * @notice Get all data about an auction except for number of bids made per user * @param auctionId ID of auction */ function getFullAuctionData( bytes32 auctionId ) external view returns (EnglishAuction memory, HighestBidderData memory, EditionAuction memory); /** * @notice Get all data about a set of auctions except for number of bids made per user * @param auctionIds IDs of auctions */ function getFullAuctionsData( bytes32[] calldata auctionIds ) external view returns (EnglishAuction[] memory, HighestBidderData[] memory, EditionAuction[] memory); }
// SPDX-License-Identifier: Unlicensed pragma solidity 0.8.10; /** * @notice Simple interface to interact with EIP-173 implementing contracts */ interface IOwnable { function owner() external view returns (address); }
// 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) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } /** * @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/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol) pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } }
// 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: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ```solidity * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/utils/ERC721Holder.sol) pragma solidity ^0.8.0; import "../IERC721Receiver.sol"; /** * @dev Implementation of the {IERC721Receiver} interface. * * Accepts all token transfers. * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}. */ contract ERC721Holder is IERC721Receiver { /** * @dev See {IERC721Receiver-onERC721Received}. * * Always returns `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) { return this.onERC721Received.selector; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/utils/ERC1155Holder.sol) pragma solidity ^0.8.0; import "./ERC1155Receiver.sol"; /** * Simple implementation of `ERC1155Receiver` that will allow a contract to hold ERC1155 tokens. * * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be * stuck. * * @dev _Available since v3.1._ */ contract ERC1155Holder is ERC1155Receiver { function onERC1155Received( address, address, uint256, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155Received.selector; } function onERC1155BatchReceived( address, address, uint256[] memory, uint256[] memory, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155BatchReceived.selector; } }
// 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.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 v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.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.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.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.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol) pragma solidity ^0.8.0; import "../IERC1155Receiver.sol"; import "../../../utils/introspection/ERC165.sol"; /** * @dev _Available since v3.1._ */ abstract contract ERC1155Receiver is ERC165, IERC1155Receiver { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (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) (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/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts 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) (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 } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155Receiver is IERC165 { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
{ "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[{"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":"bytes32","name":"auctionId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"AuctionCanceledOnChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"auctionId","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"winner","type":"address"},{"indexed":false,"internalType":"address","name":"paymentRecipient","type":"address"},{"indexed":false,"internalType":"address","name":"nftRecipient","type":"address"},{"indexed":false,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"paymentRecipientPctBPS","type":"uint256"}],"name":"AuctionWon","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"auctionId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"bidder","type":"address"},{"indexed":true,"internalType":"bool","name":"firstBid","type":"bool"},{"indexed":false,"internalType":"address","name":"collection","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bool","name":"timeLengthened","type":"bool"},{"indexed":false,"internalType":"address","name":"preferredNFTRecipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"endTime","type":"uint256"}],"name":"Bid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"auctionId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"newEndTime","type":"uint256"}],"name":"EndTimeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"auctionId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"address","name":"paymentRecipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"endTime","type":"uint256"}],"name":"EnglishAuctionCreated","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":"auctionId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"newPaymentRecipient","type":"address"}],"name":"PaymentRecipientUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"executor","type":"address"},{"indexed":true,"internalType":"bool","name":"added","type":"bool"}],"name":"PlatformExecutorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newPlatform","type":"address"}],"name":"PlatformUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"auctionId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"newPreferredNFTRecipient","type":"address"}],"name":"PreferredNFTRecipientUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"auctionId","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":false,"internalType":"uint256","name":"buffer","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newEndTime","type":"uint256"}],"name":"TimeLengthened","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"address","name":"_executor","type":"address"}],"name":"addPlatformExecutor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"}],"name":"auctionBids","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"auctionId","type":"bytes32"},{"internalType":"uint256","name":"bidPrice","type":"uint256"},{"internalType":"uint256","name":"reservePrice","type":"uint256"},{"internalType":"uint256","name":"maxClaimsPerAccount","type":"uint256"},{"internalType":"uint256","name":"claimExpiryTimestamp","type":"uint256"},{"internalType":"uint256","name":"buffer","type":"uint256"},{"internalType":"uint256","name":"minimumIncrementPerBidPctBPS","type":"uint256"},{"internalType":"address payable","name":"claimer","type":"address"}],"internalType":"struct IAuctionManager.Claim","name":"claim","type":"tuple"},{"internalType":"bytes","name":"claimSignature","type":"bytes"},{"internalType":"address","name":"preferredNftRecipient","type":"address"}],"name":"bid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"auctionId","type":"bytes32"}],"name":"cancelAuctionOnChain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cleanup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"auctionId","type":"bytes32"},{"components":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"currency","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address payable","name":"paymentRecipient","type":"address"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bool","name":"mintWhenReserveMet","type":"bool"},{"internalType":"enum IAuctionManager.AuctionState","name":"state","type":"uint8"}],"internalType":"struct IAuctionManager.EnglishAuction","name":"auction","type":"tuple"}],"name":"createAuctionForExistingToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"auctionId","type":"bytes32"},{"components":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"currency","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address payable","name":"paymentRecipient","type":"address"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bool","name":"mintWhenReserveMet","type":"bool"},{"internalType":"enum IAuctionManager.AuctionState","name":"state","type":"uint8"}],"internalType":"struct IAuctionManager.EnglishAuction","name":"auction","type":"tuple"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"gas","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IMinimalForwarder.ForwardRequest","name":"req","type":"tuple"},{"internalType":"bytes","name":"requestSignature","type":"bytes"}],"name":"createAuctionForExistingTokenWithMetaTxPacket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"auctionId","type":"bytes32"},{"components":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"currency","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address payable","name":"paymentRecipient","type":"address"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bool","name":"mintWhenReserveMet","type":"bool"},{"internalType":"enum IAuctionManager.AuctionState","name":"state","type":"uint8"}],"internalType":"struct IAuctionManager.EnglishAuction","name":"auction","type":"tuple"},{"internalType":"uint256","name":"editionId","type":"uint256"}],"name":"createAuctionForNewEdition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"auctionId","type":"bytes32"},{"components":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"currency","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address payable","name":"paymentRecipient","type":"address"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bool","name":"mintWhenReserveMet","type":"bool"},{"internalType":"enum IAuctionManager.AuctionState","name":"state","type":"uint8"}],"internalType":"struct IAuctionManager.EnglishAuction","name":"auction","type":"tuple"}],"name":"createAuctionForNewToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_executor","type":"address"}],"name":"deprecatePlatformExecutor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"auctionId","type":"bytes32"}],"name":"fulfillAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"auctionId","type":"bytes32"}],"name":"getFullAuctionData","outputs":[{"components":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"currency","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address payable","name":"paymentRecipient","type":"address"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bool","name":"mintWhenReserveMet","type":"bool"},{"internalType":"enum IAuctionManager.AuctionState","name":"state","type":"uint8"}],"internalType":"struct IAuctionManager.EnglishAuction","name":"","type":"tuple"},{"components":[{"internalType":"address payable","name":"bidder","type":"address"},{"internalType":"address","name":"preferredNFTRecipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IAuctionManager.HighestBidderData","name":"","type":"tuple"},{"components":[{"internalType":"bool","name":"used","type":"bool"},{"internalType":"uint256","name":"editionId","type":"uint256"}],"internalType":"struct IAuctionManager.EditionAuction","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"auctionIds","type":"bytes32[]"}],"name":"getFullAuctionsData","outputs":[{"components":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"currency","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address payable","name":"paymentRecipient","type":"address"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bool","name":"mintWhenReserveMet","type":"bool"},{"internalType":"enum IAuctionManager.AuctionState","name":"state","type":"uint8"}],"internalType":"struct IAuctionManager.EnglishAuction[]","name":"","type":"tuple[]"},{"components":[{"internalType":"address payable","name":"bidder","type":"address"},{"internalType":"address","name":"preferredNFTRecipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IAuctionManager.HighestBidderData[]","name":"","type":"tuple[]"},{"components":[{"internalType":"bool","name":"used","type":"bool"},{"internalType":"uint256","name":"editionId","type":"uint256"}],"internalType":"struct IAuctionManager.EditionAuction[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"platform","type":"address"},{"internalType":"address","name":"collectionMinimalForwarder","type":"address"},{"internalType":"address","name":"initialUpgrader","type":"address"},{"internalType":"address","name":"initialExecutor","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"platformExecutors","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","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":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"auctionId","type":"bytes32"},{"internalType":"uint256","name":"newEndTime","type":"uint256"}],"name":"updateEndTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"auctionId","type":"bytes32"},{"internalType":"address payable","name":"newPaymentRecipient","type":"address"}],"name":"updatePaymentRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"newPlatform","type":"address"}],"name":"updatePlatform","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newCutBPS","type":"uint256"}],"name":"updatePlatformCut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"auctionId","type":"bytes32"},{"internalType":"address","name":"newPreferredNFTRecipient","type":"address"}],"name":"updatePreferredNFTRecipient","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":[{"components":[{"internalType":"bytes32","name":"auctionId","type":"bytes32"},{"internalType":"uint256","name":"bidPrice","type":"uint256"},{"internalType":"uint256","name":"reservePrice","type":"uint256"},{"internalType":"uint256","name":"maxClaimsPerAccount","type":"uint256"},{"internalType":"uint256","name":"claimExpiryTimestamp","type":"uint256"},{"internalType":"uint256","name":"buffer","type":"uint256"},{"internalType":"uint256","name":"minimumIncrementPerBidPctBPS","type":"uint256"},{"internalType":"address payable","name":"claimer","type":"address"}],"internalType":"struct IAuctionManager.Claim","name":"claim","type":"tuple"},{"internalType":"bytes","name":"claimSignature","type":"bytes"},{"internalType":"address","name":"expectedMsgSender","type":"address"}],"name":"verifyClaim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
9c4d535b0000000000000000000000000000000000000000000000000000000000000000010005ed25ae6e21d39b845d5a407136cfcd4975bf159017fee1fa9196d1425e00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x0004000000000002001a00000000000200000060031002700000053e0a3001970003000000a1035500020000000103550000053e0030019d0000000100200190000000000800041600000001090000390000000007000410000000a002000039000000630000c13d0000008004000039000000400040043f0000000400a0008c0000006e0000413d000000000201043b000000e003200270000005400030009c0000009d06000039000000700000613d000005410030009c0000000402100370000000a60000613d000005420030009c000000b10000613d000005430030009c000000200500008a000000c70000613d000005440030009c000000fc0000613d000005450030009c0000016e0000613d000005460030009c000001840000613d000005470030009c0000019c0000613d000005480030009c000001cf0000613d000005490030009c0000020d0000613d0000054a0030009c000002420000613d0000054b0030009c0000024e0000613d0000054c0030009c0000027b0000613d0000054d0030009c000002920000613d0000054e0030009c000002ba0000613d0000054f0030009c000002ef0000613d000005500030009c000003570000613d000005510030009c000003a90000613d000005520030009c000003b10000613d000005530030009c000003c20000613d000005540030009c000003e00000613d000005550030009c000003f00000613d000005560030009c000004720000613d000005570030009c000005a20000613d000005580030009c000005cd0000613d000005590030009c0000061c0000613d0000055a0030009c0000063d0000613d0000055b0030009c000006530000613d0000055c0030009c000006690000613d0000055d0030009c0000067b0000613d0000055e0030009c0000006e0000c13d0000002400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d000000000102043b000005bc0010019800000a6b0000c13d000005bd01100197000005be0010009c00000000020000390000000102006039000005bf0010009c00000001022061bf000000800020043f000003af0000013d000000400020043f000000000008004b00000a6b0000c13d000000800070043f000001400000044300000160007004430000002001000039000001000010044300000120009004430000053f01000041000014f50001042e0000000001000019000014f50001042e000000000008004b00000a6b0000c13d00000000010a001914f40edf0000040f001100000002001d001000000003001d000f00000004001d001300000001001d0000000201100367000000000101043b001200000001001d000000000010043f0001007e0000003d0000137a0000013d000006390000213d000100810000003d000014ef0000013d00000013010000290000001102000029000000100300002914f411bc0000040f0000001202000029000000000020043f0000009e02000039000000200020043f001100000001001d0000004002000039000000000100001914f413390000040f14f4110b0000040f0000001202000029000000000020043f0000009c02000039000000200020043f001200000001001d0000000001000019000000400200003914f413390000040f0000001302000029000000e0022000390000000202200367000000000202043b0000055f0020009c00000a6b0000213d000000000020043f0001009f0000003d000014520000013d0000001302000029000000120300002900000011040000290000000f0500002914f4129b0000040f0000000102000039000003ec0000013d0000002400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d000000000102043b001300000001001d14f40f360000040f000000a0010000390000001302000029000000000021041b000009260000013d0000008400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d000000000202043b0000055f0020009c00000a6b0000213d0000002402100370000000000202043b0000055f0020009c00000a6b0000213d0000006402100370000000000302043b000005730030009c00000a6b0000213d00000023023000390000000000a2004b00000a6b0000813d000100c50000003d000014640000013d000005bb02000041000003ec0000013d0000012400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d000000000102043b001200000001001d00000000010a001914f40e670000040f001300000001001d14f4106d0000040f00000013010000290000000021010434001100000002001d0000055f021001970000000001000411000000000012004b000007030000c13d000000010100003914f4105e0000040f0000001201000029000000000010043f000100de0000003d0000137a0000013d000006390000213d000100e10000003d000013e10000013d000000130500002900000080015000390000006002500039000000a00350003900000040045000390000000005050433000000000404043300000000030304330000001106000029000000000606043300000000020204330000000001010433000000400700043d000000600870003900000000001804350000055f01200197000000400270003900000000001204350000055f016001970000002002700039000000000012043500000000003704350000053e0070009c0000053e0700804100000040017002100000000002000414000008af0000013d0000002400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d000000000102043b001300000001001d0000055f0010009c00000a6b0000213d000101060000003d000014310000013d0000059c0200004114f4134d0000040f0012055f0010019b0000000002000410000000120020006c0000000001000039000000010100c03914f40f640000040f0000059f01000041000000000101041a0000055f01100197000000120010006c0000000001000039000000010100603914f40f730000040f14f40f360000040f000000400400043d000005ba0040009c000008180000213d0000002002400039000000400020043f0000000000040435000005a101000041000000000101041a000000ff001001900000084b0000c13d001000000002001d000000400500043d000005a201000041000000000015043500000000010004140000001302000029000000040020008c000001330000613d001200000004001d000000040400003900000013020000290000000003050019001100000005001d000000110500002914f40dfb0000040f00000011050000290000001204000029000000000001004b000002040000613d000101350000003d000013850000013d000005730020009c000008180000213d0000000100300190000008180000c13d001200000004001d000000400020043f000005760010009c00000a6b0000213d000000200010008c00000a6b0000413d00000000010504330000059f0010009c000101430000003d000014be0000013d0000053e0010009c001100000001001d0000053e01008041000000400110021000000000020004140000053e0020009c0000053e02008041000000c002200210000000000112019f0000056d011001c70000800d020000390000000203000039000005a304000041000000130500002914f4136b0000040f000000010020019000000a6b0000613d00000012010000290000000001010433000000000001004b000009260000613d0000001101000029000005790010009c0000001203000029000008180000213d00000011040000290000006001400039000000400010043f0000004001400039000005a40200004100000000002104350000002001400039000005a502000041000000000021043500000027010000390000000000140435000000000403043300000000010004140000001302000029000000040020008c00000c1e0000c13d000000010100003900000c210000013d000000000008004b00000a6b0000c13d0000000001000415001300000001001d000005ad01000041000000000010043f0000009d01000039000000200010043f000005ae0100004114f410d40000040f000000e0021000390000000002020433000000030020008c000006390000213d0000081e0000c13d000000400100043d0000004402100039000005b903000041000000000032043500000024021000390000000103000039000008650000013d0000002400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d000000000102043b001300000001001d0000055f0010009c00000a6b0000213d14f40f360000040f0000001301000029000000000010043f000000a301000039000101920000003d000013be0000013d000000000301041a000000000003004b000008320000c13d000000400100043d0000004402100039000005ac03000041000000000032043500000024021000390000000e03000039000008650000013d0000004400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d0000002401100370000000000101043b001200000001001d000000000102043b001300000001001d000000000010043f0000009d01000039000101a90000003d000014d70000013d0000000201100039000000000101041a0000055f01100197000101ae0000003d000014c50000013d000101b00000003d0000138e0000013d000006390000213d000101b30000003d000014e80000013d0000009e01000039000101b60000003d000014520000013d0000055f001001980000083a0000c13d0000009d01000039000101bb0000003d000014d70000013d00000004011000390000001202000029000000000021041b0000001301000029000101c10000003d000014190000013d0000053e0010009c0000053e01008041000000400110021000000000030004140000053e0030009c0000053e03008041000000c003300210000000000113019f0000056d011001c70000055f062001970000800d020000390000000403000039000005a8040000410000023f0000013d0000004400a0008c00000a6b0000413d000000000202043b001300000002001d0000055f0020009c00000a6b0000213d0000002402100370000000000302043b000005730030009c00000a6b0000213d00000023023000390000000000a2004b00000a6b0000813d000101de0000003d000014640000013d001100000001001d000101e10000003d000014310000013d0000059c0200004114f4134d0000040f0012055f0010019b0000000001000410000000120010006c0000000001000039000000010100c03914f40f640000040f0000059f01000041000000000101041a0000055f01100197000000120010006c0000000001000039000000010100603914f40f730000040f14f40f360000040f000005a101000041000000000101041a000000ff001001900000084b0000c13d000000400500043d000005a201000041000000000015043500000000010004140000001302000029000000040020008c0000092a0000613d00000004040000390000000003050019001200000005001d000000120500002914f40dfb0000040f0000001205000029000000000001004b0000092a0000c13d000000400200043d001300000002001d00000563010000410000000000120435000000040120003914f40f910000040f00000013030000290000000002310049000008f90000013d0000004400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d0000002401100370000000000101043b001200000001001d0000055f0010009c00000a6b0000213d000000000102043b001300000001001d000000000010043f000000200060043f0000004002000039000000000100001914f413390000040f0000000201100039000000000101041a0000055f01100197000102220000003d000014c50000013d000102240000003d0000138e0000013d000006390000213d000102270000003d000014e80000013d0000009d010000390001022a0000003d000013be0000013d0000000301100039000000000201041a000005640220019700000012022001af000000000021041b0000001301000029000102320000003d000014190000013d0000053e0010009c0000053e01008041000000400110021000000000030004140000053e0030009c0000053e03008041000000c003300210000000000113019f0000056d011001c70000055f062001970000800d020000390000000403000039000005a00400004100000013050000290000001207000029000009230000013d000000000008004b00000a6b0000c13d000102460000003d000014310000013d0000059c0200004114f4134d0000040f0000055f011001970000000002000410000000000012004b0000071d0000c13d0000059f01000041000003ae0000013d0000002400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d000000000202043b000005730020009c00000a6b0000213d00000023032000390000000000a3004b00000a6b0000813d0000000403200039000000000131034f000000000101043b000f00000001001d000005730010009c00000a6b0000213d00000024022000390000000f010000290000000501100210000e00000002001d001200000001001d00000000012100190000000000a1004b00000a6b0000213d00000012010000290000003f011000390000059b01100197001100000001001d000005820010009c000008180000213d00000011010000290000008001100039000000400010043f0000000f01000029000000800010043f0000000003000019000000120030006c000009600000813d001300000003001d14f411530000040f0000001303000029000000a00230003900000000001204350000002003300039000002720000013d000000000008004b00000a6b0000c13d14f40f360000040f0000006a01000039000000000201041a0000056403200197000000000031041b000000400100043d0000053e0010009c0000053e01008041000000400110021000000000030004140000053e0030009c0000053e03008041000000c003300210000000000113019f0000055f052001970000056d011001c70000800d0200003900000003030000390000059a040000410000000006000019000009230000013d00000000010a001914f40edf0000040f000f00000002001d000e00000003001d000d00000004001d001200000001001d0000000201100367000000000101043b001300000001001d000000000010043f0001029e0000003d0000137a0000013d000006390000213d000102a10000003d000013f50000013d001100000001001d000102a40000003d000014dc0000013d000c00000001001d00000011010000290000008001100039000b00000001001d0000000001010433001000000001001d0000800b01000039000000040300003900000000040004150000001a0440008a0000000504400210000005830200004114f4134d0000040f000000100010006c000007290000a13d000000400100043d00000044021000390000059903000041000000000032043500000024021000390000000f03000039000008650000013d0000004400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d0000002401100370000000000101043b001300000001001d0000055f0010009c00000a6b0000213d000000000102043b001200000001001d000000000010043f0000009e01000039000102c90000003d000014520000013d0000055f011001970000000002000411000000000021004b0000084e0000c13d000102cf0000003d0000137a0000013d000006390000213d000102d20000003d000014ef0000013d0000001201000029000000000010043f0000009e01000039000102d70000003d000013be0000013d0000000101100039000000000201041a000005640220019700000013022001af000000000021041b0000001201000029000102df0000003d000014190000013d0000053e0010009c0000053e01008041000000400110021000000000030004140000053e0030009c0000053e03008041000000c003300210000000000113019f0000056d011001c70000055f062001970000800d0200003900000004030000390000058e0400004100000012050000290000001307000029000009230000013d0000002400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d000000000202043b0000000001000415001100000001001d001300000002001d000000000020043f000102fa0000003d0000137a0000013d000006390000213d000102fd0000003d000013f50000013d001200000001001d000103000000003d000014dc0000013d0000001302000029000000000020043f000000a402000039000000200020043f000e00000001001d0000000001000019000000400200003914f413390000040f14f411230000040f000000120200002900000080022000390000000002020433001000000002001d000f00000001001d0000800b01000039000000040300003900000000040004150000001a0440008a0000000504400210000005830200004114f4134d0000040f0000001002000029000000000002004b000008580000613d000000000021004b000008580000a13d0000001201000029000000a0051000390000000f010000290000000001010433000000000001004b001000000005001d000008c00000c13d0000000001050433000f00000001001d000000120100002900000000020104330000000e010000290000002001100039000b00000001001d0000000001010433000d00000001001d000c00000002001d0017055f0020019b0001032e0000003d0000149c0000013d000000170440008a0000000504400210000005600200004114f4134d0000040f0000000004000410000000000001004b00000a6b0000613d0000000c010000290000055f02100197000000400500043d00000044015000390000000f0300002900000000003104350000000d010000290000055f01100197000000240350003900000000001304350000057e0100004100000000001504350000055f01400197000000040350003900000000001304350000000001000414000000040020008c00000a5b0000613d00000064040000390000000003050019000f00000005001d0000000f05000029000000000600001914f40dd70000040f0000000f05000029000000000001004b00000a5b0000c13d000000400100043d0000006402100039000005850300004100000000003204350000004402100039000005860300004100000ac80000013d0000012400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d000000000102043b001100000001001d00000000010a001914f40e670000040f001300000001001d0000000001000415001200000001001d14f4106d0000040f000000130100002900000000010104330000055f021001970000000001000411000000000012004b000007c60000c13d000000010100003914f4105e0000040f0000001302000029000000a0012000390000000001010433000f00000001001d00000040012000390000000001010433001000000001001d0000000001020433000e00000001001d0016055f0010019b000103770000003d0000149c0000013d000000160440008a0000000504400210000005600200004114f4134d0000040f000000000001004b000000000400041000000a6b0000613d0000000e010000290000055f02100197000000400300043d00000044013000390000000f0500002900000000005104350000055f01400197000000240430003900000000001404350000057e01000041000000000013043500000010010000290000055f01100197000000040430003900000000001404350000000001000414000000040020008c000003980000613d0000006404000039001000000003001d0000001005000029000000000600001914f40dd70000040f0000001003000029000000000001004b000007ee0000613d0000001f010000390000000101100031000000200200008a000000000221016f0000000001320019000000000021004b00000000020000390000000102004039000005730010009c000008180000213d0000000100200190000008180000c13d000000400010043f0000001101000029000000130200002914f4116e0000040f0000046b0000013d000000000008004b00000a6b0000c13d0000006a01000039000000000101041a0000055f01100197000000800010043f0000008001000039000003ee0000013d000000000008004b00000a6b0000c13d0000000006050019000000a202000039000000000102041a000000800010043f000000000020043f00000581020000410000000003000019000000000013004b000006ed0000813d0000002004400039000000000502041a000000000054043500000001033000390000000102200039000003ba0000013d0000002400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d000000000102043b001300000001001d0000055f0010009c00000a6b0000213d14f40f360000040f000000a102000039000000000102041a00000564011001970000001303000029000000000131019f000000000012041b000000400100043d00000000003104350000053e0010009c0000053e01008041000000400110021000000000020004140000053e0020009c0000053e02008041000000c002200210000000000112019f0000056b011001c70000800d0200003900000001030000390000058004000041000009230000013d000000000008004b00000a6b0000c13d00000000010a001914f40ea60000040f001300000002001d000000000010043f0000009c01000039000103e90000003d000014d70000013d000000130200002914f40efb0000040f000000000201041a000000400100043d00000000002104350000002002000039000009280000013d0000002400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d000000000102043b001300000001001d0000000001000415001200000001001d14f4106d0000040f0000001301000029000000000010043f000103fd0000003d0000137a0000013d000006390000213d000104000000003d000014ef0000013d000104020000003d000013c30000013d0000000201100039000000000101041a0000055f01100197000104070000003d000014c50000013d000104090000003d000014e10000013d001100000001001d0001040c0000003d000014dc0000013d00000000010104330000055f001001980000085f0000c13d0000001102000029001000a00020003d000f00400020003d000000c0012000390000000001010433000000000001004b0000044d0000c13d00000010010000290000000001010433000d00000001001d0000000f010000290000000001010433000e00000001001d00000011010000290000000001010433000c00000001001d0015055f0010019b000104220000003d0000149c0000013d000000150440008a0000000504400210000005600200004114f4134d0000040f0000000004000410000000000001004b00000a6b0000613d0000000c010000290000055f02100197000000400500043d00000044015000390000000d0300002900000000003104350000000e010000290000055f01100197000000240350003900000000001304350000057e0100004100000000001504350000055f01400197000000040350003900000000001304350000000001000414000000040020008c000004440000613d00000064040000390000000003050019000e00000005001d0000000e05000029000000000600001914f40dd70000040f0000000e05000029000000000001004b000007ee0000613d000104460000003d000013850000013d000005730020009c000008180000213d0000000100300190000008180000c13d000000400020043f000005760010009c00000a6b0000213d0001044f0000003d000014460000013d00000200022001bf000000000021041b000000110100002900000000020104330000000f01000029000000000301043300000010010000290000000001010433000000400400043d00000000001404350000053e0040009c0000053e04008041000000400140021000000000040004140000053e0040009c0000053e04008041000000c004400210000000000114019f0000056b011001c70000055f063001970000055f072001970000800d0200003900000004030000390000057f04000041000000130500002914f4136b0000040f000000010020019000000a6b0000613d0000000101000039000000000011041b0000000001000415000000120200002900000000011200490000000001000002000009260000013d0000016400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d000000000102043b001000000001001d00000000010a001900130000000a001d14f40e670000040f0000001304000029001100000001001d00000002010003670000012402100370000000000202043b001200000002001d000005730020009c00000a6b0000213d000000120240006a000005760020009c00000a6b0000213d000000c40020008c00000a6b0000413d0000014402100370000000000202043b000005730020009c00000a6b0000213d0000002303200039000000000043004b00000a6b0000813d0000000403200039000000000131034f000000000101043b000f00000001001d000005730010009c00000a6b0000213d0000002402200039000e00000002001d0000000f01200029000000000041004b00000a6b0000213d14f4106d0000040f000000110100002900000000010104330000055f021001970000000001000411000000000012004b00000a6c0000c13d00000001010000390000001202000029000d00040020003d14f4105e0000040f0000009f01000039000000000101041a000000400300043d0000057b020000410000000002230436000c00000002001d001300000003001d00000004023000390000004003000039000000000032043500000002020003670000000d090000290000000d03200360000000000303043b0000055f0030009c00000a6b0000213d0000001304000029000000440440003900000000003404350000002003900039000000000432034f000000000404043b0000055f0040009c00000a6b0000213d0000001306000029000000640560003900000000004504350000002004300039000000000442034f000000000404043b000000840560003900000000004504350000004004300039000000000442034f000000000404043b000000a40560003900000000004504350000006004300039000000000442034f000000000404043b000000c40560003900000000004504350000008003300039000000000332034f0000000005000031000000120450006a000000230440008a000000000303043b0000057c063001970000057c07400197000000000876013f000000000076004b00000000060000190000057c06002041000000000043004b00000000040000190000057c040040410000057c0080009c000000000604c019000000000006004b00000a6b0000613d0000000004930019000000000342034f000000000303043b000005730030009c00000a6b0000213d0000000005350049000000000095004b00000000060000190000057c060040410000057c079001970000057c05500197000000000875013f000000000075004b00000000050000190000057c050020410000057c0080009c000000000506c019000000000005004b00000a6b0000c13d0000001309000029000000e405900039000000c0060000390000000000650435000001040590003900000000003504350000002004400039000000000642034f000000200400008a00000000074301700000001f0830018f00000124049000390000000005740019000005090000613d000000000906034f000000000a040019000000009b09043c000000000aba043600000000005a004b000005050000c13d000000000008004b000005160000613d000000000676034f0000000307800210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000000000543001900000000000504350000001f03300039000000200700008a000000000373016f00000013050000290000002405500039000001200630003900000000006504350000000e0520036000000000024300190000000f04000029000000000342043600000000067401700000001f0740018f00000000046300190000052d0000613d000000000205034f0000000008030019000000002902043c0000000008980436000000000048004b000005290000c13d0000055f02100197000000000007004b0000053b0000613d000000000165034f0000000305700210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f00000000001404350000000f0130002900000000000104350000000001000414000000040020008c0000054c0000613d0000000f040000290000001f04400039000000200500008a000000000454016f0000001305000029000000000454004900000000043400190000000003050019000000000600001914f40dd70000040f000000000001004b000007ee0000613d00000003030003670000000101000031000000200200008a00000000042101700000001f0510018f0000001302400029000005590000613d000000000603034f0000001307000029000000006806043c0000000007870436000000000027004b000005550000c13d000000000005004b0000055f0000613d000000000343034f00000003045002100001055f0000003d000014230000013d0000001f02100039000000200300008a000000000332016f0000001302300029000105650000003d0000142d0000013d000005730020009c000008180000213d0000000100300190000008180000c13d000000400020043f000005760010009c00000a6b0000213d000000400010008c00000a6b0000413d00000013030000290000000003030433000000000003004b0000000004000039000000010400c039000000000043004b00000a6b0000c13d0000000c030000290000000003030433000005730030009c00000a6b0000213d000000130410002900000013013000290000001f03100039000000000043004b00000000050000190000057c050080410000057c033001970000057c06400197000000000763013f000000000063004b00000000030000190000057c030040410000057c0070009c000000000305c019000000000003004b00000a6b0000c13d0000000031010434000005730010009c000008180000213d0000001f05100039000000200600008a000000000565016f0000003f05500039000000000565016f0000000005250019000005730050009c000008180000213d000000400050043f00000000021204360000000005310019000000000045004b00000a6b0000213d0000000004000019000000000014004b00000dd00000813d000000000524001900000000063400190000000006060433000000000065043500000020044000390000059a0000013d000000a400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d000000000202043b0000055f0020009c00000a6b0000213d0000002402100370000000000202043b0000055f0020009c00000a6b0000213d0000004401100370000000000101043b000005730010009c00000a6b0000213d000000040110003900000000020a001900130000000a001d14f40f010000040f000000130200002900000064010000390000000201100367000000000101043b000005730010009c00000a6b0000213d000000040110003914f40f010000040f000000130300002900000002020003670000008401200370000000000101043b000005730010009c00000a6b0000213d0000002304100039000000000034004b00000a6b0000813d0000000404100039000000000242034f000000000202043b000000240110003914f40e2f0000040f0000057a02000041000003ec0000013d0000002400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d000000000102043b001300000001001d14f411530000040f000000400100043d000005790010009c000008180000213d0000006002100039000000400020043f00000040021000390000000000020435000000200210003900000000000204350000000000010435000000400100043d000005650010009c000008180000213d0000004002100039000000400020043f0000002002100039000000000002043500000000000104350000001301000029000000000010043f0000009d01000039000105eb0000003d000013be0000013d0000009e02000039000000200020043f001200000001001d0000000001000019000000400200003914f413390000040f000105f30000003d0000147e0000013d001100000001001d000000120100002914f410d40000040f001200000001001d000000130100002914f4110b0000040f001000000001001d000000110100002914f411230000040f001300000001001d000000400200043d001100000002001d000000120100002914f40eb30000040f000000100500002900000000210504340000055f0110019700000011040000290000010003400039000000000013043500000000010204330000055f0110019700000120024000390000000000120435000000400150003900000000010104330000014002400039000000000012043500000013010000290000000021010434000000000001004b0000000001000039000000010100c039000001600340003900000000001304350000000003020433000001800240003900000000010400190000000000320435000001a002000039000009280000013d0000014400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d001100000009001d000000000102043b001200000001001d00000000010a001914f40e670000040f00000124020000390000000202200367000000000202043b000f00000002001d001300000001001d14f4106d0000040f00000013010000290000000021010434001000000002001d0000055f021001970000000001000411000000000012004b000007e00000c13d000000110100002914f4105e0000040f0000001201000029000000000010043f000106380000003d0000137a0000013d000008130000a13d000005a901000041000000000010043f00000021010000390000081b0000013d000000a400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d000000000202043b0000055f0020009c00000a6b0000213d0000002402100370000000000202043b0000055f0020009c00000a6b0000213d0000008402100370000000000302043b000005730030009c00000a6b0000213d00000023023000390000000000a2004b00000a6b0000813d000106510000003d000014640000013d0000057402000041000003ec0000013d0000002400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d000000000102043b001300000001001d0000055f0010009c00000a6b0000213d14f40f360000040f0000001301000029000000000001004b0000086d0000c13d000000400100043d00000064021000390000057103000041000000000032043500000044021000390000057203000041000000000032043500000024021000390000002603000039000008430000013d0000002400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d000000000102043b001300000001001d0000055f0010009c00000a6b0000213d14f40f360000040f000000130000006b0000086f0000c13d000000400100043d00000044021000390000057003000041000000000032043500000024021000390000001a03000039000008650000013d0000008400a0008c00000a6b0000413d000000000008004b00000a6b0000c13d000000000202043b001300000002001d0000055f0020009c00000a6b0000213d0000002402100370000000000202043b001200000002001d0000055f0020009c00000a6b0000213d0000004402100370000000000202043b001100000002001d0000055f0020009c00000a6b0000213d0000006401100370000000000101043b001000000001001d0000055f0010009c00000a6b0000213d0000000001000415000f00000001001d000000000300041a0000ffff00300190000006a60000613d001400000007001d0000800201000039000e00000003001d00000024030000390000000004000415000000140440008a0000000504400210000005600200004114f4134d0000040f0000000e03000029000000ff0230018f000000010020008c00000ac20000c13d000000000001004b00000ac20000c13d0000ff0000300190000001000100008a000000000113016f00000001011001bf000000000010041b00000a980000c13d0000ffff0200008a000000000121016f00000100011001bf000000000010041b000000a102000039000000000102041a000005640110019700000013011001af000000000012041b0000009f02000039000000000102041a0000056401100197000106ba0000003d0000146b0000013d000005650020009c000008180000213d0000004001200039000000400010043f0000000e0100003900000000031204360000056601000041001300000003001d0000000000130435000000400300043d000005650030009c000008180000213d000106c80000003d000014900000013d0000056701000041000106cb0000003d000013a10000013d0000056802000041000106ce0000003d000014070000013d000005690300004100000000003104350000056a0020009c000008180000213d000106d40000003d000014aa0000013d0000056902000041000106d70000003d000013cb0000013d0000ff010100008a000000000200041a000000000112016f000000000010041b000000400100043d000000010300003900000000003104350000053e0010009c0000053e01008041000000400110021000000000020004140000053e0020009c0000053e02008041000000c002200210000000000112019f0000056b011001c70000800d020000390000056c0400004114f4136b0000040f000000010020019000000abf0000c13d00000a6b0000013d000000410140008a000000000361016f000005820030009c000008180000213d0000008001300039000000400010043f00000020020000390000000000210435000000a004300039000000800200043d00000000002404350000008004000039000000c0033000390000000005000019000000000025004b000007ff0000813d000000200440003900000000060404330000055f0660019700000000036304360000000105500039000006fb0000013d000000400500043d000005750100004100000000001504350000000001000414000000040020008c0000070c0000613d0001070b0000003d000014a00000013d000007ee0000613d0001070e0000003d000013850000013d000005730020009c000008180000213d0000000100300190000008180000c13d000000400020043f000005760010009c00000a6b0000213d000000200010008c00000a6b0000413d00000000010504330000055f0010009c00000a6b0000213d0001071c0000003d000014790000013d000000d90000013d0000056301000041000000800010043f0000002001000039000000840010043f0000003801000039000000a40010043f0000059d01000041000000c40010043f0000059e01000041000000e40010043f0000008001000039000008490000013d0000001202000029000000a0022000390000000202200367000000000302043b000000010200008a000000000223013f000000000021004b000008360000213d000700000003001d0000000002130019000a00000002001d000000100020006c0000073e0000a13d0000000b010000290000000a0200002900000000002104350001073b0000003d000013c30000013d00000004011000390000000a02000029000000000021041b000000110100002900000020051000390000000c0200002900000000010204330000055f04100198000800000004001d000900000005001d000008e20000c13d000500010000003d00000009010000290000000001010433000400000001001d00000012010000290000000f020000290000000e0300002914f411bc0000040f000f00020000036b00000012020000290000000202200367000000000202043b000600000002001d000000000020043f0000009c02000039000000200020043f000e00000001001d0000004002000039000000000100001914f413390000040f0000001202000029000000e002200039000900000002001d0000000f0220035f000000000202043b000f00000002001d0000055f0020009c00000a6b0000213d0000000f02000029000000000020043f000107660000003d000014520000013d000300000001001d000000000500041100000012020000290000000c030000290000000e0400002914f4129b0000040f0000000301000029000000010110003a000008360000613d001200000001001d0000000601000029000000000010043f0000009c01000039000107750000003d000013be0000013d0000000f02000029000000000020043f000000200010043f0000000001000019000000400200003914f413390000040f0000001202000029000000000021041b00000002010003670000000902100360000000000202043b001200000002001d0000055f0020009c00000a6b0000213d0000000902000029000e00c0002000920000000e01100360000000000101043b000f00000001001d000000400100043d000005790010009c000008180000213d00000000020100190000000401000029000c055f0010019b0000000003020019000200000002001d0000006001200039000000400010043f0000004002200039000400000002001d0000000f01000029000000000012043500000012010000290000000002130436000300000002001d0000000d010000290000055f01100197000d00000001001d00000000001204350000000601000029000000000010043f0000009e01000039000107a20000003d000013be0000013d000000020200002900000000020204330000055f02200197000000000301041a0000056403300197000000000223019f000000000021041b000000030200002900000000020204330000055f022001970000000103100039000000000403041a0000056404400197000000000224019f000000000023041b000000020110003900000004020000290000000002020433000000000021041b0000000c01000029000000000001004b00000b330000c13d00000000010004160000000f0010006c00000b5d0000813d000000400100043d0000004402100039000005980300004100000000003204350000056302000041000000000021043500000024021000390000002003000039000000000032043500000004021000390000086a0000013d000000400500043d000005750100004100000000001504350000000001000414000000040020008c000007cf0000613d000107ce0000003d000014a00000013d000007ee0000613d000107d10000003d000013850000013d000005730020009c000008180000213d0000000100300190000008180000c13d000000400020043f000005760010009c00000a6b0000213d000000200010008c00000a6b0000413d00000000010504330000055f0010009c00000a6b0000213d000107df0000003d000014790000013d0000036a0000013d000000400500043d000005750100004100000000001504350000000001000414000000040020008c000008010000613d00000004040000390000000003050019001100000005001d000000110500002914f40dfb0000040f0000001105000029000000000001004b000008010000c13d00000003040003670000000102000031000000200100008a000107f30000003d000014740000013d000007fa0000613d000000000704034f0000000008010019000000007907043c0000000008980436000000000038004b000007f60000c13d000000000006004b000007fe0000613d000107fe0000003d0000143a0000013d14f413270000040f0000000002130049000009280000013d000108030000003d000013850000013d000005730020009c000008180000213d0000000100300190000008180000c13d000000400020043f000005760010009c00000a6b0000213d000000200010008c00000a6b0000413d00000000010504330000055f0010009c00000a6b0000213d000108110000003d000014790000013d001100000001001d000006320000013d000108150000003d000013e10000013d000000400100043d000005650010009c0000087a0000a13d000005a901000041000000000010043f0000004101000039000000040010043f000005aa01000041000014f600010430001200000001001d000005ad01000041000000000010043f0000009e01000039000000200010043f000005af0100004114f4110b0000040f000000400300043d00000040011000390000000001010433000005b00010009c000008ed0000c13d000000a101000039000000000201041a00000000010004140000055f04200197000000040040008c0000097d0000c13d00000001010000390000098d0000013d000000a204000039000000000204041a000000000002004b000008fa0000c13d000005a901000041000000000010043f00000011010000390000081b0000013d000000400100043d0000006402100039000005a60300004100000000003204350000004402100039000005a703000041000000000032043500000024021000390000002203000039000000000032043500000563020000410000000000210435000000040210003900000020030000390000000000320435000000840200003914f413270000040f000000130100002914f40f9e0000040f000009260000013d0000056301000041000000800010043f0000002001000039000000840010043f0000001a01000039000000a40010043f0000058d01000041000000c40010043f00000080010000390000086b0000013d000000400100043d00000044021000390000058c03000041000000000032043500000024021000390000001403000039000008650000013d000000400100043d00000044021000390000057d03000041000000000032043500000024021000390000001903000039000000000032043500000563020000410000000000210435000000040210003900000020030000390000000000320435000000640200003914f413270000040f14f40f4a0000040f000009260000013d000000130100002914f4103c0000040f000000400300043d000000000001004b000009150000c13d00000044013000390000056f02000041000000000021043500000024013000390000000d02000039000008f20000013d0000000003010019000e00000001001d0000004001100039000000400010043f0000002002300039001100000002001d0000000f010000290000000000120435000000010100003900000000001304350000001201000029000000000010043f000000a401000039000108890000003d000013be0000013d000001000200008a000000000301041a000000000223016f0000000e030000290000000003030433000000000003004b000000010220c1bf000000000021041b000000110200002900000000020204330000000101100039000000000021041b000000130500002900000060015000390000008002500039000000a003500039000000400450003900000000050504330000000004040433000000000303043300000000020204330000000001010433000000100600002900000000060604330000055f06600197000000400700043d000000200870003900000000006804350000055f01100197000000400670003900000000001604350000006001700039000000000021043500000000003704350000053e0070009c0000053e07008041000000400170021000000000020004140000053e0020009c0000053e02008041000000c002200210000000000112019f00000577011001c70000055f064001970000055f075001970000800d0200003900000004030000390000057804000041000000120500002914f4136b0000040f000000010020019000000a6b0000613d0000000101000039000000000011041b000009260000013d000000120100002900000000020104330000000f0100002900000020011000390000000001010433000000400500043d000005840300004100000000003504350000000403500039000000000013043500000000010004140000055f02200197000000040020008c000008d60000613d00000024040000390000000003050019000f00000005001d0000000f0500002914f40dfb0000040f0000000f05000029000000000001004b000007ee0000613d000108d80000003d000013850000013d000005730020009c000008180000213d0000000100300190000008180000c13d000000400020043f000005760010009c00000a6b0000213d000000200010008c000003210000813d00000a6b0000013d000000400700043d0000004001200039000000000301043300000000010504330000055f0210019800000a1c0000c13d0000000001000414000000040040008c00000a8b0000c13d000000010100003900000b040000013d0000004401300039000005b1020000410000000000210435000000240130003900000003020000390000000000210435000005630100004100000000001304350000000401300039000000200200003900000000002104350000006402000039000014b20000013d000000010130008a000000000032004b00000a440000c13d000005ab0230009a000000000002041b000000000014041b0000001301000029000000000010043f000000a301000039000109050000003d000013be0000013d000000000001041b000000400100043d0000053e0010009c0000053e01008041000000400110021000000000020004140000053e0020009c0000053e02008041000000c002200210000000000112019f0000056d011001c70000800d0200003900000003030000390000056e040000410000001305000029000002900000013d0000053e0030009c0000053e03008041000000400130021000000000020004140000053e0020009c0000053e02008041000000c002200210000000000112019f0000056d011001c70000800d02000039000000030300003900000001060000390000056e04000041000000130500002914f4136b0000040f000000010020019000000a6b0000613d000000400100043d0000000002000019000000000300001914f4132f0000040f0001092c0000003d000013850000013d000005730020009c000008180000213d0000000100300190000008180000c13d000000400020043f000005760010009c00000a6b0000213d000000200010008c00000a6b0000413d00000000010504330000059f0010009c000109390000003d000014be0000013d0000053e0010009c001200000001001d0000053e01008041000000400110021000000000020004140000053e0020009c0000053e02008041000000c002200210000000000112019f0000056d011001c70000800d020000390000000203000039000005a304000041000000130500002914f4136b0000040f000000010020019000000a6b0000613d0000001201000029000005790010009c0000001303000029000008180000213d00000012040000290000006001400039000000400010043f0000004001400039000005a40200004100000000002104350000002001400039000005a502000041000000000021043500000027010000390000000000140435000000110100002900000000040104330000000001000414000000040030008c00000bf40000c13d000000010100003900000bf80000013d000000400500043d0000001101500029000000000051004b00000000020000390000000102004039000005730010009c000008180000213d0000000100200190000008180000c13d000000400010043f0000000f0100002900000000061504360000000001000019000000400400043d000000120010006c000000200740003900000acc0000813d000005790040009c000008180000213d0000006002400039000000400020043f00000040024000390000000000020435000000000007043500000000000404350000000002610019000000000042043500000020011000390000096d0000013d0000053e0030009c0000053e0300804100000040023002100000053e0010009c0000053e01008041000000c001100210000000000121019f0000056d011001c70000800902000039000005b003000041000000000500001914f4136b0000040f00000060031002700001053e0030019d0003000000010355000000010120018f001100000001001d14f40fbd0000040f000000110100002914f411380000040f000005b201000041000000000010043f0000009d01000039000000200010043f000005b30100004114f410d40000040f000000e0011000390000000001010433000000030010008c000006390000213d00000a940000c13d000005b201000041000000000010043f0000009e01000039000000200010043f000005b50100004114f4110b0000040f000005b202000041000000000020043f000000a402000039000000200020043f001000000001001d000005b60100004114f411230000040f000000400400043d000000040240003900000020011000390000000001010433000000060010008c00000ae60000c13d00000012010000290000000003010433000005840100004100000000001404350000000601000039000000000012043500000000010004140000055f02300197000000040020008c001100000004001d000009c00000613d00000024040000390000001103000029000000000503001914f40dfb0000040f000000000001004b000007ee0000613d0000000101000031000f00000001001d0000001f01100039000000200200008a000000000121016f00000011030000290000001102100029000d00000001001d000000000012004b00000000010000390000000101004039000e00000002001d000005730020009c000008180000213d0000000100100190000008180000c13d0000000e01000029000000400010043f0000000f01000029000005760010009c00000a6b0000213d0000000f01000029000000200010008c00000a6b0000413d0000000001030433000000070010008c00000c290000c13d000000100100002900000020011000390000000001010433001100000001001d00000012010000290000000001010433001200000001001d0018055f0010019b000109e50000003d0000149c0000013d000000180440008a0000000504400210000005600200004114f4134d0000040f000000000001004b000000000400041000000a6b0000613d00000012010000290000055f021001970000000e0500002900000044015000390000000703000039000000000031043500000011010000290000055f01100197000000240350003900000000001304350000057e0100004100000000001504350000055f01400197000000040350003900000000001304350000000001000414000000040020008c00000daa0000613d00000064040000390000000e030000290000000005030019000000000600001914f40dd70000040f000f000100000035000000000001004b00000da60000c13d0000000303000367000000200100008a0000000f0200002900000000041201700000001f0520018f000000400100043d000000000241001900000a140000613d000000000603034f0000000007010019000000006806043c0000000007870436000000000027004b00000a100000c13d000000000005004b00000a1a0000613d000000000343034f000000030450021000010a1a0000003d000014230000013d0000000f0200002914f413270000040f0000002401700039000000000031043500000587010000410000000000170435000000040170003900000000004104350000000001000414000000040020008c00000a2e0000613d0000004404000039000000200600003900000000030700190000000005070019000600000007001d14f40dd70000040f0000000607000029000000000001004b000007ee0000613d00000001010000310000001f02100039000000200300008a000000000332016f000000000273001900010a350000003d0000142d0000013d000005730020009c000008180000213d0000000100300190000008180000c13d000000400020043f000005760010009c00000a6b0000213d000000200010008c00000a6b0000413d000000000107043300010a410000003d000014b40000013d000500000000001d000007470000613d00000a6b0000013d000000000012004b00000bf00000a13d000005ab0120009a000000000101041a000005ab0230009a000000000012041b000000000010043f000000a301000039000000200010043f00000040020000390000000001000019001200000003001d14f413390000040f000000a2040000390000001202000029000000000021041b000000000304041a000000000003004b00000af30000c13d000005a901000041000000000010043f00000031010000390000081b0000013d00000001020000310000001f01200039000000200300008a000000000631016f0000000003560019000000000063004b00000000010000390000000101004039000005730030009c000008180000213d0000000100100190000008180000c13d000f00000003001d000000400030043f000005760020009c00000b130000a13d000014a80000013d000000400500043d000005750100004100000000001504350000000001000414000000040020008c00000a7a0000613d00000004040000390000000003050019001300000005001d000000130500002914f40dfb0000040f0000001305000029000000000001004b000007ee0000613d00010a7c0000003d000013850000013d000005730020009c000008180000213d0000000100300190000008180000c13d000000400020043f000005760010009c00000a6b0000213d000000200010008c00000a6b0000413d00000000010504330000055f0010009c00000a6b0000213d00010a8a0000003d000014790000013d000004a20000013d000000000003004b00000af50000c13d0000000002040019000000000307001900000000040000190000000005000019000000000600001914f40dd70000040f00000b040000013d000000400100043d0000004402100039000005b403000041000001800000013d000000a102000039000000000102041a000005640110019700000013011001af000000000012041b0000009f02000039000000000102041a000005640110019700010aa20000003d0000146b0000013d000005650020009c000008180000213d0000004001200039000000400010043f0000000e0100003900000000031204360000056601000041001300000003001d0000000000130435000000400300043d000005650030009c000008180000213d00010ab00000003d000014900000013d000005670100004100010ab30000003d000013a10000013d000005680200004100010ab60000003d000014070000013d000005690300004100000000003104350000056a0020009c000008180000213d00010abc0000003d000014aa0000013d000005690200004100010abf0000003d000013cb0000013d00000000010004150000000f020000290000046f0000013d000000400100043d00000064021000390000056103000041000000000032043500000044021000390000056203000041000000000032043500000024021000390000002e03000039000008430000013d0000001101400029000000000041004b00000000020000390000000102004039000005730010009c000008180000213d0000000100200190000008180000c13d000000400010043f0000000f0100002900000000001404350000000001000019000000120010006c00000bb30000813d000000400200043d000005650020009c000008180000213d0000004003200039000000400030043f00000020032000390000000000030435000000000002043500000000037100190000000000230435000000200110003900000ad80000013d00000563010000410000000000140435000000200100003900000000001204350000004401400039000005b70200004100000000002104350000002401400039000000010200003900000000002104350000006402000039000000000104001914f413270000040f000000010130008a000008fd0000013d0000053e0070009c0000053e0700804100000040027002100000053e0010009c0000053e01008041000000c001100210000000000121019f0000056d011001c70000800902000039000000000500001914f4136b0000040f00000060031002700001053e0030019d0003000000010355000000010120018f000600000001001d14f40fbd0000040f000000060000006b000500000000001d000007470000c13d000000400100043d00000064021000390000058f03000041000000000032043500000044021000390000059003000041000000000032043500000024021000390000002b03000039000008430000013d000000a001000039000000000101041a0000000e030000290000004003300039000d00000003001d0000000007030433000000000007004b00000b1f0000613d000000010300008a00000000037300d9000000000013004b000008360000413d00000000017100a9000a00000001001d000c2710001001220000000c0370006c000008360000413d00000012050000290000006001500039000800000001001d00000000010104330000055f041001970000002001500039000900000001001d00000000010104330000055f0510019800000bff0000c13d0000000001000414000000040040008c00000c360000c13d000000010100003900000cc10000013d0000000003010019000000400400043d00000044014000390000000f02000029000000000021043500000000010004100000055f011001970000002402400039000000000012043500000591010000410000000000140435000f00000004001d0000000401400039000000120200002900000000002104350000000001000414000000040030008c00000b4b0000613d00000064040000390000002006000039000000000203001900010b4a0000003d000014b90000013d000007ee0000613d00010b4d0000003d000014d10000013d00010b4f0000003d0000142d0000013d000005730020009c000008180000213d0000000100300190000008180000c13d000000400020043f000005760010009c00000a6b0000213d000000200010008c00000a6b0000413d0000000f01000029000000000101043300010b5c0000003d000014b40000013d00000a6b0000c13d000000080000006b0000001101000029001200a00010003d00000b660000c13d0000001101000029000000c0011000390000000001010433000000000001004b00000c3f0000c13d00000002010003670000000902100360000000000602043b0000055f0060009c00000a6b0000213d0000000e01100360000000000101043b0000000b0200002900000000020204330000001103000029000000000303043300000012040000290000000004040433000000400500043d000000a007500039000000000027043500000080025000390000000d0700002900000000007204350000000a07000029000000100070006c000000000200003900000001020020390000006007500039000000000027043500000040025000390000000000120435000000200150003900000000004104350000055f0130019700000000001504350000053e0050009c0000053e05008041000000400150021000000000020004140000053e0020009c0000053e02008041000000c002200210000000000112019f00000594011001c70000800d02000039000000040300003900000595040000410000001305000029000000050700002914f4136b0000040f000000010020019000000a6b0000613d0000000a02000029000000100020006c000008bd0000a13d00000012010000290000000006010433000000110100002900000000020104330000000b010000290000000001010433000000400300043d00000020043000390000000000140435000000070100002900000000001304350000053e0030009c0000053e03008041000000400130021000000000030004140000053e0030009c0000053e03008041000000c003300210000000000113019f00000596011001c70000055f072001970000800d02000039000000040300003900000597040000410000001305000029000008ba0000013d0000000003000019000d00000004001d000c00000005001d000b00000006001d000a00000007001d0000000f0030006c0000009d0200003900000cdb0000813d0000000504300210001100000004001d0000000e014000290000000201100367000000000101043b001300000001001d000000000010043f000000200020043f00000000010000190000004002000039001200000003001d00010bc80000003d000014e10000013d001000000001001d00010bcb0000003d000014dc0000013d00010bcd0000003d0000147e0000013d14f411230000040f00000011080000290000001203000029000000800200043d000000000032004b0000000d040000290000000c050000290000000b060000290000000a0700002900000bf00000a13d000000a00280003900000010090000290000000000920435000000800200043d000000000032004b00000bf00000a13d0000000002050433000000000032004b00000bf00000a13d0000000002680019000000130900002900000000009204350000000002050433000000000032004b00000bf00000a13d0000000002040433000000000032004b00000bf00000a13d0000000002780019000000000012043500000001013000390000000002040433000000000032004b000000000301001900000bb80000213d000005a901000041000000000010043f00000032010000390000081b0000013d00000011020000290000002003200039000000130200002914f40e1e0000040f001100000001001d14f40fbd0000040f000000000301001900000013010000290000001102000029000000120400002900000c270000013d0000000f070000290000002401700039000000000031043500000587010000410000000000170435000000040170003900000000004104350000000001000414000000040050008c00000c720000613d0000004404000039000000200600003900000000020500190000000f03000029000000000503001914f40dd70000040f0000000102000031000000000001004b00000c6f0000c13d0000000304000367000000200100008a00010c160000003d000014740000013d000007fa0000613d000000000704034f0000000008010019000000007907043c0000000008980436000000000038004b00000c190000c13d000007fa0000013d0000001302000029000000100300002914f40e1e0000040f001200000001001d14f40fbd0000040f000000000301001900000013010000290000001202000029000000110400002914f40feb0000040f000009260000013d0000000e010000290000004403100039000005b8020000410000000000230435000000240310003900000001020000390000000000230435000005630200004100000000002104350000000403100039000000200200003900000000002304350000086b0000013d0000000c0070006c00000cb10000c13d00000000020400190000000f0300002900000000040000190000000005000019000000000600001914f40dd70000040f00000cc10000013d0000001301000029000000000010043f000000a40100003900010c440000003d000013be0000013d14f411230000040f00000000020004100000055f03200197000000400200043d000f00000002001d0000000404200039000000110200002900000000020204330000055f022001970000000015010434000000000005004b00000d280000c13d00000593010000410000000f05000029000000000015043500000000003404350000000001000414000000040020008c00000c5c0000613d0000002404000039000000200600003900010c5b0000003d000014b90000013d000007ee0000613d00010c5e0000003d000014d10000013d00010c600000003d0000142d0000013d000005730020009c000008180000213d0000000100300190000008180000c13d000000400020043f000005760010009c00000a6b0000213d000000200010008c00000a6b0000413d0000000f0100002900000000020104330000001201000029000f00000002001d000000000021043500000d470000013d0000001f01200039000000200300008a000000000631016f0000000f03600029000000000063004b00000000010000390000000101004039000700000003001d000005730030009c000008180000213d0000000100100190000008180000c13d0000000701000029000000400010043f000005760020009c00000a6b0000213d000000200020008c00000a6b0000413d0000000f010000290000000001010433000000000001004b0000000003000039000000010300c039000000000031004b00000a6b0000c13d0000000a01000029000027100010008c00000d640000413d00000009010000290000000003010433000000a101000039000000000101041a000000070700002900000024047000390000000c0500002900000000005404350000058704000041000000000047043500000004047000390000055f01100197000000000014043500000000010004140000055f03300197000000040030008c00000dbd0000613d0000004404000039000000200600003900000000020300190000000703000029000000000503001914f40dd70000040f0000000102000031000000000001004b00000dba0000c13d0000000304000367000000200100008a00010ca90000003d000014740000013d000007fa0000613d000000000704034f0000000008010019000000007907043c0000000008980436000000000038004b00000cac0000c13d000007fa0000013d0000000f020000290000053e0020009c0000053e0200804100000040022002100000053e0010009c0000053e01008041000000c001100210000000000121019f0000056d011001c70000800902000039000000000500001914f4136b0000040f00000060031002700001053e0030019d0003000000010355000000010120018f000f00000001001d14f40fbd0000040f0000000f0000006b00000ccf0000c13d000000400100043d00000064021000390000058a03000041000000000032043500000044021000390000058b03000041000000000032043500000024021000390000003403000039000008430000013d0000000a01000029000027100010008c00000d640000413d000000400200043d000000a101000039000000000301041a00000000010004140000055f04300197000000040040008c00000d500000c13d000000010100003900000d600000013d000000400200043d00000060010000390000000001120436000e00000001001d0000006001200039000000800300043d001000000003001d0000000000310435001300800000003d000f00000002001d00000080042000390000000002000019001200000002001d000000100020006c00000cf60000813d00000013010000290000002001100039001300000001001d00000000010104330000000002040019001100000004001d14f40eb30000040f000000110400002900000012020000290000000102200039000001000440003900000ce70000013d0000000f0140006a0000000e0200002900000000001204350000000c080000290000000003080433000000000234043600000000040000190000002009200039000000000034004b00000d0f0000813d0000002008800039000000000508043300000000760504340000055f06600197000000000062043500000000060704330000055f06600197000000000069043500000040015000390000000001010433000000400520003900000000001504350000000104400039000000600220003900000cfd0000013d0000000f010000290000000003120049000000400410003900000000003404350000000d06000029000000000306043300000000003204350000000002000019000000000032004b00000d250000813d000000200660003900000000040604330000000054040434000000000004004b0000000004000039000000010400c0390000000004490436000000000505043300000000005404350000000102200039000000400990003900000d170000013d0000000f010000290000000002190049000009280000013d000000000101043300000592050000410000000f0600002900000000005604350000000000140435000000240160003900000000003104350000000001000414000000040020008c00000d370000613d0000004404000039000000200600003900010d360000003d000014b90000013d000007ee0000613d00010d390000003d000014d10000013d00010d3b0000003d0000142d0000013d000005730020009c000008180000213d0000000100300190000008180000c13d000000400020043f000005760010009c00000a6b0000213d000000200010008c00000a6b0000413d00000012010000290000000001010433000f00000001001d0000001301000029000000000010043f0000009d0100003900010d4c0000003d000013be0000013d00000005011000390000000f02000029000000000021041b00000b660000013d0000053e0020009c0000053e0200804100000040022002100000053e0010009c0000053e01008041000000c001100210000000000121019f0000056d011001c700008009020000390000000c03000029000000000500001914f4136b0000040f00000060031002700001053e0030019d0003000000010355000000010120018f000f00000001001d14f40fbd0000040f0000000f0100002914f411380000040f000000a001000039000000000201041a000027100020008c000008360000213d0000001001000029000000000601043300000012010000290000004003100039000000000101043300000000030304330000000e040000290000000004040433000000080500002900000000050504330000000b070000290000000007070433000000090800002900000000080804330000000d0900002900000000090904330000271002200089000000400a00043d000000c00ba0003900000000002b0435000000a002a0003900000000009204350000055f028001970000008008a0003900000000002804350000055f027001970000006007a0003900000000002704350000055f025001970000004005a0003900000000002504350000055f024001970000002004a0003900000000002404350000055f0230019700000000002a04350000053e00a0009c0000053e0a0080410000004002a0021000000000030004140000053e0030009c0000053e03008041000000c003300210000000000223019f0000055f0710019700000588012001c70000800d0200003900000004030000390000058904000041000000130500002914f4136b0000040f000000010020019000000a6b0000613d00010d9f0000003d000014460000013d00000300022001bf000000000021041b0000000101000039000000000011041b000000000100041500000011020000290000046f0000013d0000000f010000290000001f01100039000000200200008a000d0000002101730000000d020000290000000e01200029000000000021004b00000000020000390000000102004039000005730010009c000008180000213d0000000100200190000008180000c13d000000400010043f0000000f01000029000005760010009c00000a6b0000213d000000000100041500000013020000290000046f0000013d0000001f01200039000000200300008a000000000631016f0000000701600029000000000061004b00000000030000390000000103004039000005730010009c000008180000213d0000000100300190000008180000c13d000000400010043f000005760020009c00000a6b0000213d000000200020008c00000a6b0000413d0000000701000029000000000101043300010dce0000003d000014b40000013d00000d640000613d00000a6b0000013d00000dd30000a13d000000000121001900000000000104350000001001000029000000110200002914f4116e0000040f000008bd0000013d0003000000000002000300000006001d000200000005001d0000053e0030009c0000053e0300804100000040033002100000053e0040009c0000053e040080410000006004400210000000000334019f0000053e0010009c0000053e01008041000000c001100210000000000113019f14f4136b0000040f000000020900002900000060031002700000053e03300197000000030030006c000000030400002900000000040340190000001f0540018f000005c006400198000000000469001900000df50000613d000000000701034f000000007807043c0000000009890436000000000049004b00000df10000c13d000000010220018f000000000005004b00000dfa0000613d00010dfa0000003d000014580000013d000014980000013d0002000000000002000200000005001d0000053e0030009c0000053e0300804100000040033002100000053e0040009c0000053e040080410000006004400210000000000334019f0000053e0010009c0000053e01008041000000c001100210000000000113019f14f413700000040f000000020900002900000060031002700000053e03300197000000200030008c000000200400003900000000040340190000001f0540018f0000002006400190000000000469001900000e180000613d000000000701034f000000007807043c0000000009890436000000000049004b00000e140000c13d000000010220018f000000000005004b00000e1d0000613d00010e1d0000003d000014580000013d000014980000013d0000053e0030009c0000053e0300804100000040033002100000053e0040009c0000053e040080410000006004400210000000000334019f0000053e0010009c0000053e01008041000000c001100210000000000113019f14f413750000040f00000060031002700001053e0030019d0003000000010355000000010120018f000000000001042d000005c10020009c00000e600000813d00000000040100190000001f01200039000000200600008a000000000161016f0000003f01100039000000000561016f000000400100043d0000000005510019000000000015004b00000000070000390000000107004039000005730050009c00000e600000213d000000010070019000000e600000c13d000000400050043f00000000052104360000000007420019000000000037004b00000e660000213d00000000066201700000001f0720018f0000000204400367000000000365001900000e500000613d000000000804034f0000000009050019000000008a08043c0000000009a90436000000000039004b00000e4c0000c13d000000000007004b00000e5d0000613d000000000464034f0000000306700210000000000703043300000000076701cf000000000767022f000000000404043b0000010006600089000000000464022f00000000046401cf000000000474019f000000000043043500000000022500190000000000020435000000000001042d000005a901000041000000000010043f0000004101000039000000040010043f000005aa01000041000014f600010430000014a80000013d000005760010009c00000e9f0000213d000001230010008c00000e9f0000a13d000000400100043d000005c20010009c00000ea00000813d0000010002100039000000400020043f00000002020003670000002403200370000000000303043b0000055f0030009c00000e9f0000213d00000000033104360000004404200370000000000404043b0000055f0040009c00000e9f0000213d00000000004304350000006403200370000000000303043b0000055f0030009c00000e9f0000213d000000400410003900000000003404350000008403200370000000000303043b0000055f0030009c00000e9f0000213d00000060041000390000000000340435000000a403200370000000000303043b00000080041000390000000000340435000000a003100039000000c404200370000000000404043b0000000000430435000000e403200370000000000303043b000000000003004b0000000004000039000000010400c039000000000043004b00000e9f0000c13d000000c00410003900000000003404350000010402200370000000000202043b000000030020008c00000e9f0000213d000000e0031000390000000000230435000000000001042d000014a80000013d000005a901000041000000000010043f0000004101000039000000040010043f000005aa01000041000014f600010430000005760010009c00000eb20000213d000000430010008c00000eb20000a13d00000002010003670000002402100370000000000202043b0000055f0020009c00000eb20000213d0000000401100370000000000101043b000000000001042d000014a80000013d00000000430104340000055f03300197000000000332043600000000040404330000055f044001970000000000430435000000400310003900000000030304330000055f0330019700000040042000390000000000340435000000600310003900000000030304330000055f03300197000000600420003900000000003404350000008003100039000000000303043300000080042000390000000000340435000000a0031000390000000003030433000000a0042000390000000000340435000000c003200039000000c0041000390000000004040433000000000004004b0000000004000039000000010400c0390000000000430435000000e0011000390000000001010433000000040010008c00000ed90000813d000000e0022000390000000000120435000000000001042d000005a901000041000000000010043f0000002101000039000000040010043f000005aa01000041000014f600010430000005760010009c00000efa0000213d000001430010008c00000efa0000a13d00000002040003670000010402400370000000000202043b000005730020009c00000efa0000213d0000002303200039000000000013004b00000efa0000813d0000000403200039000000000334034f000000000303043b000005730030009c00000efa0000213d00000024022000390000000005230019000000000015004b00000efa0000213d0000012401400370000000000401043b0000055f0040009c00000efa0000213d0000000401000039000000000001042d000014a80000013d00010000000000020000055f02200197000000000020043f00010f000000003d000013be0000013d000000000001042d0000001f03100039000000000023004b00000000040000190000057c040040410000057c052001970000057c03300197000000000653013f000000000053004b00000000030000190000057c030020410000057c0060009c000000000304c019000000000003004b00000f350000613d0000000203000367000000000413034f000000000504043b000005c10050009c00000f2f0000813d00000005065002100000003f046000390000059b07400197000000400400043d0000000007740019000000000047004b00000000080000390000000108004039000005730070009c00000f2f0000213d000000010080019000000f2f0000c13d000000400070043f000000000054043500000000056100190000002005500039000000000025004b00000f350000213d0000002001100039000000000051004b00000f2e0000813d000000000213034f000000000202043b0000002004400039000000000024043500000f260000013d000000000001042d000005a901000041000000000010043f0000004101000039000000040010043f000005aa01000041000014f600010430000014a80000013d0000006a01000039000000000101041a0000055f011001970000000002000411000000000021004b00000f3d0000c13d000000000001042d000000400100043d0000004402100039000005c30300004100000000003204350000056302000041000000000021043500000024021000390000002003000039000000000032043500000004021000390000000000320435000000640200003914f413270000040f00000000060100190000055f011001970000006a02000039000000000302041a0000056404300197000000000114019f000000000012041b000000400100043d0000053e0010009c0000053e01008041000000400110021000000000020004140000053e0020009c0000053e02008041000000c002200210000000000112019f0000055f053001970000056d011001c70000800d0200003900000003030000390000059a0400004114f4136b0000040f000000010020019000000f630000613d000000000001042d000014a80000013d000000000001004b00000f670000613d000000000001042d000000400100043d0000006402100039000005c40300004100000000003204350000004402100039000005c503000041000000000032043500000024021000390000002c03000039000000000032043500000563020000410000139b0000013d000000000001004b00000f760000613d000000000001042d000000400100043d0000006402100039000005c60300004100000000003204350000004402100039000005c503000041000000000032043500000024021000390000002c03000039000000000032043500000563020000410000139b0000013d000000000001004b00000f850000613d000000000001042d000000400100043d0000006402100039000005c70300004100000000003204350000004402100039000005c803000041000000000032043500000024021000390000002903000039000000000032043500000563020000410000139b0000013d0000006002100039000005c90300004100000000003204350000004002100039000005ca03000041000000000032043500000020021000390000002e030000390000000000320435000000200200003900000000002104350000008001100039000000000001042d0003000000000002000200000001001d000300000001001d00010fa30000003d0000149c0000013d000000030440008a0000000504400210000005600200004114f4134d0000040f000000000001004b00000fb10000613d00000002010000290000055f011001970000059f02000041000000000302041a0000056403300197000000000113019f000000000012041b000000000001042d000000400100043d0000006402100039000005cb0300004100000000003204350000004402100039000005cc03000041000000000032043500000024021000390000002d03000039000000000032043500000563020000410000139b0000013d0001000000000002000000010200003200000fe30000613d000005c10020009c00000fe50000813d0000001f01200039000000200300008a000000000131016f0000003f01100039000000000431016f000000400100043d0000000004410019000000000014004b00000000050000390000000105004039000005730040009c00000fe50000213d000000010050019000000fe50000c13d000000400040043f000000000621043600000000033201700000001f0420018f0000000002360019000000030500036700000fdc0000613d000000000705034f000000007807043c0000000006860436000000000026004b00000fd80000c13d000000000004004b00000fe40000613d000000000335034f000000030440021000010fe20000003d000014230000013d000000000001042d0000006001000039000000000001042d000005a901000041000000000010043f0000004101000039000000040010043f000005aa01000041000014f6000104300004000000000002000000000603001900000000050200190000000032030434000000000005004b000010000000613d000000000002004b00000ffe0000c13d000400000001001d00010ff60000003d0000149c0000013d000000040440008a00000005044002100000056002000041000300000006001d14f4134d0000040f0000000306000029000000000001004b000010170000613d0000000001060019000000000001042d000000000002004b000010160000c13d000000400500043d000300000005001d0000056301000041000000000015043500000004015000390000002002000039000000000021043500000024025000390000000013040434000200000003001d0000000000320435000000440250003914f410200000040f00000002010000290000001f01100039000000200200008a000000000121016f0000004402100039000000030100002914f413270000040f000014b20000013d000000400100043d0000004402100039000005cd03000041000000000032043500000024021000390000001d0300003900000000003204350000056302000041000013950000013d0000000004000019000000000034004b000010290000813d00000000052400190000000006140019000000000606043300000000006504350000002004400039000010210000013d0000102c0000a13d00000000012300190000000000010435000000000001042d000000000001004b000010300000613d000000000001042d000000400100043d0000006402100039000005ce0300004100000000003204350000004402100039000005cf03000041000000000032043500000024021000390000002b03000039000000000032043500000563020000410000139b0000013d0003000000000002000300000001001d000110400000003d000014870000013d0000000001000019000010430000613d000000000001042d000000a3050000390000000304000029000000a201000039000000000201041a000005730020009c000010580000213d0000000103200039000000000031041b000005d00220009a000000000042041b000000000101041a000200000001001d000000000040043f000000200050043f0000004002000039000000000100001914f413390000040f0000000202000029000000000021041b0000000101000039000000000001042d000005a901000041000000000010043f0000004101000039000000040010043f000005aa01000041000014f600010430000000000001004b000010610000613d000000000001042d000000400100043d0000006402100039000005d10300004100000000003204350000004402100039000005d203000041000000000032043500000024021000390000002203000039000000000032043500000563020000410000139b0000013d0000000101000039000000000201041a000000020020008c000010740000613d0000000202000039000000000021041b000000000001042d000000400100043d0000004402100039000005d303000041000000000032043500000024021000390000001f0300003900000000003204350000056302000041000013950000013d000000000001004b000010800000613d000000000001042d000000400100043d0000004402100039000005d403000041000000000032043500000024021000390000000f0300003900000000003204350000056302000041000013950000013d00000000430204340000055f03300197000000000501041a0000056405500197000000000335019f000000000031041b00000000030404330000055f033001970000000104100039000000000504041a0000056405500197000000000335019f000000000034041b000000400320003900000000030304330000055f033001970000000204100039000000000504041a0000056405500197000000000335019f000000000034041b000000600320003900000000030304330000055f033001970000000304100039000000000504041a0000056405500197000000000335019f000000000034041b000000800320003900000000030304330000000404100039000000000034041b000000a00320003900000000030304330000000504100039000000000034041b0000000601100039000001000300008a000000000401041a000000000334016f000000c0042000390000000004040433000000000004004b000000010330c1bf000000000031041b000000e0022000390000000002020433000000040020008c000010c20000813d0000ffff0400008a000000000343016f00000008022002100000ff000220018f000000000232019f000000000021041b000000000001042d000005a901000041000000000010043f0000002101000039000000040010043f000005aa01000041000014f600010430000000000001004b000010cb0000613d000000000001042d000000400100043d0000004402100039000005d50300004100000000003204350000002402100039000000080300003900000000003204350000056302000041000013950000013d0000000002010019000000400100043d000005c20010009c000011010000813d0000010003100039000000400030043f000000000302041a0000055f0330019700000000033104360000000104200039000000000404041a0000055f0440019700000000004304350000000203200039000000000303041a0000055f03300197000000400410003900000000003404350000000303200039000000000303041a0000055f03300197000000600410003900000000003404350000000403200039000000000303041a000000800410003900000000003404350000000503200039000000000303041a000000a0041000390000000000340435000000c0031000390000000602200039000000000202041a000000ff002001900000000004000039000000010400c03900000000004304350000000802200270000000ff0220018f000000040020008c000011050000813d000000e0031000390000000000230435000000000001042d000005a901000041000000000010043f0000004101000039000011080000013d000005a901000041000000000010043f0000002101000039000000040010043f000005aa01000041000014f6000104300000000002010019000000400100043d000005d60010009c0000111d0000813d0000006003100039000000400030043f000000000302041a0000055f0330019700000000033104360000000104200039000000000404041a0000055f0440019700000000004304350000000202200039000000000202041a00000040031000390000000000230435000000000001042d000005a901000041000000000010043f0000004101000039000000040010043f000005aa01000041000014f6000104300000000002010019000000400100043d000005d70010009c000011320000813d0000004003100039000000400030043f000000000302041a000000ff003001900000000003000039000000010300c03900000000033104360000000102200039000000000202041a0000000000230435000000000001042d000005a901000041000000000010043f0000004101000039000000040010043f000005aa01000041000014f600010430000000000001004b0000113b0000613d000000000001042d000000400100043d0000006402100039000005d803000041000000000032043500000044021000390000058b03000041000000000032043500000024021000390000002b03000039000000000032043500000563020000410000139b0000013d000000000001004b0000114a0000613d000000000001042d000000400100043d0000004402100039000005d90300004100000000003204350000002402100039000000110300003900000000003204350000056302000041000013950000013d000000400100043d000005c20010009c000011680000813d0000010002100039000000400020043f000000e0021000390000000000020435000000c0021000390000000000020435000000a0021000390000000000020435000000800210003900000000000204350000006002100039000000000002043500000040021000390000000000020435000000200210003900000000000204350000000000010435000000000001042d000005a901000041000000000010043f0000004101000039000000040010043f000005aa01000041000014f6000104300003000000000002000300000002001d000200000001001d000000000010043f0000009d01000039000111750000003d000014d70000013d0000000601100039000000000101041a0000000801100270000000ff0110018f000000040010008c000011b50000813d000000000001004b0000000001000039000000010100603914f4107d0000040f0000000303000029000000e00130003900000001020000390000000000210435000000c00130003900000000000104350000000201000029000000000010043f0000009d010000390001118a0000003d000013be0000013d000000030200002914f410890000040f0000000306000029000000800160003900000060026000390000002003600039000000a0046000390000004005600039000000000706043300000000050504330000000004040433000000000303043300000000020204330000000001010433000000400600043d000000600860003900000000001804350000055f01200197000000400260003900000000001204350000055f013001970000002002600039000000000012043500000000004604350000053e0060009c0000053e06008041000000400160021000000000020004140000053e0020009c0000053e02008041000000c002200210000000000112019f00000577011001c70000055f065001970000055f077001970000800d0200003900000004030000390000057804000041000000020500002914f4136b0000040f0000000100200190000011bb0000613d000000000001042d000005a901000041000000000010043f0000002101000039000000040010043f000005aa01000041000014f600010430000014a80000013d00080000000000020000000008010019000000e0011000390000000204000367000000000114034f000000000701043b000005da0070009c000012630000813d000400000002001d000500000003001d000000400900043d0000002001900039000005db050000410000000000510435000000000584034f000000000505043b000000400690003900000000005604350000002005800039000000000554034f000000000505043b000000600690003900000000005604350000004005800039000000000554034f000000000505043b000000800690003900000000005604350000006005800039000000000554034f000000000505043b000000a00690003900000000005604350000008005800039000000000554034f000000000505043b000000c0069000390000000000560435000000a005800039000000000554034f000000000505043b000000e0069000390000000000560435000000c002800039000000000224034f000000000202043b000001200490003900000000007404350000010003900039000000000023043500000120020000390000000000290435000005dc0090009c0000125d0000813d0000014002900039000700000002001d000000400020043f000200000009001d000000000209043314f413390000040f000300000001001d0000003401000039000000000101041a000600000001001d0000800b0100003900000004030000390000000004000415000000080440008a0000000504400210000005680200004114f4134d0000040f000000060010006c000012090000c13d0000003301000039000000000101041a0000000704000029000012270000013d0000003702000039000000000202041a0000003503000039000000000303041a0000003604000039000000000404041a0000000207000029000001e00570003900000000060004100000000000650435000001c0057000390000000000150435000001a00170003900000000004104350000018001700039000000000031043500000160017000390000000000210435000000a00200003900000007030000290000000000230435000005dd0070009c0000125d0000213d00000000020300190000020003700039000600000003001d000000400030043f000000000202043314f413390000040f00000006040000290000004202400039000000030300002900000000003204350000002003400039000005de0200004100000000002304350000002202400039000000000012043500000042010000390000000000140435000005820040009c0000125d0000213d0000008001400039000000400010043f0000000002040433000000000103001914f413390000040f000700000001001d00000000030000310000000401000029000000050200002914f40e2f0000040f000000400300043d0000000024010434000000410040008c000012640000c13d00000040041000390000000004040433000005e00040009c000012710000213d0000006001100039000000000101043300000000020204330000006005300039000000000045043500000040043000390000000000240435000000f8011002700000002002300039000000000012043500000007010000290000000000130435000000000000043f000000000100041400000001020000390000008004000039000000000500001914f40dfb0000040f000000000001004b000012810000613d000000000100043d0000055f00100198000012920000613d000000000001042d000005a901000041000000000010043f0000004101000039000000040010043f000005aa01000041000014f600010430000014a80000013d0000004401300039000005df02000041000000000021043500000024013000390000001f020000390000000000210435000005630100004100000000001304350000000401300039000000200200003900000000002104350000006402000039000012800000013d0000006401300039000005e20200004100000000002104350000004401300039000005e3020000410000000000210435000000240130003900000022020000390000000000210435000005630100004100000000001304350000000401300039000000200200003900000000002104350000008402000039000014b20000013d0000000304000367000000200100008a0000000102000031000112860000003d000014740000013d0000128d0000613d000000000704034f0000000008010019000000007907043c0000000008980436000000000038004b000012890000c13d000000000006004b000012910000613d000112910000003d0000143a0000013d14f413270000040f000000400100043d0000004402100039000005e10300004100000000003204350000002402100039000000180300003900000000003204350000056302000041000013950000013d0006000000000002000500000003001d000400e00020003d00000002020003670000000403200360000000000303043b000005da0030009c000012f30000813d000200000001001d00030000000203530000055f02500197000000000032004b000012f40000c13d0000055f01400197000112ab0000003d000014870000013d000012fb0000613d000000050100002900000000010104330000055f00100198000012b90000c13d0000000402000029000000c00120008a000000030110035f000000a00220008a000000030220035f000000000202043b000000000101043b000000000021004b000013160000413d0000800b0100003900000004030000390000000004000415000000060440008a0000000504400210000005830200004114f4134d0000040f0000000402000029000000600220008a000000030600035f000000000326034f000000000303043b000000000013004b000013020000413d000000200120008a000000000216034f000000000202043b000000010220008a000000020020006c000013090000413d0000006001100039000000000316034f000000050200002900000040022000390000000002020433000000000303043b000000000003004b000012ed0000613d000000000002004b000000010400008a000012db0000613d00000000052400d9000000000035004b000013100000413d00000000033200a9000027100330011a000000000443013f000000000042004b000013100000213d0000000002230019000000a00110008a000000000116034f000000000101043b000000000021004b000012f20000813d000000400100043d0000004402100039000005e503000041000000000032043500000024021000390000001c03000039000013230000013d000000a00110008a000000000116034f000000000101043b000000000021004b0000131d0000a13d000000000001042d000014a80000013d000000400100043d0000004402100039000005e403000041000000000032043500000024021000390000001203000039000013230000013d000000400100043d0000004402100039000005ea03000041000000000032043500000024021000390000001903000039000013230000013d000000400100043d0000004402100039000005e803000041000000000032043500000024021000390000000d03000039000013230000013d000000400100043d0000004402100039000005e703000041000000000032043500000024021000390000001f03000039000013230000013d000005a901000041000000000010043f0000001101000039000000040010043f000005aa01000041000014f600010430000000400100043d0000004402100039000005e903000041000000000032043500000024021000390000001503000039000013230000013d000000400100043d0000004402100039000005e603000041000000000032043500000024021000390000000e0300003900000000003204350000056302000041000013950000013d000000000001042f0000053e0010009c0000053e0100804100000040011002100000053e0020009c0000053e020080410000006002200210000000000112019f000014f6000104300000053e0010009c0000053e0100804100000040011002100000053e0020009c0000053e020080410000006002200210000000000112019f000000e002300210000000000121019f000014f50001042e0000053e0010009c0000053e0100804100000040011002100000053e0020009c0000053e020080410000006002200210000000000112019f00000000020004140000053e0020009c0000053e02008041000000c002200210000000000112019f0000056d011001c7000080100200003914f413700000040f00000001002001900000134c0000613d000000000101043b000000000001042d000014a80000013d00000000050100190000000000200443000000050030008c0000135b0000413d000000040100003900000000020000190000000506200210000000000664001900000005066002700000000006060031000000000161043a0000000102200039000000000031004b000013530000413d0000053e0030009c0000053e03008041000000600130021000000000020004140000053e0020009c0000053e02008041000000c002200210000000000112019f000005eb011001c7000000000205001914f413700000040f00000001002001900000136a0000613d000000000101043b000000000001042d000000000001042f0000136e002104210000000102000039000000000001042d0000000002000019000000000001042d00001373002104230000000102000039000000000001042d0000000002000019000000000001042d00001378002104250000000102000039000000000001042d0000000002000019000000000001042d0000009d01000039000000200010043f0000004002000039000000000100001914f413390000040f0000000601100039000000000101041a0000000801100270000000ff0110018f000000030010008c000000010000013b00000001010000310000001f02100039000000200300008a000000000332016f0000000002530019000000000032004b00000000030000390000000103004039000000010000013b14f413390000040f0000000601100039000000000101041a0000000801100270000000ff0110018f000000030010008c000000010000013b0000000000210435000000040210003900000020030000390000000000320435000000640200003914f413270000040f0000000000210435000000040210003900000020030000390000000000320435000000840200003914f413270000040f000000000013043500000005010000390000000000140435000000000100041a0000000801100270000000ff0110018f000e00000002001d14f4102d0000040f0000000e010000290000000002010433000000130100002914f413390000040f00000010020000290000000002020433001300000001001d000000120100002914f413390000040f00000035020000390000001303000029000000000032041b001200000001001d0000003602000039000000000012041b0000800b01000039000000040300003900000000040004150000001a0440008a0000000504400210000000010000013b000000200010043f0000004002000039000000000100001914f413390000040f000000010000013b0000001301000029000000000010043f0000009d01000039000000200010043f0000004002000039000000000100001914f413390000040f000000010000013b000000000021041b000000000100041a0000000801100270000000ff0110018f001300000001001d14f4102d0000040f000000130100002914f4102d0000040f0000000101000039000000000011041b000000000100041a0000000801100270000000ff0110018f001300000001001d14f4102d0000040f000000130100002914f4102d0000040f000000000100041114f40f4a0000040f000000110100002914f40f4a0000040f000000010000013b000000000001004b0000000001000039000000010100603914f4107d0000040f0000001303000029000000e00130003900000001020000390000000000210435000000c00130003900000000002104350000001201000029000000000010043f0000009d01000039000000200010043f0000004002000039000000000100001914f413390000040f000000130200002914f410890000040f000000010000013b000000010010008c0000000001000039000000010100603914f410c80000040f14f4106d0000040f0000001301000029000000000010043f0000009d01000039000000200010043f0000004002000039000000000100001914f413390000040f14f410d40000040f0000001302000029000000000020043f0000009e02000039000000200020043f000000010000013b14f4134d0000040f0000003402000039000000000012041b000000400200043d00000040032000390000001304000029000000000043043500000060032000390000001204000029000000000043043500000080032000390000000000130435000000a00120003900000000030004100000000000310435000000a0010000390000000001120436000000010000013b000000000010043f0000009d01000039000000200010043f0000000001000019000000400200003914f413390000040f0000000201100039000000000201041a000000400100043d000000010000013b000000000502043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000320435000000010000013b000000000032004b00000000030000390000000103004039000000010000013b0000000001000412001a00000001001d001900000000003d0000800501000039000000440300003900000000040004150000001a0440008a0000000504400210000000010000013b000000000454034f0000000305600210000000000603043300000000065601cf000000000656022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000464019f0000000000430435000000010000013b0000001301000029000000000010043f0000009d01000039000000200010043f0000004002000039000000000100001914f413390000040f00000006011000390000ff010200008a000000000301041a000000000223016f000000010000013b000000200010043f0000004002000039000000000100001914f413390000040f000000000101041a000000010000013b000000000661034f0000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f0000000000540435000000010000013b0000000402300039000000000121034f000000000201043b000000240130003900000000030a001914f40e2f0000040f000000010000013b00000012011001af000000000012041b000001f401000039000000a002000039000000000012041b000000100100002914f4103c0000040f000000400200043d000000010000013b00000000051201700000001f0620018f000000400100043d0000000003510019000000010000013b0000000002000411000000000021004b00000000010000390000000101006039000000010000013b0000001302000029000000000020043f000000a402000039000000200020043f001300000001001d0000000001000019000000400200003914f413390000040f000000010000013b000000000010043f000000a301000039000000200010043f0000004002000039000000000100001914f413390000040f000000000101041a000000000001004b000000010000013b00000000010300190000000004030019001000000001001d0000004001100039000000400010043f0000002003300039001200000003001d000000010000013b000100000003001f00030000000103550000000001020019000000000001042d000080020100003900000024030000390000000004000415000000010000013b00000004040000390000000003050019001000000005001d000000100500002914f40dfb0000040f0000001005000029000000000001004b000000010000013b0000000001000019000014f600010430000000c003200039000000400030043f000000000202043314f413390000040f0000003302000039000000000012041b0000003701000039000000010000013b000000000103001914f413270000040f000000000001004b0000000002000039000000010200c039000000000021004b000000010000013b0000000f03000029000000000503001914f40dd70000040f000000000001004b000000010000013b0000000001000039000000010100603914f40f820000040f000000130100002914f40f9e0000040f000000400100043d000000010000013b0000000002000411000000000021004b0000000001000039000000010100603914f411470000040f0000001301000029000000000010043f0000009d01000039000000200010043f00000000010000190000004002000039000000010000013b00000001010000310000001f02100039000000200300008a000000000332016f0000000f02300029000000010000013b000000200010043f0000004002000039000000000100001914f413390000040f000000010000013b0000000001000019000000400200003914f413390000040f14f4110b0000040f000000010000013b14f413390000040f14f410d40000040f0000001302000029000000000020043f0000009e02000039000000200020043f000000010000013b000000010010008c0000000001000039000000010100603914f410c80000040f0000001301000029000000000010043f000000010000013b000000010010008c0000000001000039000000010100603914f410c80000040f000000010000013b000014f400000432000014f50001042e000014f600010430000000000000000000000000000000000000000000000000000000000000000000000000ffffffff000000020000000000000000000000000000008000000100000000000000000000000000000000000000000000000000000000000000000000000000fe1da514000000000000000000000000000000000000000000000000000000000e5a5abe00000000000000000000000000000000000000000000000000000000150b7a02000000000000000000000000000000000000000000000000000000002ea484ec000000000000000000000000000000000000000000000000000000003659cfe6000000000000000000000000000000000000000000000000000000003cecd7190000000000000000000000000000000000000000000000000000000046b060c30000000000000000000000000000000000000000000000000000000047e16c8c000000000000000000000000000000000000000000000000000000004f1ef28600000000000000000000000000000000000000000000000000000000526086370000000000000000000000000000000000000000000000000000000052d1902d0000000000000000000000000000000000000000000000000000000059faca2100000000000000000000000000000000000000000000000000000000715018a600000000000000000000000000000000000000000000000000000000786c58ae0000000000000000000000000000000000000000000000000000000078fe54c20000000000000000000000000000000000000000000000000000000086b265bd000000000000000000000000000000000000000000000000000000008821cb66000000000000000000000000000000000000000000000000000000008da5cb5b000000000000000000000000000000000000000000000000000000009c5c049200000000000000000000000000000000000000000000000000000000a293da0f00000000000000000000000000000000000000000000000000000000a335699900000000000000000000000000000000000000000000000000000000a7879b8400000000000000000000000000000000000000000000000000000000af42c72500000000000000000000000000000000000000000000000000000000bc197c8100000000000000000000000000000000000000000000000000000000d1add5cc00000000000000000000000000000000000000000000000000000000e25e37ee00000000000000000000000000000000000000000000000000000000f23a6e6100000000000000000000000000000000000000000000000000000000f2fde38b00000000000000000000000000000000000000000000000000000000f73bc2da00000000000000000000000000000000000000000000000000000000f8c8765e0000000000000000000000000000000000000000000000000000000001ffc9a7000000000000000000000000ffffffffffffffffffffffffffffffffffffffff1806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b83647920696e697469616c697a6564000000000000000000000000000000000000496e697469616c697a61626c653a20636f6e747261637420697320616c72656108c379a000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffbf41756374696f6e4d616e61676572000000000000000000000000000000000000312e302e300000000000000000000000000000000000000000000000000000009a8a0592ac89c5ad3bc6df8224c17b485976f597df104ee20d0df415241f670b8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f000000000000000000000000000000000000000000000000ffffffffffffff3f02000000000000000000000000000000000000200000000000000000000000007f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498020000000000000000000000000000000000000000000000000000000000000088d9d369733d630a0dbd71ed25dcafecbae7bc29d54a925afc1d003acf2af385416c72656164792061646465640000000000000000000000000000000000000043616e6e6f742073657420746f206e756c6c206164647265737300000000000064647265737300000000000000000000000000000000000000000000000000004f776e61626c653a206e6577206f776e657220697320746865207a65726f2061000000000000000000000000000000000000000000000000fffffffffffffffff23a6e61000000000000000000000000000000000000000000000000000000008da5cb5b000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0200000000000000000000000000000000000080000000000000000000000000c0f62773798a2ec429dfa963237b4bd66b86e98216edfc09ae708f416cd7fe60000000000000000000000000000000000000000000000000ffffffffffffff9fbc197c810000000000000000000000000000000000000000000000000000000047153f8200000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000052657365727665207072696365206d657420616c72656164790000000000000042842e0e000000000000000000000000000000000000000000000000000000007693239f56545420e68fbc8ea0002717610319c02cb2f63968af5dd44320daa638703bc9e5fbfe6a4ab89353328531fd2a9b9b0a4953c587bd38e559da9c29cfaaf4f58de99300cfadc4585755f376d5fa747d5bc561d5bd9d710de1f91bf42d000000000000000000000000000000000000000000000000ffffffffffffff7f796b89b91644bc98cd93958e4c9038275d622183e25ac5af08cc6b5d95539132fac70dc90000000000000000000000000000000000000000000000000000000076616c6964207265636569766572000000000000000000000000000000000000507265666572726564206e667420726563697069656e7420697320616e20696ea9059cbb0000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000e00000000000000000000000004718228cee25eb51eb8f330dd4e487e55149491fcfe67e307a03fcad7d3c7016746f207061796d656e7420726563697069656e740000000000000000000000004661696c656420746f2073656e64206e61746976652067617320746f6b656e2041756374696f6e206861736e277420656e6465640000000000000000000000004e6f742063757272656e742068696768657374206269646465720000000000004145156216647e79fe86353ad8b815cd10113e7a1180ef66755de417eb2871d768657374206269646465720000000000000000000000000000000000000000004661696c656420746f2073656e6420457468657220746f206c6173742068696723b872dd00000000000000000000000000000000000000000000000000000000b859c93500000000000000000000000000000000000000000000000000000000184a94d50000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000c000000000000000000000000017e4b9d4c680ca37a71a808246e11c4cb371e62cb506c776a0c9b6d7d4d819d202000000000000000000000000000000000000400000000000000000000000006ab786a8cf4920cec3e458b91fec01f279ad0217a8fe9c246af29d50a1f01591496e76616c6964206e61746976652067617320746f6b656e207061796d656e7441756374696f6e206578706972656400000000000000000000000000000000008be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e555550535570677261646561626c653a206d757374206e6f742062652063616c6c6564207468726f7567682064656c656761746563616c6c0000000000000000360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbcb2702a28e8e81585b75276ae753310056382a4745b72e8c683fe6089dc9c5f014910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd914352d1902d00000000000000000000000000000000000000000000000000000000bc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b206661696c656400000000000000000000000000000000000000000000000000416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c696400000000000000000000000000000000000000000000000000000000000043616e2774207570646174652061667465722066697273742076616c69642062a68c45bdaec70c5a58a1517b0185cd77e0eeadbfdba569eae9ed4fdb092627e54e487b71000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000550b0a72166cff30523ba7a8aa0c892a058b82a43a9e2a42628ef21e06e40bd44e6f7420646570726563617465640000000000000000000000000000000000003635643537656362626539653766323466383839393738340000000000000000591fa7911e1f6d5a563732de7cff70f7f8047fcc53b74b26060e8131664cdda73a8edbf3b52c2a2d5c54fc37c01f4c680327b5e9c27c899ecd5ceee1749fbd94000000000000000000000000000000000000000000000000006a94d74f430000612e35000000000000000000000000000000000000000000000000000000000036356435386265643437633835303063663766333836303100000000000000008b6c75899fe33db49914e1affe9c5304c150bb73dab92981f10ba1a7984ec31962000000000000000000000000000000000000000000000000000000000000003279400a5670ad04e85d93473fa3ea2055ceb9a3a7815930638b44b76e0515e8c3cbf4a62a73213c6ae33b6a471352958da8aeba802f8ddbe3e5fdae2d33c198630000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffdf150b7a020000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000001ffc9a7000000000000000000000000000000000000000000000000000000004e2312e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffe00000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000ffffffffffffff004f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657264656c656761746563616c6c000000000000000000000000000000000000000046756e6374696f6e206d7573742062652063616c6c6564207468726f756768206163746976652070726f787900000000000000000000000000000000000000006961626c6555554944000000000000000000000000000000000000000000000045524331393637557067726164653a20756e737570706f727465642070726f786f6e206973206e6f74205555505300000000000000000000000000000000000045524331393637557067726164653a206e657720696d706c656d656e746174696f74206120636f6e747261637400000000000000000000000000000000000000455243313936373a206e657720696d706c656d656e746174696f6e206973206e416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006e697469616c697a696e67000000000000000000000000000000000000000000496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069550b0a72166cff30523ba7a8aa0c892a058b82a43a9e2a42628ef21e06e40bd36f6e0000000000000000000000000000000000000000000000000000000000004e6f7420636f6c6c656374696f6e206f776e6572206f7220636f6c6c656374695265656e7472616e637947756172643a207265656e7472616e742063616c6c0041756374696f6e206964207573656400000000000000000000000000000000004e6f74206c697665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffa0000000000000000000000000000000000000000000000000ffffffffffffffc0746f20706c6174666f726d0000000000000000000000000000000000000000004e6f742061756374696f6e206f776e6572000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000099d8a02a79974ec414b3e597f06f8755940f5e26e45ee9ad90318a6e06d2387c000000000000000000000000000000000000000000000000fffffffffffffec0000000000000000000000000000000000000000000000000fffffffffffffdff190100000000000000000000000000000000000000000000000000000000000045434453413a20696e76616c6964207369676e6174757265206c656e677468007fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a045434453413a20696e76616c6964207369676e61747572650000000000000000756500000000000000000000000000000000000000000000000000000000000045434453413a20696e76616c6964207369676e6174757265202773272076616c53656e646572206e6f7420636c61696d65720000000000000000000000000000426964206e6f742062696720656e6f756768206f662061206a756d7000000000426964206e6f74206869676865720000000000000000000000000000000000004578636565646564206d617820636c61696d7320666f72206163636f756e7400436c61696d20657870697265640000000000000000000000000000000000000052657365727665207072696365206e6f74206d65740000000000000000000000436c61696d207369676e6572206e6f74206578656375746f72000000000000000200000200000000000000000000000000000000000000000000000000000000ade4ae3bb931f135833413ef2a5b2fc564c4952eed23b8c75ae89257c4d98ba3
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.