Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 6,441 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Wake Bear | 16853875 | 616 days ago | IN | 0 ETH | 0.00179366 | ||||
Mek Honey Comb W... | 16852929 | 616 days ago | IN | 0 ETH | 0.00547947 | ||||
Mek Honey Comb W... | 16852917 | 616 days ago | IN | 0 ETH | 0.00105683 | ||||
Mek Honey Comb W... | 16852914 | 616 days ago | IN | 0 ETH | 0.00116027 | ||||
Mek Honey Comb W... | 16852893 | 616 days ago | IN | 0 ETH | 0.02368929 | ||||
Mek Honey Comb W... | 16852852 | 616 days ago | IN | 0 ETH | 0.00303457 | ||||
Mek Honey Comb W... | 16852832 | 616 days ago | IN | 0 ETH | 0.0027332 | ||||
Mek Honey Comb W... | 16852808 | 616 days ago | IN | 0 ETH | 0.0030537 | ||||
Mek Honey Comb W... | 16852804 | 616 days ago | IN | 0 ETH | 0.06857167 | ||||
Mek Honey Comb W... | 16852803 | 616 days ago | IN | 0 ETH | 0.0029103 | ||||
Mek Honey Comb W... | 16852783 | 616 days ago | IN | 0 ETH | 0.00738196 | ||||
Mek Honey Comb W... | 16852769 | 616 days ago | IN | 0 ETH | 0.00291619 | ||||
Mek Honey Comb W... | 16852688 | 616 days ago | IN | 0 ETH | 0.0031191 | ||||
Early Mek Honey ... | 16852426 | 616 days ago | IN | 0 ETH | 0.00407993 | ||||
Mek Honey Comb W... | 16852232 | 616 days ago | IN | 0 ETH | 0.09726427 | ||||
Mek Honey Comb W... | 16852186 | 616 days ago | IN | 0 ETH | 0.00321083 | ||||
Early Mek Honey ... | 16852163 | 616 days ago | IN | 0 ETH | 0.00612134 | ||||
Mek Honey Comb W... | 16852115 | 616 days ago | IN | 0 ETH | 0.00374947 | ||||
Mek Honey Comb W... | 16852096 | 616 days ago | IN | 0 ETH | 0.02535559 | ||||
Mek Honey Comb W... | 16852001 | 616 days ago | IN | 0 ETH | 0.00398525 | ||||
Mek Honey Comb W... | 16851997 | 616 days ago | IN | 0 ETH | 0.04618101 | ||||
Mek Honey Comb W... | 16851934 | 616 days ago | IN | 0 ETH | 0.04896461 | ||||
Mek Honey Comb W... | 16851865 | 616 days ago | IN | 0 ETH | 0.01748989 | ||||
Mek Honey Comb W... | 16851794 | 616 days ago | IN | 0 ETH | 0.02940522 | ||||
Mek Honey Comb W... | 16851761 | 616 days ago | IN | 0 ETH | 0.0066323 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
16850921 | 616 days ago | 0.0768933 ETH | ||||
16850921 | 616 days ago | 0.0221067 ETH | ||||
16848786 | 616 days ago | 0.3075732 ETH | ||||
16848786 | 616 days ago | 0.0884268 ETH | ||||
16848586 | 617 days ago | 0.0768933 ETH | ||||
16848586 | 617 days ago | 0.0221067 ETH | ||||
16847674 | 617 days ago | 0.0768933 ETH | ||||
16847674 | 617 days ago | 0.0221067 ETH | ||||
16847225 | 617 days ago | 0.0768933 ETH | ||||
16847225 | 617 days ago | 0.0221067 ETH | ||||
16844867 | 617 days ago | 0.0768933 ETH | ||||
16844867 | 617 days ago | 0.0221067 ETH | ||||
16842690 | 617 days ago | 0.0768933 ETH | ||||
16842690 | 617 days ago | 0.0221067 ETH | ||||
16841988 | 617 days ago | 0.6151464 ETH | ||||
16841988 | 617 days ago | 0.1768536 ETH | ||||
16841973 | 617 days ago | 0.0768933 ETH | ||||
16841973 | 617 days ago | 0.0221067 ETH | ||||
16838671 | 618 days ago | 0.1537866 ETH | ||||
16838671 | 618 days ago | 0.0442134 ETH | ||||
16831466 | 619 days ago | 0.0768933 ETH | ||||
16831466 | 619 days ago | 0.0221067 ETH | ||||
16827867 | 619 days ago | 0.0768933 ETH | ||||
16827867 | 619 days ago | 0.0221067 ETH | ||||
16827370 | 620 days ago | 0.1537866 ETH |
Loading...
Loading
Contract Name:
BearCave
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 10 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.17; import {ERC1155, ERC1155TokenReceiver} from "solmate/tokens/ERC1155.sol"; import "solmate/tokens/ERC20.sol"; import "solmate/utils/SafeTransferLib.sol"; import "solmate/utils/FixedPointMathLib.sol"; import "solmate/utils/ReentrancyGuard.sol"; import "@chainlink/interfaces/VRFCoordinatorV2Interface.sol"; import "@chainlink/VRFConsumerBaseV2.sol"; import {Gatekeeper} from "./Gatekeeper.sol"; import {IHoneyComb} from "./IHoneyComb.sol"; import {IBearCave} from "./IBearCave.sol"; import {GameRegistryConsumer} from "./GameRegistry.sol"; import {Constants} from "./GameLib.sol"; import "forge-std/console2.sol"; // Example: https://opensea.io/0xd87fa9FeD90948cd7deA9f77c06b9168Ac07F407 :dafoe: contract BearCave is IBearCave, VRFConsumerBaseV2, ERC1155TokenReceiver, ReentrancyGuard, GameRegistryConsumer { using SafeTransferLib for ERC20; using FixedPointMathLib for uint256; /** * Game Errors */ // Contract State error NotInitialized(); error AlreadyInitialized(); // Game state error BearAlreadyWoke(uint256 bearId); error GameInProgress(); error AlreadyTooManyHoneyCombs(uint256 bearId); error SpecialHoneyCombNotFound(uint256 bearId); error NotEnoughHoneyCombMinted(uint256 bearId); error GeneralMintNotOpen(uint256 bearId); // User Errors error NotOwnerOfSpecialHoneyComb(uint256 bearId, uint256 honeycombId); error Claim_IncorrectInput(); error Claim_InvalidProof(); error MekingTooManyHoneyCombs(uint256 bearId); /** * Events */ event Initialized(MintConfig mintConfig); event BearHibernated(uint256 tokenId); event SpecialHoneyCombFound(uint256 tokenId, uint256 honeyCombId); event MintConfigChanged(MintConfig mintConfig); event HoneycombClaimed(uint256 tokenId, address player, uint256 amount); event BearAwoke(uint256 tokenId, address player); /** * Configuration */ ERC20 public paymentToken; // OHM ERC1155 public erc1155; //the openseaAddress (rip) for Bears MintConfig public mintConfig; bool public distributeWithMint; // Feature Toggle... what if we just make a feature toggle lib... uint256 public publicMintingTime; /** * Chainlink VRF Config */ // The gas lane to use, which specifies the maximum gas price to bump to. // For a list of available gas lanes on each network, // see https://docs.chain.link/docs/vrf-contracts/#configurations bytes32 internal keyHash; uint64 internal subId; // https://vrf.chain.link/goerli/new uint16 internal minConfirmations = 3; // Default is 3 // Storing each word costs about 20,000 gas, // so 100,000 is a safe default for this example contract. uint32 internal callbackGasLimit = 100000; // enough for ~5 words /** * bearPouch */ address payable private beekeeper; // rev share 22.33% address payable private jani; uint256 public honeyCombShare; // as a WAD // Accounting vars uint256 public totalERC20Fees; uint256 public totalETHfees; /** * Depenedncies */ Gatekeeper public gatekeeper; IHoneyComb public honeycomb; VRFCoordinatorV2Interface internal vrfCoordinator; /** * Internal Storage */ bool public initialized; // TODO: Review usage & combine these mappings into a single struct where appropriate. mapping(uint256 => HibernatingBear) public bears; // bearId --> hibernatingBear status mapping(uint256 => uint256[]) public honeyJar; // bearId --> honeycomb that was made for it (honeyJar[bearId].length is # minted honeycomb) mapping(uint256 => uint256) public honeycombToBear; // Reverse mapping: honeyId -> bearId mapping(uint256 => uint32) public claimed; // bearid -> numClaimed mapping(uint256 => uint256) public rng; // Chainlink VRF request ID => bearId constructor( address _vrfCoordinator, address _gameRegistry, address _honeycombAddress, address _erc1155Address, address _paymentToken, address _gatekeeper, uint256 _honeyCombShare ) VRFConsumerBaseV2(_vrfCoordinator) GameRegistryConsumer(_gameRegistry) ReentrancyGuard() { vrfCoordinator = VRFCoordinatorV2Interface(_vrfCoordinator); honeycomb = IHoneyComb(_honeycombAddress); erc1155 = ERC1155(_erc1155Address); paymentToken = ERC20(_paymentToken); gatekeeper = Gatekeeper(_gatekeeper); honeyCombShare = _honeyCombShare; distributeWithMint = true; } function initialize( bytes32 keyhash_, uint64 subId_, MintConfig calldata mintConfig_ ) external onlyRole(Constants.GAME_ADMIN) { if (initialized) revert AlreadyInitialized(); initialized = true; keyHash = keyhash_; subId = subId_; mintConfig = mintConfig_; emit Initialized(mintConfig); } /// @notice you miss your bear so you want it function getBear(uint256 _bearId) external view returns (HibernatingBear memory) { return bears[_bearId]; } /// @inheritdoc IBearCave function hibernateBear(uint256 _bearId) external onlyRole(Constants.GAME_ADMIN) { // This is shitty, because theres only one permissions thing. require(erc1155.isApprovedForAll(msg.sender, address(this)), "Gibb cave to permissions to hibernate your bear"); erc1155.safeTransferFrom(msg.sender, address(this), _bearId, 1, ""); bears[_bearId] = HibernatingBear(_bearId, 0, block.timestamp + 72 hours, false, false); gatekeeper.startGatesForToken(_bearId); emit BearHibernated(_bearId); } function _canMintHoneycomb(uint256 bearId_, uint256 amount_) internal view { if (!initialized) revert NotInitialized(); HibernatingBear memory bear = bears[bearId_]; require(bear.id == bearId_, "Da bear isn't hibernating"); if (bear.isAwake) revert BearAlreadyWoke(bearId_); if (honeyJar[bearId_].length > mintConfig.maxHoneycomb) revert AlreadyTooManyHoneyCombs(bearId_); if (honeyJar[bearId_].length + amount_ > mintConfig.maxHoneycomb) revert MekingTooManyHoneyCombs(bearId_); require(amount_ > 0, "why you tryna mint nothing"); } function earlyMekHoneyCombWithERC20( uint256 bearId, uint32 gateId, uint32 proofAmount, bytes32[] calldata proof, uint256 mintAmount ) external returns (uint256) { require(mintAmount > 0, "why you tryna mint nothing"); _canMintHoneycomb(bearId, mintAmount); // validateProof checks that gates are open bool validProof = gatekeeper.validateProof(bearId, gateId, msg.sender, proofAmount, proof); if (!validProof) revert Claim_InvalidProof(); return _distributeERC20AndMintHoneycomb(bearId, mintAmount); } function earlyMekHoneyCombWithEth( uint256 bearId, uint32 gateId, uint32 proofAmount, bytes32[] calldata proof, uint256 mintAmount ) external payable returns (uint256) { _canMintHoneycomb(bearId, mintAmount); // validateProof checks that gates are open bool validProof = gatekeeper.validateProof(bearId, gateId, msg.sender, proofAmount, proof); // This shit needs to be bulletproof if (!validProof) revert Claim_InvalidProof(); return _distributeETHAndMintHoneycomb(bearId, mintAmount); } /// @inheritdoc IBearCave function mekHoneyCombWithERC20(uint256 bearId_, uint256 amount_) external returns (uint256) { _canMintHoneycomb(bearId_, amount_); if (bears[bearId_].publicMintTime > block.timestamp) revert GeneralMintNotOpen(bearId_); return _distributeERC20AndMintHoneycomb(bearId_, amount_); } function mekHoneyCombWithEth(uint256 bearId_, uint256 amount_) external payable returns (uint256) { _canMintHoneycomb(bearId_, amount_); if (bears[bearId_].publicMintTime > block.timestamp) revert GeneralMintNotOpen(bearId_); return _distributeETHAndMintHoneycomb(bearId_, amount_); } /// @dev internal helper function to collect payment and mint honeycomb /// @return tokenID of minted honeyComb function _distributeERC20AndMintHoneycomb(uint256 bearId_, uint256 amount_) internal returns (uint256) { uint256 price = mintConfig.honeycombPrice_ERC20; if (distributeWithMint) { _distribute(price * amount_); } else { paymentToken.safeTransferFrom(msg.sender, address(this), price * amount_); // will revert if there isn't enough totalERC20Fees += price; } // Mint da honey return _mintHoneyCombForBear(msg.sender, bearId_, amount_); } /// @dev internal helper function to collect payment and mint honeycomb /// @return tokenID of minted honeyComb function _distributeETHAndMintHoneycomb(uint256 bearId_, uint256 amount_) internal returns (uint256) { uint256 price = mintConfig.honeycombPrice_ETH; require(msg.value == price * amount_, "MekHoney::Exact eth pls"); if (distributeWithMint) { _distribute(0); } else { totalETHfees += price * amount_; } return _mintHoneyCombForBear(msg.sender, bearId_, amount_); } /// @notice internal method to mint for a particular user /// @param to user to mint to /// @param _bearId the bea being minted for function _mintHoneyCombForBear( address to, uint256 _bearId, uint256 amount_ ) internal returns (uint256) { uint256 tokenId = honeycomb.nextTokenId(); honeycomb.batchMint(to, amount_); // Have a unique tokenId for a given bearId for (uint256 i = 0; i < amount_; ++i) { honeyJar[_bearId].push(tokenId); honeycombToBear[tokenId] = _bearId; ++tokenId; } // Find the special honeycomb when the last honeyComb is minted. if (honeyJar[_bearId].length >= mintConfig.maxHoneycomb) { _findHoneyComb(_bearId); } return tokenId - 1; // returns the lastID created } /// @notice this function _should_ only be called in case of emergencies /// @notice if the honeycombs are minted but the VRF called failed. /// @dev kicks off another VRF request function forceHoneycombSearch(uint256 bearId_) external onlyRole(Constants.GAME_ADMIN) { if (honeyJar[bearId_].length < mintConfig.maxHoneycomb) revert NotEnoughHoneyCombMinted(bearId_); _findHoneyComb(bearId_); } /// @notice Forcing function to find a bear. /// @notice Should only be called when the last honeyCombs is minted. function _findHoneyComb(uint256 bearId_) internal { uint256 requestId = vrfCoordinator.requestRandomWords(keyHash, subId, minConfirmations, callbackGasLimit, 2); rng[requestId] = bearId_; } /// @notice the callback method that is called when VRF completes /// @param requestId requestId that is generated when initiaully calling VRF /// @param randomness an array of random numbers based on `numWords` config function fulfillRandomWords(uint256 requestId, uint256[] memory randomness) internal override { /// use requestID to get bearId uint256 bearId = rng[requestId]; _setSpecialHoneyComb(bearId, randomness[0]); } /// @notice helper function to set a random honeycomb as a winner /// @param bearId self-explanatpry /// @param randomNumber used to determine the index of the winnign number function _setSpecialHoneyComb(uint256 bearId, uint256 randomNumber) internal { uint256 numHoneyCombs = honeyJar[bearId].length; uint256 specialHoneyIndex = randomNumber % numHoneyCombs; uint256 specialHoneyCombId = honeyJar[bearId][specialHoneyIndex]; HibernatingBear storage bear = bears[bearId]; bear.specialHoneycombFound = true; bear.specialHoneycombId = specialHoneyCombId; emit SpecialHoneyCombFound(bearId, specialHoneyCombId); } /// @inheritdoc IBearCave /// @dev erc1155.safeTransferFrom is requires a reciever. function wakeBear(uint256 _bearId) external { // Check that msg.sender has the special honeycomb to wake up bear HibernatingBear memory bear = bears[_bearId]; if (bear.isAwake) revert BearAlreadyWoke(_bearId); if (honeyJar[_bearId].length < mintConfig.maxHoneycomb) revert NotEnoughHoneyCombMinted(_bearId); if (!bear.specialHoneycombFound) revert SpecialHoneyCombNotFound(_bearId); if (honeycomb.ownerOf(bear.specialHoneycombId) != msg.sender) { revert NotOwnerOfSpecialHoneyComb(_bearId, bear.specialHoneycombId); } // Send over bear erc1155.safeTransferFrom(address(this), msg.sender, bear.id, 1, ""); emit BearAwoke(_bearId, msg.sender); } /** * BearPouch owner methods * Can move into another contract for portability * depends on: * Exclusive: beekeeper, jani, honeyCombShare * shared: paymentToken */ /// @dev requires that beekeeper and jani addresses are set. /// @param amountERC20 is zero if we're only distributing the ETH function _distribute(uint256 amountERC20) internal { uint256 beekeeperShareERC20 = amountERC20.mulWadUp(honeyCombShare); uint256 beekeeperShareETH = (msg.value).mulWadUp(honeyCombShare); if (beekeeperShareERC20 > 0) { paymentToken.safeTransferFrom(msg.sender, beekeeper, beekeeperShareERC20); paymentToken.safeTransferFrom(msg.sender, jani, amountERC20 - beekeeperShareERC20); } if (beekeeperShareETH > 0) { SafeTransferLib.safeTransferETH(beekeeper, beekeeperShareETH); SafeTransferLib.safeTransferETH(jani, msg.value - beekeeperShareETH); } } function _splitFee(uint256 currentBalance) internal view returns (uint256) { return currentBalance.mulWadUp(honeyCombShare); } /// @notice should only get called in the event automatic distribution doesn't work function withdrawERC20() external nonReentrant returns (uint256) { require(!distributeWithMint, "distriboot w/ mints should be false"); // permissions check require(_hasRole(Constants.JANI) || _hasRole(Constants.BEEKEEPER), "oogabooga you can't do that"); require(beekeeper != address(0), "withdrawFunds::beekeeper address not set"); require(jani != address(0), "withdrawFunds::jani address not set"); uint256 currBalance = paymentToken.balanceOf(address(this)); require(currBalance > 0, "oogabooga theres nothing here"); // xfer everything all at once so we don't have to worry about accounting uint256 beekeeperShare = _splitFee(currBalance); paymentToken.safeTransfer(beekeeper, beekeeperShare); paymentToken.safeTransfer(jani, paymentToken.balanceOf(address(this))); // This should be everything return paymentToken.balanceOf(address(this)); } /// @notice should only get called in the event automatic distribution doesn't work function withdrawETH() public nonReentrant returns (uint256) { require(!distributeWithMint, "distriboot w/ mints should be false"); require(_hasRole(Constants.JANI) || _hasRole(Constants.BEEKEEPER), "oogabooga you can't do that"); require(beekeeper != address(0), "withdrawETH::beekeeper address not set"); require(jani != address(0), "withdrawFunds::jani address not set"); uint256 beekeeperShare = _splitFee(address(this).balance); SafeTransferLib.safeTransferETH(beekeeper, beekeeperShare); SafeTransferLib.safeTransferETH(jani, address(this).balance); return address(this).balance; } /** * Gatekeeper: for claiming free honeycomb * BearCave: * - maxMintableHoneyComb per Bear * - claimedHoneyComb per Bear // free * - maxClaimableHoneyComb per Bear * Gatekeeper: (per bear) * Gates: * - maxHoneycombAvailable per gate * - maxClaimable per gate * x */ function claim( uint256 bearId_, uint32 gateId, uint32 amount, bytes32[] calldata proof ) public { // Gatekeeper tracks per-player/per-gate claims if (proof.length == 0) revert Claim_InvalidProof(); uint32 numClaim = gatekeeper.claim(bearId_, gateId, msg.sender, amount, proof); if (numClaim == 0) { return; } // Track per bear freeClaims uint32 claimedAmount = claimed[bearId_]; if (numClaim + claimedAmount > mintConfig.maxClaimableHoneycomb) { numClaim = mintConfig.maxClaimableHoneycomb - claimedAmount; } _canMintHoneycomb(bearId_, numClaim); // Validating here because numClaims can change // If for some reason this fails, GG no honeyComb for you _mintHoneyCombForBear(msg.sender, bearId_, numClaim); claimed[bearId_] += numClaim; // Can be combined with "claim" call above, but keeping separate to separate view + modification on gatekeeper gatekeeper.addClaimed(bearId_, gateId, numClaim, proof); emit HoneycombClaimed(bearId_, msg.sender, amount); } // Helpfer function to claim all the free shit function claimAll( uint256 bearId_, uint32[] calldata gateId, uint32[] calldata amount, bytes32[][] calldata proof ) external { uint256 inputLength = proof.length; if (inputLength != gateId.length) revert Claim_IncorrectInput(); if (inputLength != amount.length) revert Claim_IncorrectInput(); for (uint256 i = 0; i < inputLength; ++i) { if (proof[i].length == 0) continue; // Don't nomad yourself claim(bearId_, gateId[i], amount[i], proof[i]); } } //=============== SETTERS ================// /** * Bear Pouch setters (needed for distribution) * Currently separate from the permissioned roles in gameRegistry */ function setJani(address jani_) external onlyRole(Constants.GAME_ADMIN) { jani = payable(jani_); } function setBeeKeeper(address beekeeper_) external onlyRole(Constants.GAME_ADMIN) { beekeeper = payable(beekeeper_); } function setDistributeWithMint(bool distributeWithMint_) external onlyRole(Constants.GAME_ADMIN) { distributeWithMint = distributeWithMint_; } /** * Game setters * These should not be called while a game is in progress to prevent hostage holding. */ /// @notice Sets the max number NFTs (honeyComb) that can be generated from the deposit of a bear (asset) function setMaxHoneycomb(uint32 _maxHoneycomb) external onlyRole(Constants.GAME_ADMIN) { if (_isEnabled(address(this))) revert GameInProgress(); mintConfig.maxHoneycomb = _maxHoneycomb; emit MintConfigChanged(mintConfig); } /// @notice sets the price of the honeycomb in `paymentToken` function setHoneyCombPrice_ERC20(uint256 _honeyCombPrice) external onlyRole(Constants.GAME_ADMIN) { if (_isEnabled(address(this))) revert GameInProgress(); mintConfig.honeycombPrice_ERC20 = _honeyCombPrice; emit MintConfigChanged(mintConfig); } /// @notice sets the price of the honeycomb in `ETH` function setHoneyCombPrice_ETH(uint256 _honeyCombPrice) external onlyRole(Constants.GAME_ADMIN) { if (_isEnabled(address(this))) revert GameInProgress(); mintConfig.honeycombPrice_ETH = _honeyCombPrice; emit MintConfigChanged(mintConfig); } /** * Chainlink Setters * @notice modifiable after initialization isn't a security risk. Just for VRF config. */ function setSubId(uint64 subId_) external onlyRole(Constants.GAME_ADMIN) { subId = subId_; } function setKeyHash(bytes32 keyHash_) external onlyRole(Constants.GAME_ADMIN) { keyHash = keyHash_; } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables * (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, * checking first that contract recipients are aware of the ERC721 protocol * to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move * this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external payable; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) external view returns (bool); // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; import '../IERC721A.sol'; /** * @dev Interface of ERC721AQueryable. */ interface IERC721AQueryable is IERC721A { /** * Invalid query range (`start` >= `stop`). */ error InvalidQueryRange(); /** * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting. * * If the `tokenId` is out of bounds: * * - `addr = address(0)` * - `startTimestamp = 0` * - `burned = false` * - `extraData = 0` * * If the `tokenId` is burned: * * - `addr = <Address of owner before token was burned>` * - `startTimestamp = <Timestamp when token was burned>` * - `burned = true` * - `extraData = <Extra data when token was burned>` * * Otherwise: * * - `addr = <Address of owner>` * - `startTimestamp = <Timestamp of start of ownership>` * - `burned = false` * - `extraData = <Extra data at start of ownership>` */ function explicitOwnershipOf(uint256 tokenId) external view returns (TokenOwnership memory); /** * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order. * See {ERC721AQueryable-explicitOwnershipOf} */ function explicitOwnershipsOf(uint256[] memory tokenIds) external view returns (TokenOwnership[] memory); /** * @dev Returns an array of token IDs owned by `owner`, * in the range [`start`, `stop`) * (i.e. `start <= tokenId < stop`). * * This function allows for tokens to be queried if the collection * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}. * * Requirements: * * - `start < stop` */ function tokensOfOwnerIn( address owner, uint256 start, uint256 stop ) external view returns (uint256[] memory); /** * @dev Returns an array of token IDs owned by `owner`. * * This function scans the ownership mapping and is O(`totalSupply`) in complexity. * It is meant to be called off-chain. * * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into * multiple smaller scans if the collection is large enough to cause * an out-of-gas error (10K collections should be fine). */ function tokensOfOwner(address owner) external view returns (uint256[] memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /** **************************************************************************** * @notice Interface for contracts using VRF randomness * ***************************************************************************** * @dev PURPOSE * * @dev Reggie the Random Oracle (not his real job) wants to provide randomness * @dev to Vera the verifier in such a way that Vera can be sure he's not * @dev making his output up to suit himself. Reggie provides Vera a public key * @dev to which he knows the secret key. Each time Vera provides a seed to * @dev Reggie, he gives back a value which is computed completely * @dev deterministically from the seed and the secret key. * * @dev Reggie provides a proof by which Vera can verify that the output was * @dev correctly computed once Reggie tells it to her, but without that proof, * @dev the output is indistinguishable to her from a uniform random sample * @dev from the output space. * * @dev The purpose of this contract is to make it easy for unrelated contracts * @dev to talk to Vera the verifier about the work Reggie is doing, to provide * @dev simple access to a verifiable source of randomness. It ensures 2 things: * @dev 1. The fulfillment came from the VRFCoordinator * @dev 2. The consumer contract implements fulfillRandomWords. * ***************************************************************************** * @dev USAGE * * @dev Calling contracts must inherit from VRFConsumerBase, and can * @dev initialize VRFConsumerBase's attributes in their constructor as * @dev shown: * * @dev contract VRFConsumer { * @dev constructor(<other arguments>, address _vrfCoordinator, address _link) * @dev VRFConsumerBase(_vrfCoordinator) public { * @dev <initialization with other arguments goes here> * @dev } * @dev } * * @dev The oracle will have given you an ID for the VRF keypair they have * @dev committed to (let's call it keyHash). Create subscription, fund it * @dev and your consumer contract as a consumer of it (see VRFCoordinatorInterface * @dev subscription management functions). * @dev Call requestRandomWords(keyHash, subId, minimumRequestConfirmations, * @dev callbackGasLimit, numWords), * @dev see (VRFCoordinatorInterface for a description of the arguments). * * @dev Once the VRFCoordinator has received and validated the oracle's response * @dev to your request, it will call your contract's fulfillRandomWords method. * * @dev The randomness argument to fulfillRandomWords is a set of random words * @dev generated from your requestId and the blockHash of the request. * * @dev If your contract could have concurrent requests open, you can use the * @dev requestId returned from requestRandomWords to track which response is associated * @dev with which randomness request. * @dev See "SECURITY CONSIDERATIONS" for principles to keep in mind, * @dev if your contract could have multiple requests in flight simultaneously. * * @dev Colliding `requestId`s are cryptographically impossible as long as seeds * @dev differ. * * ***************************************************************************** * @dev SECURITY CONSIDERATIONS * * @dev A method with the ability to call your fulfillRandomness method directly * @dev could spoof a VRF response with any random value, so it's critical that * @dev it cannot be directly called by anything other than this base contract * @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method). * * @dev For your users to trust that your contract's random behavior is free * @dev from malicious interference, it's best if you can write it so that all * @dev behaviors implied by a VRF response are executed *during* your * @dev fulfillRandomness method. If your contract must store the response (or * @dev anything derived from it) and use it later, you must ensure that any * @dev user-significant behavior which depends on that stored value cannot be * @dev manipulated by a subsequent VRF request. * * @dev Similarly, both miners and the VRF oracle itself have some influence * @dev over the order in which VRF responses appear on the blockchain, so if * @dev your contract could have multiple VRF requests in flight simultaneously, * @dev you must ensure that the order in which the VRF responses arrive cannot * @dev be used to manipulate your contract's user-significant behavior. * * @dev Since the block hash of the block which contains the requestRandomness * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful * @dev miner could, in principle, fork the blockchain to evict the block * @dev containing the request, forcing the request to be included in a * @dev different block with a different hash, and therefore a different input * @dev to the VRF. However, such an attack would incur a substantial economic * @dev cost. This cost scales with the number of blocks the VRF oracle waits * @dev until it calls responds to a request. It is for this reason that * @dev that you can signal to an oracle you'd like them to wait longer before * @dev responding to the request (however this is not enforced in the contract * @dev and so remains effective only in the case of unmodified oracle software). */ abstract contract VRFConsumerBaseV2 { error OnlyCoordinatorCanFulfill(address have, address want); address private immutable vrfCoordinator; /** * @param _vrfCoordinator address of VRFCoordinator contract */ constructor(address _vrfCoordinator) { vrfCoordinator = _vrfCoordinator; } /** * @notice fulfillRandomness handles the VRF response. Your contract must * @notice implement it. See "SECURITY CONSIDERATIONS" above for important * @notice principles to keep in mind when implementing your fulfillRandomness * @notice method. * * @dev VRFConsumerBaseV2 expects its subcontracts to have a method with this * @dev signature, and will call it once it has verified the proof * @dev associated with the randomness. (It is triggered via a call to * @dev rawFulfillRandomness, below.) * * @param requestId The Id initially returned by requestRandomness * @param randomWords the VRF output expanded to the requested number of words */ function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal virtual; // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF // proof. rawFulfillRandomness then calls fulfillRandomness, after validating // the origin of the call function rawFulfillRandomWords(uint256 requestId, uint256[] memory randomWords) external { if (msg.sender != vrfCoordinator) { revert OnlyCoordinatorCanFulfill(msg.sender, vrfCoordinator); } fulfillRandomWords(requestId, randomWords); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface VRFCoordinatorV2Interface { /** * @notice Get configuration relevant for making requests * @return minimumRequestConfirmations global min for request confirmations * @return maxGasLimit global max for request gas limit * @return s_provingKeyHashes list of registered key hashes */ function getRequestConfig() external view returns ( uint16, uint32, bytes32[] memory ); /** * @notice Request a set of random words. * @param keyHash - Corresponds to a particular oracle job which uses * that key for generating the VRF proof. Different keyHash's have different gas price * ceilings, so you can select a specific one to bound your maximum per request cost. * @param subId - The ID of the VRF subscription. Must be funded * with the minimum subscription balance required for the selected keyHash. * @param minimumRequestConfirmations - How many blocks you'd like the * oracle to wait before responding to the request. See SECURITY CONSIDERATIONS * for why you may want to request more. The acceptable range is * [minimumRequestBlockConfirmations, 200]. * @param callbackGasLimit - How much gas you'd like to receive in your * fulfillRandomWords callback. Note that gasleft() inside fulfillRandomWords * may be slightly less than this amount because of gas used calling the function * (argument decoding etc.), so you may need to request slightly more than you expect * to have inside fulfillRandomWords. The acceptable range is * [0, maxGasLimit] * @param numWords - The number of uint256 random values you'd like to receive * in your fulfillRandomWords callback. Note these numbers are expanded in a * secure way by the VRFCoordinator from a single random value supplied by the oracle. * @return requestId - A unique identifier of the request. Can be used to match * a request to a response in fulfillRandomWords. */ function requestRandomWords( bytes32 keyHash, uint64 subId, uint16 minimumRequestConfirmations, uint32 callbackGasLimit, uint32 numWords ) external returns (uint256 requestId); /** * @notice Create a VRF subscription. * @return subId - A unique subscription id. * @dev You can manage the consumer set dynamically with addConsumer/removeConsumer. * @dev Note to fund the subscription, use transferAndCall. For example * @dev LINKTOKEN.transferAndCall( * @dev address(COORDINATOR), * @dev amount, * @dev abi.encode(subId)); */ function createSubscription() external returns (uint64 subId); /** * @notice Get a VRF subscription. * @param subId - ID of the subscription * @return balance - LINK balance of the subscription in juels. * @return reqCount - number of requests for this subscription, determines fee tier. * @return owner - owner of the subscription. * @return consumers - list of consumer address which are able to use this subscription. */ function getSubscription(uint64 subId) external view returns ( uint96 balance, uint64 reqCount, address owner, address[] memory consumers ); /** * @notice Request subscription owner transfer. * @param subId - ID of the subscription * @param newOwner - proposed new owner of the subscription */ function requestSubscriptionOwnerTransfer(uint64 subId, address newOwner) external; /** * @notice Request subscription owner transfer. * @param subId - ID of the subscription * @dev will revert if original owner of subId has * not requested that msg.sender become the new owner. */ function acceptSubscriptionOwnerTransfer(uint64 subId) external; /** * @notice Add a consumer to a VRF subscription. * @param subId - ID of the subscription * @param consumer - New consumer which can use the subscription */ function addConsumer(uint64 subId, address consumer) external; /** * @notice Remove a consumer from a VRF subscription. * @param subId - ID of the subscription * @param consumer - Consumer to remove from the subscription */ function removeConsumer(uint64 subId, address consumer) external; /** * @notice Cancel a subscription * @param subId - ID of the subscription * @param to - Where to send the remaining LINK to */ function cancelSubscription(uint64 subId, address to) external; /* * @notice Check to see if there exists a request commitment consumers * for all consumers and keyhashes for a given sub. * @param subId - ID of the subscription * @return true if there exists at least one unfulfilled request for the subscription, false * otherwise. */ function pendingRequestExists(uint64 subId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.9.0; /// @dev The original console.sol uses `int` and `uint` for computing function selectors, but it should /// use `int256` and `uint256`. This modified version fixes that. This version is recommended /// over `console.sol` if you don't need compatibility with Hardhat as the logs will show up in /// forge stack traces. If you do need compatibility with Hardhat, you must use `console.sol`. /// Reference: https://github.com/NomicFoundation/hardhat/issues/2178 library console2 { address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); function _sendLogPayload(bytes memory payload) private view { uint256 payloadLength = payload.length; address consoleAddress = CONSOLE_ADDRESS; /// @solidity memory-safe-assembly assembly { let payloadStart := add(payload, 32) let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) } } function log() internal view { _sendLogPayload(abi.encodeWithSignature("log()")); } function logInt(int256 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); } function logUint(uint256 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); } function logString(string memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function logBool(bool p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function logAddress(address p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function logBytes(bytes memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); } function logBytes1(bytes1 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); } function logBytes2(bytes2 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); } function logBytes3(bytes3 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); } function logBytes4(bytes4 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); } function logBytes5(bytes5 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); } function logBytes6(bytes6 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); } function logBytes7(bytes7 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); } function logBytes8(bytes8 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); } function logBytes9(bytes9 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); } function logBytes10(bytes10 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); } function logBytes11(bytes11 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); } function logBytes12(bytes12 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); } function logBytes13(bytes13 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); } function logBytes14(bytes14 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); } function logBytes15(bytes15 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); } function logBytes16(bytes16 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); } function logBytes17(bytes17 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); } function logBytes18(bytes18 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); } function logBytes19(bytes19 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); } function logBytes20(bytes20 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); } function logBytes21(bytes21 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); } function logBytes22(bytes22 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); } function logBytes23(bytes23 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); } function logBytes24(bytes24 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); } function logBytes25(bytes25 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); } function logBytes26(bytes26 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); } function logBytes27(bytes27 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); } function logBytes28(bytes28 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); } function logBytes29(bytes29 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); } function logBytes30(bytes30 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); } function logBytes31(bytes31 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); } function logBytes32(bytes32 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); } function log(uint256 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); } function log(int256 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); } function log(string memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function log(bool p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function log(address p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function log(uint256 p0, uint256 p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1)); } function log(uint256 p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1)); } function log(uint256 p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1)); } function log(uint256 p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1)); } function log(string memory p0, uint256 p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); } function log(string memory p0, int256 p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,int256)", p0, p1)); } function log(string memory p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); } function log(string memory p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); } function log(string memory p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); } function log(bool p0, uint256 p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1)); } function log(bool p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); } function log(bool p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); } function log(bool p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); } function log(address p0, uint256 p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1)); } function log(address p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); } function log(address p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); } function log(address p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); } function log(uint256 p0, uint256 p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2)); } function log(uint256 p0, string memory p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2)); } function log(uint256 p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2)); } function log(uint256 p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2)); } function log(uint256 p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2)); } function log(uint256 p0, bool p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2)); } function log(uint256 p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2)); } function log(uint256 p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2)); } function log(uint256 p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2)); } function log(uint256 p0, address p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2)); } function log(uint256 p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2)); } function log(uint256 p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2)); } function log(uint256 p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2)); } function log(string memory p0, uint256 p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2)); } function log(string memory p0, uint256 p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2)); } function log(string memory p0, uint256 p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2)); } function log(string memory p0, uint256 p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2)); } function log(string memory p0, string memory p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2)); } function log(string memory p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); } function log(string memory p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); } function log(string memory p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); } function log(string memory p0, bool p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2)); } function log(string memory p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); } function log(string memory p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); } function log(string memory p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); } function log(string memory p0, address p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2)); } function log(string memory p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); } function log(string memory p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); } function log(string memory p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); } function log(bool p0, uint256 p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2)); } function log(bool p0, uint256 p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2)); } function log(bool p0, uint256 p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2)); } function log(bool p0, uint256 p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2)); } function log(bool p0, string memory p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2)); } function log(bool p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); } function log(bool p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); } function log(bool p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); } function log(bool p0, bool p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2)); } function log(bool p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); } function log(bool p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); } function log(bool p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); } function log(bool p0, address p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2)); } function log(bool p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); } function log(bool p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); } function log(bool p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); } function log(address p0, uint256 p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2)); } function log(address p0, uint256 p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2)); } function log(address p0, uint256 p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2)); } function log(address p0, uint256 p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2)); } function log(address p0, string memory p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2)); } function log(address p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); } function log(address p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); } function log(address p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); } function log(address p0, bool p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2)); } function log(address p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); } function log(address p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); } function log(address p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); } function log(address p0, address p1, uint256 p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2)); } function log(address p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); } function log(address p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); } function log(address p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, uint256 p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControl.sol"; import "../utils/Context.sol"; import "../utils/Strings.sol"; import "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(account), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.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 `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); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts 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.8.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) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. 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 10, 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 * 8) < value ? 1 : 0); } } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Minimalist and gas efficient standard ERC1155 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol) abstract contract ERC1155 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event TransferSingle( address indexed operator, address indexed from, address indexed to, uint256 id, uint256 amount ); event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] amounts ); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); event URI(string value, uint256 indexed id); /*////////////////////////////////////////////////////////////// ERC1155 STORAGE //////////////////////////////////////////////////////////////*/ mapping(address => mapping(uint256 => uint256)) public balanceOf; mapping(address => mapping(address => bool)) public isApprovedForAll; /*////////////////////////////////////////////////////////////// METADATA LOGIC //////////////////////////////////////////////////////////////*/ function uri(uint256 id) public view virtual returns (string memory); /*////////////////////////////////////////////////////////////// ERC1155 LOGIC //////////////////////////////////////////////////////////////*/ function setApprovalForAll(address operator, bool approved) public virtual { isApprovedForAll[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) public virtual { require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED"); balanceOf[from][id] -= amount; balanceOf[to][id] += amount; emit TransferSingle(msg.sender, from, to, id, amount); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) == ERC1155TokenReceiver.onERC1155Received.selector, "UNSAFE_RECIPIENT" ); } function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) public virtual { require(ids.length == amounts.length, "LENGTH_MISMATCH"); require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED"); // Storing these outside the loop saves ~15 gas per iteration. uint256 id; uint256 amount; for (uint256 i = 0; i < ids.length; ) { id = ids[i]; amount = amounts[i]; balanceOf[from][id] -= amount; balanceOf[to][id] += amount; // An array can't have a total length // larger than the max uint256 value. unchecked { ++i; } } emit TransferBatch(msg.sender, from, to, ids, amounts); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) == ERC1155TokenReceiver.onERC1155BatchReceived.selector, "UNSAFE_RECIPIENT" ); } function balanceOfBatch(address[] calldata owners, uint256[] calldata ids) public view virtual returns (uint256[] memory balances) { require(owners.length == ids.length, "LENGTH_MISMATCH"); balances = new uint256[](owners.length); // Unchecked because the only math done is incrementing // the array index counter which cannot possibly overflow. unchecked { for (uint256 i = 0; i < owners.length; ++i) { balances[i] = balanceOf[owners[i]][ids[i]]; } } } /*////////////////////////////////////////////////////////////// ERC165 LOGIC //////////////////////////////////////////////////////////////*/ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155 interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint( address to, uint256 id, uint256 amount, bytes memory data ) internal virtual { balanceOf[to][id] += amount; emit TransferSingle(msg.sender, address(0), to, id, amount); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, address(0), id, amount, data) == ERC1155TokenReceiver.onERC1155Received.selector, "UNSAFE_RECIPIENT" ); } function _batchMint( address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { uint256 idsLength = ids.length; // Saves MLOADs. require(idsLength == amounts.length, "LENGTH_MISMATCH"); for (uint256 i = 0; i < idsLength; ) { balanceOf[to][ids[i]] += amounts[i]; // An array can't have a total length // larger than the max uint256 value. unchecked { ++i; } } emit TransferBatch(msg.sender, address(0), to, ids, amounts); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) == ERC1155TokenReceiver.onERC1155BatchReceived.selector, "UNSAFE_RECIPIENT" ); } function _batchBurn( address from, uint256[] memory ids, uint256[] memory amounts ) internal virtual { uint256 idsLength = ids.length; // Saves MLOADs. require(idsLength == amounts.length, "LENGTH_MISMATCH"); for (uint256 i = 0; i < idsLength; ) { balanceOf[from][ids[i]] -= amounts[i]; // An array can't have a total length // larger than the max uint256 value. unchecked { ++i; } } emit TransferBatch(msg.sender, from, address(0), ids, amounts); } function _burn( address from, uint256 id, uint256 amount ) internal virtual { balanceOf[from][id] -= amount; emit TransferSingle(msg.sender, from, address(0), id, amount); } } /// @notice A generic interface for a contract which properly accepts ERC1155 tokens. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol) abstract contract ERC1155TokenReceiver { function onERC1155Received( address, address, uint256, uint256, bytes calldata ) external virtual returns (bytes4) { return ERC1155TokenReceiver.onERC1155Received.selector; } function onERC1155BatchReceived( address, address, uint256[] calldata, uint256[] calldata, bytes calldata ) external virtual returns (bytes4) { return ERC1155TokenReceiver.onERC1155BatchReceived.selector; } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); /*////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { address recoveredAddress = ecrecover( keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256( abi.encode( keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ), owner, spender, value, nonces[owner]++, deadline ) ) ) ), v, r, s ); require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern, minimalist, and gas efficient ERC-721 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) abstract contract ERC721 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 indexed id); event Approval(address indexed owner, address indexed spender, uint256 indexed id); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /*////////////////////////////////////////////////////////////// METADATA STORAGE/LOGIC //////////////////////////////////////////////////////////////*/ string public name; string public symbol; function tokenURI(uint256 id) public view virtual returns (string memory); /*////////////////////////////////////////////////////////////// ERC721 BALANCE/OWNER STORAGE //////////////////////////////////////////////////////////////*/ mapping(uint256 => address) internal _ownerOf; mapping(address => uint256) internal _balanceOf; function ownerOf(uint256 id) public view virtual returns (address owner) { require((owner = _ownerOf[id]) != address(0), "NOT_MINTED"); } function balanceOf(address owner) public view virtual returns (uint256) { require(owner != address(0), "ZERO_ADDRESS"); return _balanceOf[owner]; } /*////////////////////////////////////////////////////////////// ERC721 APPROVAL STORAGE //////////////////////////////////////////////////////////////*/ mapping(uint256 => address) public getApproved; mapping(address => mapping(address => bool)) public isApprovedForAll; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor(string memory _name, string memory _symbol) { name = _name; symbol = _symbol; } /*////////////////////////////////////////////////////////////// ERC721 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 id) public virtual { address owner = _ownerOf[id]; require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED"); getApproved[id] = spender; emit Approval(owner, spender, id); } function setApprovalForAll(address operator, bool approved) public virtual { isApprovedForAll[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } function transferFrom( address from, address to, uint256 id ) public virtual { require(from == _ownerOf[id], "WRONG_FROM"); require(to != address(0), "INVALID_RECIPIENT"); require( msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id], "NOT_AUTHORIZED" ); // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. unchecked { _balanceOf[from]--; _balanceOf[to]++; } _ownerOf[id] = to; delete getApproved[id]; emit Transfer(from, to, id); } function safeTransferFrom( address from, address to, uint256 id ) public virtual { transferFrom(from, to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } function safeTransferFrom( address from, address to, uint256 id, bytes calldata data ) public virtual { transferFrom(from, to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } /*////////////////////////////////////////////////////////////// ERC165 LOGIC //////////////////////////////////////////////////////////////*/ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721 interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 id) internal virtual { require(to != address(0), "INVALID_RECIPIENT"); require(_ownerOf[id] == address(0), "ALREADY_MINTED"); // Counter overflow is incredibly unrealistic. unchecked { _balanceOf[to]++; } _ownerOf[id] = to; emit Transfer(address(0), to, id); } function _burn(uint256 id) internal virtual { address owner = _ownerOf[id]; require(owner != address(0), "NOT_MINTED"); // Ownership check above ensures no underflow. unchecked { _balanceOf[owner]--; } delete _ownerOf[id]; delete getApproved[id]; emit Transfer(owner, address(0), id); } /*////////////////////////////////////////////////////////////// INTERNAL SAFE MINT LOGIC //////////////////////////////////////////////////////////////*/ function _safeMint(address to, uint256 id) internal virtual { _mint(to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } function _safeMint( address to, uint256 id, bytes memory data ) internal virtual { _mint(to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } } /// @notice A generic interface for a contract which properly accepts ERC721 tokens. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) abstract contract ERC721TokenReceiver { function onERC721Received( address, address, uint256, bytes calldata ) external virtual returns (bytes4) { return ERC721TokenReceiver.onERC721Received.selector; } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Arithmetic library with operations for fixed-point numbers. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol) /// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol) library FixedPointMathLib { /*////////////////////////////////////////////////////////////// SIMPLIFIED FIXED POINT OPERATIONS //////////////////////////////////////////////////////////////*/ uint256 internal constant MAX_UINT256 = 2**256 - 1; uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s. function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down. } function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up. } function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down. } function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up. } /*////////////////////////////////////////////////////////////// LOW LEVEL FIXED POINT OPERATIONS //////////////////////////////////////////////////////////////*/ function mulDivDown( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { revert(0, 0) } // Divide x * y by the denominator. z := div(mul(x, y), denominator) } } function mulDivUp( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { revert(0, 0) } // If x * y modulo the denominator is strictly greater than 0, // 1 is added to round up the division of x * y by the denominator. z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator)) } } function rpow( uint256 x, uint256 n, uint256 scalar ) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { switch x case 0 { switch n case 0 { // 0 ** 0 = 1 z := scalar } default { // 0 ** n = 0 z := 0 } } default { switch mod(n, 2) case 0 { // If n is even, store scalar in z for now. z := scalar } default { // If n is odd, store x in z for now. z := x } // Shifting right by 1 is like dividing by 2. let half := shr(1, scalar) for { // Shift n right by 1 before looping to halve it. n := shr(1, n) } n { // Shift n right by 1 each iteration to halve it. n := shr(1, n) } { // Revert immediately if x ** 2 would overflow. // Equivalent to iszero(eq(div(xx, x), x)) here. if shr(128, x) { revert(0, 0) } // Store x squared. let xx := mul(x, x) // Round to the nearest number. let xxRound := add(xx, half) // Revert if xx + half overflowed. if lt(xxRound, xx) { revert(0, 0) } // Set x to scaled xxRound. x := div(xxRound, scalar) // If n is even: if mod(n, 2) { // Compute z * x. let zx := mul(z, x) // If z * x overflowed: if iszero(eq(div(zx, x), z)) { // Revert if x is non-zero. if iszero(iszero(x)) { revert(0, 0) } } // Round to the nearest number. let zxRound := add(zx, half) // Revert if zx + half overflowed. if lt(zxRound, zx) { revert(0, 0) } // Return properly scaled zxRound. z := div(zxRound, scalar) } } } } } /*////////////////////////////////////////////////////////////// GENERAL NUMBER UTILITIES //////////////////////////////////////////////////////////////*/ function sqrt(uint256 x) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { let y := x // We start y at x, which will help us make our initial estimate. z := 181 // The "correct" value is 1, but this saves a multiplication later. // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically. // We check y >= 2^(k + 8) but shift right by k bits // each branch to ensure that if x >= 256, then y >= 256. if iszero(lt(y, 0x10000000000000000000000000000000000)) { y := shr(128, y) z := shl(64, z) } if iszero(lt(y, 0x1000000000000000000)) { y := shr(64, y) z := shl(32, z) } if iszero(lt(y, 0x10000000000)) { y := shr(32, y) z := shl(16, z) } if iszero(lt(y, 0x1000000)) { y := shr(16, y) z := shl(8, z) } // Goal was to get z*z*y within a small factor of x. More iterations could // get y in a tighter range. Currently, we will have y in [256, 256*2^16). // We ensured y >= 256 so that the relative difference between y and y+1 is small. // That's not possible if x < 256 but we can just verify those cases exhaustively. // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256. // Correctness can be checked exhaustively for x < 256, so we assume y >= 256. // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps. // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256. // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18. // There is no overflow risk here since y < 2^136 after the first branch above. z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181. // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough. z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) // If x+1 is a perfect square, the Babylonian method cycles between // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor. // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case. // If you don't care whether the floor or ceil square root is returned, you can remove this statement. z := sub(z, lt(div(x, z), z)) } } function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Mod x by y. Note this will return // 0 instead of reverting if y is zero. z := mod(x, y) } } function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) { /// @solidity memory-safe-assembly assembly { // Divide x by y. Note this will return // 0 instead of reverting if y is zero. r := div(x, y) } } function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Add 1 to x * y if x % y > 0. Note this will // return 0 instead of reverting if y is zero. z := add(gt(mod(x, y), 0), div(x, y)) } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; /// @notice Gas optimized merkle proof verification library. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/MerkleProofLib.sol) /// @author Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/MerkleProofLib.sol) library MerkleProofLib { function verify( bytes32[] calldata proof, bytes32 root, bytes32 leaf ) internal pure returns (bool isValid) { /// @solidity memory-safe-assembly assembly { if proof.length { // Left shifting by 5 is like multiplying by 32. let end := add(proof.offset, shl(5, proof.length)) // Initialize offset to the offset of the proof in calldata. let offset := proof.offset // Iterate over proof elements to compute root hash. // prettier-ignore for {} 1 {} { // Slot where the leaf should be put in scratch space. If // leaf > calldataload(offset): slot 32, otherwise: slot 0. let leafSlot := shl(5, gt(leaf, calldataload(offset))) // Store elements to hash contiguously in scratch space. // The xor puts calldataload(offset) in whichever slot leaf // is not occupying, so 0 if leafSlot is 32, and 32 otherwise. mstore(leafSlot, leaf) mstore(xor(leafSlot, 32), calldataload(offset)) // Reuse leaf to store the hash to reduce stack operations. leaf := keccak256(0, 64) // Hash both slots of scratch space. offset := add(offset, 32) // Shift 1 word per cycle. // prettier-ignore if iszero(lt(offset, end)) { break } } } isValid := eq(leaf, root) // The proof is valid if the roots match. } } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Gas optimized reentrancy protection for smart contracts. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ReentrancyGuard.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol) abstract contract ReentrancyGuard { uint256 private locked = 1; modifier nonReentrant() virtual { require(locked == 1, "REENTRANCY"); locked = 2; _; locked = 1; } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; import {ERC20} from "../tokens/ERC20.sol"; /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) /// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer. /// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller. library SafeTransferLib { /*////////////////////////////////////////////////////////////// ETH OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferETH(address to, uint256 amount) internal { bool success; /// @solidity memory-safe-assembly assembly { // Transfer the ETH and store if it succeeded or not. success := call(gas(), to, amount, 0, 0, 0, 0) } require(success, "ETH_TRANSFER_FAILED"); } /*////////////////////////////////////////////////////////////// ERC20 OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferFrom( ERC20 token, address from, address to, uint256 amount ) internal { bool success; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), from) // Append the "from" argument. mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 100, 0, 32) ) } require(success, "TRANSFER_FROM_FAILED"); } function safeTransfer( ERC20 token, address to, uint256 amount ) internal { bool success; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "TRANSFER_FAILED"); } function safeApprove( ERC20 token, address to, uint256 amount ) internal { bool success; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "APPROVE_FAILED"); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.17; library Constants { // External permissions bytes32 public constant GAME_ADMIN = "GAME_ADMIN"; bytes32 public constant BEEKEEPER = "BEEKEEPER"; bytes32 public constant JANI = "JANI"; // Contract instances bytes32 public constant GAME_INSTANCE = "GAME_INSTANCE"; bytes32 public constant BEAR_POUCH = "BEAR_POUCH"; bytes32 public constant GATEKEEPER = "GATEKEEPER"; bytes32 public constant GATE = "GATE"; // Special honeycomb permissions bytes32 public constant MINTER = "MINTER"; bytes32 public constant BURNER = "BURNER"; }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.17; import "@openzeppelin/contracts/access/AccessControl.sol"; import {Constants} from "./GameLib.sol"; /// @title GameRegistry /// @notice Central repository that tracks games and permissions. /// @dev All game contracts should use extend `GameRegistryConsumer` to have consistent permissioning contract GameRegistry is AccessControl { struct Game { bool enabled; } uint256[] public stageTimes; constructor() { _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); _setupRole(Constants.GAME_ADMIN, msg.sender); // Initial 4 stages stageTimes.push(0 hours); stageTimes.push(24 hours); stageTimes.push(48 hours); stageTimes.push(72 hours); } mapping(address => Game) public games; function registerGame(address game_) external onlyRole(Constants.GAME_ADMIN) { _grantRole(Constants.GAME_INSTANCE, game_); games[game_] = Game(true); } function startGame(address game_) external onlyRole(Constants.GAME_ADMIN) { _grantRole(Constants.MINTER, game_); } function stopGame(address game_) external onlyRole(Constants.GAME_ADMIN) { _revokeRole(Constants.MINTER, game_); games[game_].enabled = false; } /** * Gettors */ function getStageTimes() external view returns (uint256[] memory) { return stageTimes; } /** * Bear Pouch setters (helper functions) * Can check roles directly since this is an access control */ function setJani(address jani_) external onlyRole(Constants.GAME_ADMIN) { _grantRole(Constants.JANI, jani_); } function setBeekeeper(address beeKeeper_) external onlyRole(Constants.GAME_ADMIN) { _grantRole(Constants.JANI, beeKeeper_); } function setStageTimes(uint24[] calldata _stageTimes) external onlyRole(Constants.GAME_ADMIN) { stageTimes = _stageTimes; } } abstract contract GameRegistryConsumer { GameRegistry public gameRegistry; error GameRegistry_NoPermissions(string role, address user); error GameRegistry_StageOutOfBounds(uint8 index); modifier onlyRole(bytes32 role_) { if (!gameRegistry.hasRole(role_, msg.sender)) { revert GameRegistry_NoPermissions(string(abi.encodePacked(role_)), msg.sender); } _; } constructor(address gameRegistry_) { gameRegistry = GameRegistry(gameRegistry_); } function _isEnabled(address game_) internal view returns (bool enabled) { enabled = gameRegistry.games(game_); } /// @dev the last stageTime is generalMint function _getStages() internal view returns (uint256[] memory) { return gameRegistry.getStageTimes(); } /// @dev just a helper function. For access to all stages you should use _getStages() function _getStage(uint8 stageIndex) internal view returns (uint256) { uint256[] memory stageTimes = gameRegistry.getStageTimes(); if (stageIndex >= stageTimes.length) revert GameRegistry_StageOutOfBounds(stageIndex); return stageTimes[stageIndex]; } function _hasRole(bytes32 role_) internal view returns (bool) { return gameRegistry.hasRole(role_, msg.sender); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.17; import {ERC1155} from "solmate/tokens/ERC1155.sol"; import {ERC20} from "solmate/tokens/ERC20.sol"; import {ERC721} from "solmate/tokens/ERC721.sol"; import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "solmate/utils/MerkleProofLib.sol"; import {GameRegistryConsumer} from "./GameRegistry.sol"; import {Constants} from "./GameLib.sol"; /** * Bear GateKeeper * In order to remain gas-efficient gates will be calculated off-chain * BearGate: owning bears * CrownGate: every single one of the digital collectible articles, then they get a free claim in every game * HoneyGate: Genesis mint & n-1 can mint * FrenGate: owning particular assets * PartnerGate: being on a traditional allowlist * Since gates are merkle trees, the per-player amounts will be set off-chain in the root. * @notice state needs to be reset after each game. * @notice tracks claims per player, and claims per gate. */ contract Gatekeeper is GameRegistryConsumer { struct Gate { bool enabled; uint8 stageIndex; // stage from [0-3] uint32 claimedCount; // # of claims already happend uint32 maxClaimable; // # of claims per gate bytes32 gateRoot; uint256 activeAt; // timestamp when active. } /** * Events when business logic is affects */ event GateAdded(uint256 tokenId, uint256 gateId); event GateSetEnabled(uint256 tokenId, uint256 gateId, bool enabled); event GateActivated(uint256 tokenId, uint256 gateId, uint256 activationTime); event GetSetMaxClaimable(uint256 tokenId, uint256 gateId, uint256 maxClaimable); event GateReset(uint256 tokenId, uint256 index); /** * Internal Storage */ mapping(uint256 => Gate[]) public tokenToGates; // bear -> Gates[] mapping(uint256 => mapping(bytes32 => bool)) public consumedProofs; // gateId --> proof --> boolean mapping(uint256 => bytes32[]) public consumedProofsList; // gateId mapping(uint256 => address) public games; // bear --> gameContract; /** * Dependencies */ /// @notice admin is the address that is set as the owner. constructor(address gameRegistry_) GameRegistryConsumer(gameRegistry_) {} /// @notice validate how much you can claim for a particular token and gate. (not a real claim) /// @param tokenId the ID of the bear in the game. /// @param index the gate index we're claiming /// @param amount number between 0-maxClaimable you a player wants to claim /// @param proof merkle proof function claim(uint256 tokenId, uint256 index, address player, uint32 amount, bytes32[] calldata proof) external view returns (uint32 claimAmount) { // If proof was already used within the gate, there are 0 left to claim bytes32 proofHash = keccak256(abi.encode(proof)); if (consumedProofs[index][proofHash]) return 0; Gate storage gate = tokenToGates[tokenId][index]; uint32 claimedCount = gate.claimedCount; require(claimedCount < gate.maxClaimable, "Too much honeycomb went through this gate"); claimAmount = amount; bool validProof = validateProof(tokenId, index, player, amount, proof); require(validProof, "Not a valid proof bro"); if (amount + claimedCount > gate.maxClaimable) { claimAmount = gate.maxClaimable - claimedCount; } } /// @notice Validates proof /// @dev relies on gates being enabled function validateProof(uint256 tokenId, uint256 index, address player, uint32 amount, bytes32[] calldata proof) public view returns (bool validProof) { Gate[] storage gates = tokenToGates[tokenId]; require(gates.length > 0, "nogates fren"); require(index < gates.length, "Index too big bro"); require(proof.length > 0, "Invalid Proof"); Gate storage gate = gates[index]; require(gate.enabled, "gates closed bruh"); require(gate.activeAt <= block.timestamp, "gate isn't active"); bytes32 leaf = keccak256(abi.encodePacked(player, amount)); validProof = MerkleProofLib.verify(proof, gate.gateRoot, leaf); } /** * Setters */ /// @notice update accounting /// @dev should only be called by a game function addClaimed(uint256 tokenId, uint256 gateId, uint32 numClaimed, bytes32[] calldata proof) external onlyRole(Constants.GAME_INSTANCE) { Gate storage gate = tokenToGates[tokenId][gateId]; gate.claimedCount += numClaimed; bytes32 proofHash = keccak256(abi.encode(proof)); consumedProofs[gateId][proofHash] = true; consumedProofsList[gateId].push(proofHash); } /** * Gate admin methods */ function addGate(uint256 tokenId, bytes32 root_, uint32 maxClaimable_, uint8 stageIndex_) external onlyRole(Constants.GAME_ADMIN) { // claimedCount = activeAt = 0 require(_getStages().length > stageIndex_, "addGate: stageIndex_ is out of bounds"); tokenToGates[tokenId].push(Gate(false, stageIndex_, 0, maxClaimable_, root_, 0)); emit GateAdded(tokenId, tokenToGates[tokenId].length - 1); } function startGatesForToken(uint256 tokenId) external onlyRole(Constants.GAME_INSTANCE) { Gate[] storage gates = tokenToGates[tokenId]; uint256[] memory stageTimes = _getStages(); // External Call uint256 numGates = gates.length; for (uint256 i = 0; i < numGates; i++) { gates[i].enabled = true; gates[i].activeAt = block.timestamp + stageTimes[gates[i].stageIndex]; emit GateActivated(tokenId, i, gates[i].activeAt); } } /// @notice Only to be used for emergency gate shutdown. function setGateEnabled(uint256 tokenId, uint256 index, bool enabled) external onlyRole(Constants.GAME_ADMIN) { tokenToGates[tokenId][index].enabled = enabled; emit GateSetEnabled(tokenId, index, enabled); } function setGateMaxClaimable(uint256 tokenId, uint256 index, uint32 maxClaimable_) external onlyRole(Constants.GAME_ADMIN) { tokenToGates[tokenId][index].maxClaimable = maxClaimable_; emit GetSetMaxClaimable(tokenId, index, maxClaimable_); } function resetGate(uint256 tokenId, uint256 index) external onlyRole(Constants.GAME_ADMIN) { tokenToGates[tokenId][index].claimedCount = 0; emit GateReset(tokenId, index); } function resetAllGates(uint256 tokenId) external onlyRole(Constants.GAME_ADMIN) { uint256 numGates = tokenToGates[tokenId].length; Gate[] storage tokenGates = tokenToGates[tokenId]; uint256 numProofs; // Currently a hacky way but need to clear out if the proofs were used. for (uint256 i = 0; i < numGates; i++) { tokenGates[i].claimedCount = 0; numProofs = consumedProofsList[i].length; for (uint256 j = 0; j < numProofs; ++j) { // Step through all proofs from a particular gate. consumedProofs[i][consumedProofsList[i][j]] = false; } } } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.17; /// @title BearCave: Only one true honey can make a bear wake up interface IBearCave { struct HibernatingBear { uint256 id; uint256 specialHoneycombId; // defaults to 0 uint256 publicMintTime; // block.timstamp that general public can start making honeycombs bool specialHoneycombFound; // So tokenID=0 can't wake bear before special honey is found bool isAwake; // don't try to wake if its already awake } struct MintConfig { uint32 maxHoneycomb; // Max # of generated honeys (Max of 4.2m -- we'll have 10420) uint32 maxClaimableHoneycomb; // # of honeycombs that can be claimed (total) uint256 honeycombPrice_ERC20; uint256 honeycombPrice_ETH; } /// @notice Puts the bear into the cave to mek it sleep /// @dev Should be permissioned to be onlyOwner /// @param _bearId ID of the bear to mek sleep function hibernateBear(uint256 _bearId) external; /// @notice Meks honey for `_bearID` that could wake it up. Will revert if user does not have the funds. /// @param _bearId ID of the bear the honey will wake up function mekHoneyCombWithERC20(uint256 _bearId, uint256 amount) external returns (uint256); // Makes honey for the bear /// @notice Same as `mekHoneyCombWithERC20` however this function accepts ETH payments function mekHoneyCombWithEth(uint256 _bearId, uint256 amount) external payable returns (uint256); /// @notice Takes special honey to wake up the bear /// @param _bearId ID of the bear to wake up function wakeBear(uint256 _bearId) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.17; import "ERC721A/extensions/IERC721AQueryable.sol"; interface IHoneyComb is IERC721AQueryable { function mint(address to) external returns (uint256); function batchMint(address to, uint256 amount) external; function burn(uint256 _id) external; function nextTokenId() external view returns (uint256); }
{ "remappings": [ "@chainlink/=lib/chainlink-brownie-contracts/contracts/src/v0.8/", "@openzeppelin/=lib/openzeppelin-contracts/", "ERC721A/=lib/ERC721A/contracts/", "chainlink-brownie-contracts/=lib/chainlink-brownie-contracts/contracts/src/v0.8/dev/vendor/@arbitrum/nitro-contracts/src/", "ds-test/=lib/solmate/lib/ds-test/src/", "dual-ownership-nft/=lib/dual-ownership-nft/contracts/", "forge-std/=lib/forge-std/src/", "murky/=lib/murky/src/", "openzeppelin-contracts/=lib/murky/lib/openzeppelin-contracts/", "solmate/=lib/solmate/src/" ], "optimizer": { "enabled": true, "runs": 10 }, "metadata": { "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_vrfCoordinator","type":"address"},{"internalType":"address","name":"_gameRegistry","type":"address"},{"internalType":"address","name":"_honeycombAddress","type":"address"},{"internalType":"address","name":"_erc1155Address","type":"address"},{"internalType":"address","name":"_paymentToken","type":"address"},{"internalType":"address","name":"_gatekeeper","type":"address"},{"internalType":"uint256","name":"_honeyCombShare","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[{"internalType":"uint256","name":"bearId","type":"uint256"}],"name":"AlreadyTooManyHoneyCombs","type":"error"},{"inputs":[{"internalType":"uint256","name":"bearId","type":"uint256"}],"name":"BearAlreadyWoke","type":"error"},{"inputs":[],"name":"Claim_IncorrectInput","type":"error"},{"inputs":[],"name":"Claim_InvalidProof","type":"error"},{"inputs":[],"name":"GameInProgress","type":"error"},{"inputs":[{"internalType":"string","name":"role","type":"string"},{"internalType":"address","name":"user","type":"address"}],"name":"GameRegistry_NoPermissions","type":"error"},{"inputs":[{"internalType":"uint8","name":"index","type":"uint8"}],"name":"GameRegistry_StageOutOfBounds","type":"error"},{"inputs":[{"internalType":"uint256","name":"bearId","type":"uint256"}],"name":"GeneralMintNotOpen","type":"error"},{"inputs":[{"internalType":"uint256","name":"bearId","type":"uint256"}],"name":"MekingTooManyHoneyCombs","type":"error"},{"inputs":[{"internalType":"uint256","name":"bearId","type":"uint256"}],"name":"NotEnoughHoneyCombMinted","type":"error"},{"inputs":[],"name":"NotInitialized","type":"error"},{"inputs":[{"internalType":"uint256","name":"bearId","type":"uint256"},{"internalType":"uint256","name":"honeycombId","type":"uint256"}],"name":"NotOwnerOfSpecialHoneyComb","type":"error"},{"inputs":[{"internalType":"address","name":"have","type":"address"},{"internalType":"address","name":"want","type":"address"}],"name":"OnlyCoordinatorCanFulfill","type":"error"},{"inputs":[{"internalType":"uint256","name":"bearId","type":"uint256"}],"name":"SpecialHoneyCombNotFound","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"player","type":"address"}],"name":"BearAwoke","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"BearHibernated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"HoneycombClaimed","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint32","name":"maxHoneycomb","type":"uint32"},{"internalType":"uint32","name":"maxClaimableHoneycomb","type":"uint32"},{"internalType":"uint256","name":"honeycombPrice_ERC20","type":"uint256"},{"internalType":"uint256","name":"honeycombPrice_ETH","type":"uint256"}],"indexed":false,"internalType":"struct IBearCave.MintConfig","name":"mintConfig","type":"tuple"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint32","name":"maxHoneycomb","type":"uint32"},{"internalType":"uint32","name":"maxClaimableHoneycomb","type":"uint32"},{"internalType":"uint256","name":"honeycombPrice_ERC20","type":"uint256"},{"internalType":"uint256","name":"honeycombPrice_ETH","type":"uint256"}],"indexed":false,"internalType":"struct IBearCave.MintConfig","name":"mintConfig","type":"tuple"}],"name":"MintConfigChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"honeyCombId","type":"uint256"}],"name":"SpecialHoneyCombFound","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"bears","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"specialHoneycombId","type":"uint256"},{"internalType":"uint256","name":"publicMintTime","type":"uint256"},{"internalType":"bool","name":"specialHoneycombFound","type":"bool"},{"internalType":"bool","name":"isAwake","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"bearId_","type":"uint256"},{"internalType":"uint32","name":"gateId","type":"uint32"},{"internalType":"uint32","name":"amount","type":"uint32"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"bearId_","type":"uint256"},{"internalType":"uint32[]","name":"gateId","type":"uint32[]"},{"internalType":"uint32[]","name":"amount","type":"uint32[]"},{"internalType":"bytes32[][]","name":"proof","type":"bytes32[][]"}],"name":"claimAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"claimed","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"distributeWithMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"bearId","type":"uint256"},{"internalType":"uint32","name":"gateId","type":"uint32"},{"internalType":"uint32","name":"proofAmount","type":"uint32"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint256","name":"mintAmount","type":"uint256"}],"name":"earlyMekHoneyCombWithERC20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"bearId","type":"uint256"},{"internalType":"uint32","name":"gateId","type":"uint32"},{"internalType":"uint32","name":"proofAmount","type":"uint32"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint256","name":"mintAmount","type":"uint256"}],"name":"earlyMekHoneyCombWithEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"erc1155","outputs":[{"internalType":"contract ERC1155","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"bearId_","type":"uint256"}],"name":"forceHoneycombSearch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gameRegistry","outputs":[{"internalType":"contract GameRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gatekeeper","outputs":[{"internalType":"contract Gatekeeper","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_bearId","type":"uint256"}],"name":"getBear","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"specialHoneycombId","type":"uint256"},{"internalType":"uint256","name":"publicMintTime","type":"uint256"},{"internalType":"bool","name":"specialHoneycombFound","type":"bool"},{"internalType":"bool","name":"isAwake","type":"bool"}],"internalType":"struct IBearCave.HibernatingBear","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_bearId","type":"uint256"}],"name":"hibernateBear","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"honeyCombShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"honeyJar","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"honeycomb","outputs":[{"internalType":"contract IHoneyComb","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"honeycombToBear","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"keyhash_","type":"bytes32"},{"internalType":"uint64","name":"subId_","type":"uint64"},{"components":[{"internalType":"uint32","name":"maxHoneycomb","type":"uint32"},{"internalType":"uint32","name":"maxClaimableHoneycomb","type":"uint32"},{"internalType":"uint256","name":"honeycombPrice_ERC20","type":"uint256"},{"internalType":"uint256","name":"honeycombPrice_ETH","type":"uint256"}],"internalType":"struct IBearCave.MintConfig","name":"mintConfig_","type":"tuple"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"bearId_","type":"uint256"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"mekHoneyCombWithERC20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"bearId_","type":"uint256"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"mekHoneyCombWithEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintConfig","outputs":[{"internalType":"uint32","name":"maxHoneycomb","type":"uint32"},{"internalType":"uint32","name":"maxClaimableHoneycomb","type":"uint32"},{"internalType":"uint256","name":"honeycombPrice_ERC20","type":"uint256"},{"internalType":"uint256","name":"honeycombPrice_ETH","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"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":[],"name":"paymentToken","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicMintingTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"uint256[]","name":"randomWords","type":"uint256[]"}],"name":"rawFulfillRandomWords","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rng","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"beekeeper_","type":"address"}],"name":"setBeeKeeper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"distributeWithMint_","type":"bool"}],"name":"setDistributeWithMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_honeyCombPrice","type":"uint256"}],"name":"setHoneyCombPrice_ERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_honeyCombPrice","type":"uint256"}],"name":"setHoneyCombPrice_ETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"jani_","type":"address"}],"name":"setJani","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"keyHash_","type":"bytes32"}],"name":"setKeyHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_maxHoneycomb","type":"uint32"}],"name":"setMaxHoneycomb","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"subId_","type":"uint64"}],"name":"setSubId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalERC20Fees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalETHfees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_bearId","type":"uint256"}],"name":"wakeBear","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawERC20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a06040526001600055600a805465ffffffffffff60401b19166c0186a0000300000000000000001790553480156200003757600080fd5b50604051620035cc380380620035cc8339810160408190526200005a9162000103565b6001600160a01b039687166080819052600180549789166001600160a01b03199889161781556012805489169092179091556011805496891696881696909617909555600380549488169487169490941790935560028054928716928616929092179091556010805491909516931692909217909255600d556007805460ff191690911790556200018f565b80516001600160a01b0381168114620000fe57600080fd5b919050565b600080600080600080600060e0888a0312156200011f57600080fd5b6200012a88620000e6565b96506200013a60208901620000e6565b95506200014a60408901620000e6565b94506200015a60608901620000e6565b93506200016a60808901620000e6565b92506200017a60a08901620000e6565b915060c0880151905092959891949750929550565b60805161341a620001b260003960008181610d430152610d6b015261341a6000f3fe6080604052600436106101d65760003560e01c8063016ba71f146101db5780630b06edd1146101fd5780630fd904d21461021d578063136f259714610246578063158ef93e146102665780631fe543e3146102975780632260e6fe146102b757806322ce99bb146102d75780632a8d40e7146102f75780632ed6d5e8146103175780633013ce291461032c578063307579e6146103595780633289f44d146103795780633e2831fe1461039957806353f836db146103b95780635a1a525d146103e65780635d84bbfa146103fc57806369077bc51461040f57806369c98a781461042f578063708f1e3f1461045c57806372f58b311461047c5780637f8a9ebd1461049c578063836fb8d8146104bc5780638724d112146104d2578063924c3e0214610538578063950db0171461054e5780639854471014610561578063a053884314610581578063a59c9c271461059b578063b4231563146105bb578063bc197c8114610635578063c19fe3941461067d578063d56022d71461069d578063da090755146106bd578063dbe7e3bd146106dd578063e086e5ec14610725578063e5c9b6b41461073a578063e6b62e481461075a578063e7cc72441461077a578063f23a6e61146107d2578063f3f1c954146107ff575b600080fd5b3480156101e757600080fd5b506101fb6101f636600461296c565b61081f565b005b34801561020957600080fd5b506101fb6102183660046129d0565b61092b565b34801561022957600080fd5b50610233600d5481565b6040519081526020015b60405180910390f35b34801561025257600080fd5b506101fb61026136600461296c565b610a33565b34801561027257600080fd5b5060125461028790600160a01b900460ff1681565b604051901515815260200161023d565b3480156102a357600080fd5b506101fb6102b2366004612a89565b610d38565b3480156102c357600080fd5b506101fb6102d2366004612b67565b610daf565b3480156102e357600080fd5b506101fb6102f236600461296c565b610fda565b34801561030357600080fd5b50610233610312366004612bd9565b6110ba565b34801561032357600080fd5b50610233611197565b34801561033857600080fd5b5060025461034c906001600160a01b031681565b60405161023d9190612c53565b34801561036557600080fd5b5060115461034c906001600160a01b031681565b34801561038557600080fd5b50610233610394366004612c67565b6114b3565b3480156103a557600080fd5b506101fb6103b4366004612ca5565b6114e4565b3480156103c557600080fd5b506102336103d436600461296c565b60176020526000908152604090205481565b3480156103f257600080fd5b50610233600f5481565b61023361040a366004612c67565b61159c565b34801561041b57600080fd5b506101fb61042a366004612cd5565b6115f0565b34801561043b57600080fd5b5061023361044a36600461296c565b60156020526000908152604090205481565b34801561046857600080fd5b506101fb610477366004612cd5565b6116a8565b34801561048857600080fd5b506101fb610497366004612d07565b611760565b3480156104a857600080fd5b506101fb6104b7366004612d24565b611809565b3480156104c857600080fd5b50610233600e5481565b3480156104de57600080fd5b506104f26104ed36600461296c565b6118f6565b60405161023d9190600060a08201905082518252602083015160208301526040830151604083015260608301511515606083015260808301511515608083015292915050565b34801561054457600080fd5b5061023360085481565b61023361055c366004612bd9565b611986565b34801561056d57600080fd5b506101fb61057c36600461296c565b611a38565b34801561058d57600080fd5b506007546102879060ff1681565b3480156105a757600080fd5b5060105461034c906001600160a01b031681565b3480156105c757600080fd5b506106096105d636600461296c565b60136020526000908152604090208054600182015460028301546003909301549192909160ff8082169161010090041685565b60408051958652602086019490945292840191909152151560608301521515608082015260a00161023d565b34801561064157600080fd5b50610664610650366004612d82565b63bc197c8160e01b98975050505050505050565b6040516001600160e01b0319909116815260200161023d565b34801561068957600080fd5b506101fb610698366004612e40565b611ad3565b3480156106a957600080fd5b5060035461034c906001600160a01b031681565b3480156106c957600080fd5b5060015461034c906001600160a01b031681565b3480156106e957600080fd5b506107106106f836600461296c565b60166020526000908152604090205463ffffffff1681565b60405163ffffffff909116815260200161023d565b34801561073157600080fd5b50610233611c15565b34801561074657600080fd5b50610233610755366004612c67565b611d7b565b34801561076657600080fd5b506101fb61077536600461296c565b611dc6565b34801561078657600080fd5b506004546005546006546107aa9263ffffffff80821693600160201b909204169184565b6040805163ffffffff958616815294909316602085015291830152606082015260800161023d565b3480156107de57600080fd5b506106646107ed366004612e88565b63f23a6e6160e01b9695505050505050565b34801561080b57600080fd5b506101fb61081a36600461296c565b611fe2565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d148549061085e9084903390600401612f03565b602060405180830381865afa15801561087b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061089f9190612f1a565b6108e2576040805160208101839052015b60408051601f1981840301815290829052637ed408ef60e11b82526108d9913390600401612f37565b60405180910390fd5b60045460008381526014602052604090205463ffffffff909116111561091e576040516312db150b60e31b8152600481018390526024016108d9565b610927826120c2565b5050565b8085811461094c5760405163d917240d60e01b815260040160405180910390fd5b80841461096c5760405163d917240d60e01b815260040160405180910390fd5b60005b81811015610a285783838281811061098957610989612f97565b905060200281019061099b9190612fad565b159050610a1857610a18898989848181106109b8576109b8612f97565b90506020020160208101906109cd9190612d24565b8888858181106109df576109df612f97565b90506020020160208101906109f49190612d24565b878786818110610a0657610a06612f97565b90506020028101906102d29190612fad565b610a218161300c565b905061096f565b505050505050505050565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d1485490610a729084903390600401612f03565b602060405180830381865afa158015610a8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab39190612f1a565b610ac8576040805160208101839052016108b0565b60035460405163e985e9c560e01b81526001600160a01b039091169063e985e9c590610afa9033903090600401613025565b602060405180830381865afa158015610b17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3b9190612f1a565b610b9f5760405162461bcd60e51b815260206004820152602f60248201527f47696262206361766520746f207065726d697373696f6e7320746f206869626560448201526e393730ba32903cb7bab9103132b0b960891b60648201526084016108d9565b600354604051637921219560e11b81526001600160a01b039091169063f242432a90610bd69033903090879060019060040161303f565b600060405180830381600087803b158015610bf057600080fd5b505af1158015610c04573d6000803e3d6000fd5b505050506040518060a0016040528083815260200160008152602001426203f480610c2f9190613077565b815260006020808301829052604092830182905285825260138152908290208351815590830151600182015582820151600282015560608301516003909101805460809094015115156101000261ff00199215159290921661ffff19909416939093171790915560105490516350af9ca960e01b81526001600160a01b03909116906350af9ca990610cc990859060040190815260200190565b600060405180830381600087803b158015610ce357600080fd5b505af1158015610cf7573d6000803e3d6000fd5b505050507f61e2076007ad48356518822eacd1d612e86d447a447b5364260a4899119699a882604051610d2c91815260200190565b60405180910390a15050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610da557337f000000000000000000000000000000000000000000000000000000000000000060405163073e64fd60e21b81526004016108d9929190613025565b6109278282612186565b6000819003610dd1576040516301285a3f60e41b815260040160405180910390fd5b6010546040516353b266a760e01b81526000916001600160a01b0316906353b266a790610e0c908990899033908a908a908a906004016130bc565b602060405180830381865afa158015610e29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4d91906130fb565b90508063ffffffff16600003610e635750610fd3565b60008681526016602052604090205460045463ffffffff91821691600160201b90910416610e918284613118565b63ffffffff161115610ebb57600454610eb8908290600160201b900463ffffffff1661313c565b91505b610ecb878363ffffffff166121bf565b610edc33888463ffffffff16612352565b5060008781526016602052604081208054849290610f0190849063ffffffff16613118565b825463ffffffff9182166101009390930a928302919092021990911617905550601054604051633988606560e11b81526001600160a01b0390911690637310c0ca90610f59908a908a9087908a908a90600401613159565b600060405180830381600087803b158015610f7357600080fd5b505af1158015610f87573d6000803e3d6000fd5b5050604080518a815233602082015263ffffffff89168183015290517f704231104994d1018f9af3562464a1cea318a14992757b82667a73b8025a72d29350908190036060019150a150505b5050505050565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d14854906110199084903390600401612f03565b602060405180830381865afa158015611036573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105a9190612f1a565b61106f576040805160208101839052016108b0565b611078306124c7565b1561109657604051633497d0d160e21b815260040160405180910390fd5b60068290556040516000805160206133c583398151915290610d2c90600490613194565b60008082116110db5760405162461bcd60e51b81526004016108d9906131c5565b6110e587836121bf565b601054604051630c3c43e160e41b81526000916001600160a01b03169063c3c43e1090611120908b908b9033908c908c908c906004016130bc565b602060405180830381865afa15801561113d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111619190612f1a565b905080611181576040516301285a3f60e41b815260040160405180910390fd5b61118b8884612539565b98975050505050505050565b600080546001146111ba5760405162461bcd60e51b81526004016108d9906131f9565b600260005560075460ff16156111e25760405162461bcd60e51b81526004016108d99061321d565b6111f2634a414e4960e01b6125b0565b8061120d575061120d682122a2a5a2a2a822a960b91b6125b0565b6112295760405162461bcd60e51b81526004016108d990613260565b600b546001600160a01b03166112925760405162461bcd60e51b815260206004820152602860248201527f776974686472617746756e64733a3a6265656b65657065722061646472657373604482015267081b9bdd081cd95d60c21b60648201526084016108d9565b600c546001600160a01b03166112ba5760405162461bcd60e51b81526004016108d990613295565b6002546040516370a0823160e01b81526000916001600160a01b0316906370a08231906112eb903090600401612c53565b602060405180830381865afa158015611308573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132c91906132d8565b90506000811161137e5760405162461bcd60e51b815260206004820152601d60248201527f6f6f6761626f6f676120746865726573206e6f7468696e67206865726500000060448201526064016108d9565b6000611389826125e3565b600b546002549192506113a9916001600160a01b039081169116836125fa565b600c546002546040516370a0823160e01b8152611436926001600160a01b039081169216906370a08231906113e2903090600401612c53565b602060405180830381865afa1580156113ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142391906132d8565b6002546001600160a01b031691906125fa565b6002546040516370a0823160e01b81526001600160a01b03909116906370a0823190611466903090600401612c53565b602060405180830381865afa158015611483573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a791906132d8565b92505050600160005590565b601460205281600052604060002081815481106114cf57600080fd5b90600052602060002001600091509150505481565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d14854906115239084903390600401612f03565b602060405180830381865afa158015611540573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115649190612f1a565b611579576040805160208101839052016108b0565b50600a80546001600160401b0319166001600160401b0392909216919091179055565b60006115a883836121bf565b6000838152601360205260409020600201544210156115dd57604051634a6c0a8960e01b8152600481018490526024016108d9565b6115e78383612678565b90505b92915050565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d148549061162f9084903390600401612f03565b602060405180830381865afa15801561164c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116709190612f1a565b611685576040805160208101839052016108b0565b50600b80546001600160a01b0319166001600160a01b0392909216919091179055565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d14854906116e79084903390600401612f03565b602060405180830381865afa158015611704573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117289190612f1a565b61173d576040805160208101839052016108b0565b50600c80546001600160a01b0319166001600160a01b0392909216919091179055565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d148549061179f9084903390600401612f03565b602060405180830381865afa1580156117bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e09190612f1a565b6117f5576040805160208101839052016108b0565b506007805460ff1916911515919091179055565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d14854906118489084903390600401612f03565b602060405180830381865afa158015611865573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118899190612f1a565b61189e576040805160208101839052016108b0565b6118a7306124c7565b156118c557604051633497d0d160e21b815260040160405180910390fd5b6004805463ffffffff191663ffffffff84161781556040516000805160206133c583398151915291610d2c91613194565b61192c6040518060a001604052806000815260200160008152602001600081526020016000151581526020016000151581525090565b50600090815260136020908152604091829020825160a0810184528154815260018201549281019290925260028101549282019290925260039091015460ff80821615156060840152610100909104161515608082015290565b600061199287836121bf565b601054604051630c3c43e160e41b81526000916001600160a01b03169063c3c43e10906119cd908b908b9033908c908c908c906004016130bc565b602060405180830381865afa1580156119ea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0e9190612f1a565b905080611a2e576040516301285a3f60e41b815260040160405180910390fd5b61118b8884612678565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d1485490611a779084903390600401612f03565b602060405180830381865afa158015611a94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ab89190612f1a565b611acd576040805160208101839052016108b0565b50600955565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d1485490611b129084903390600401612f03565b602060405180830381865afa158015611b2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b539190612f1a565b611b68576040805160208101839052016108b0565b601254600160a01b900460ff1615611b925760405162dc149f60e41b815260040160405180910390fd5b6012805460ff60a01b1916600160a01b1790556009849055600a80546001600160401b0385166001600160401b0319909116179055816004611bd482826132f1565b9050507f7dbc7344a75a1d1f4bc8ee6fac2781b881cbc08d46f769c0871e951f0f71da836004604051611c079190613194565b60405180910390a150505050565b60008054600114611c385760405162461bcd60e51b81526004016108d9906131f9565b600260005560075460ff1615611c605760405162461bcd60e51b81526004016108d99061321d565b611c70634a414e4960e01b6125b0565b80611c8b5750611c8b682122a2a5a2a2a822a960b91b6125b0565b611ca75760405162461bcd60e51b81526004016108d990613260565b600b546001600160a01b0316611d0e5760405162461bcd60e51b815260206004820152602660248201527f77697468647261774554483a3a6265656b65657065722061646472657373206e6044820152651bdd081cd95d60d21b60648201526084016108d9565b600c546001600160a01b0316611d365760405162461bcd60e51b81526004016108d990613295565b6000611d41476125e3565b600b54909150611d5a906001600160a01b031682612700565b600c54611d70906001600160a01b031647612700565b505060016000554790565b6000611d8783836121bf565b600083815260136020526040902060020154421015611dbc57604051634a6c0a8960e01b8152600481018490526024016108d9565b6115e78383612539565b600081815260136020908152604091829020825160a0810184528154815260018201549281019290925260028101549282019290925260039091015460ff80821615156060840152610100909104161580156080830152611e3d576040516369133f8560e11b8152600481018390526024016108d9565b60045460008381526014602052604090205463ffffffff9091161115611e79576040516312db150b60e31b8152600481018390526024016108d9565b8060600151611e9e5760405163632c741160e01b8152600481018390526024016108d9565b60115460208201516040516331a9108f60e11b8152600481019190915233916001600160a01b031690636352211e90602401602060405180830381865afa158015611eed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f11919061335b565b6001600160a01b031614611f48576020810151604051633ebc311560e21b81526108d9918491600401918252602082015260400190565b6003548151604051637921219560e11b81526001600160a01b039092169163f242432a91611f7f913091339160019060040161303f565b600060405180830381600087803b158015611f9957600080fd5b505af1158015611fad573d6000803e3d6000fd5b505050507f4b1eecdb9f1779e7ccded8615ff395d9646bae73af9701451832828abe3b05a68233604051610d2c929190612f03565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d14854906120219084903390600401612f03565b602060405180830381865afa15801561203e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120629190612f1a565b612077576040805160208101839052016108b0565b612080306124c7565b1561209e57604051633497d0d160e21b815260040160405180910390fd5b60058290556040516000805160206133c583398151915290610d2c90600490613194565b601254600954600a546040516305d3b1d360e41b815260048101929092526001600160401b0381166024830152600160401b810461ffff166044830152600160501b900463ffffffff166064820152600260848201526000916001600160a01b031690635d3b1d309060a4016020604051808303816000875af115801561214d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217191906132d8565b60009081526017602052604090209190915550565b600082815260176020526040812054825190916121ba91839185916121ad576121ad612f97565b6020026020010151612751565b505050565b601254600160a01b900460ff166121e9576040516321c4e35760e21b815260040160405180910390fd5b600082815260136020908152604091829020825160a08101845281548082526001830154938201939093526002820154938101939093526003015460ff80821615156060850152610100909104161515608083015283146122885760405162461bcd60e51b8152602060048201526019602482015278446120626561722069736e27742068696265726e6174696e6760381b60448201526064016108d9565b8060800151156122ae576040516369133f8560e11b8152600481018490526024016108d9565b60045460008481526014602052604090205463ffffffff90911610156122ea57604051632c6bc1ab60e21b8152600481018490526024016108d9565b60045460008481526014602052604090205463ffffffff90911690612310908490613077565b111561233257604051636612aeb560e11b8152600481018490526024016108d9565b600082116121ba5760405162461bcd60e51b81526004016108d9906131c5565b600080601160009054906101000a90046001600160a01b03166001600160a01b03166375794a3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123cc91906132d8565b6011546040516343508b0560e01b81526001600160a01b038881166004830152602482018790529293509116906343508b0590604401600060405180830381600087803b15801561241c57600080fd5b505af1158015612430573d6000803e3d6000fd5b5050505060005b8381101561248a576000858152601460209081526040808320805460018101825590845282842001859055848352601590915290208590556124788261300c565b91506124838161300c565b9050612437565b5060045460008581526014602052604090205463ffffffff909116116124b3576124b3846120c2565b6124be600182613378565b95945050505050565b6001546040516379131a1960e01b81526000916001600160a01b0316906379131a19906124f8908590600401612c53565b602060405180830381865afa158015612515573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ea9190612f1a565b6005546007546000919060ff16156125625761255d612558848361338b565b612805565b61259d565b6125853330612571868561338b565b6002546001600160a01b03169291906128b3565b80600e60008282546125979190613077565b90915550505b6125a8338585612352565b949350505050565b600154604051632474521560e21b81526000916001600160a01b0316906391d14854906124f89085903390600401612f03565b60006115ea600d548361293690919063ffffffff16565b600060405163a9059cbb60e01b8152836004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806126725760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b60448201526064016108d9565b50505050565b600654600090612688838261338b565b34146126d05760405162461bcd60e51b81526020600482015260176024820152764d656b486f6e65793a3a45786163742065746820706c7360481b60448201526064016108d9565b60075460ff16156126e55761255d6000612805565b6126ef838261338b565b600f60008282546125979190613077565b600080600080600085875af19050806121ba5760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b60448201526064016108d9565b6000828152601460205260408120549061276b82846133a2565b6000858152601460205260408120805492935090918390811061279057612790612f97565b6000918252602080832091909101548783526013825260409283902060038101805460ff1916600190811790915581018290558351898152928301829052909350917fa1a7bb13b8503d61dfe9f285585ade3eca913687923f03c6288cf268f2b5de4d910160405180910390a1505050505050565b600061281c600d548361293690919063ffffffff16565b90506000612835600d543461293690919063ffffffff16565b9050811561287857600b5460025461285c916001600160a01b0391821691339116856128b3565b600c546128789033906001600160a01b03166125718587613378565b80156121ba57600b54612894906001600160a01b031682612700565b600c546121ba906001600160a01b03166128ae8334613378565b612700565b60006040516323b872dd60e01b81528460048201528360248201528260448201526020600060648360008a5af13d15601f3d1160016000511416171691505080610fd35760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b60448201526064016108d9565b60006115e78383670de0b6b3a7640000600082600019048411830215820261295d57600080fd5b50910281810615159190040190565b60006020828403121561297e57600080fd5b5035919050565b60008083601f84011261299757600080fd5b5081356001600160401b038111156129ae57600080fd5b6020830191508360208260051b85010111156129c957600080fd5b9250929050565b60008060008060008060006080888a0312156129eb57600080fd5b8735965060208801356001600160401b0380821115612a0957600080fd5b612a158b838c01612985565b909850965060408a0135915080821115612a2e57600080fd5b612a3a8b838c01612985565b909650945060608a0135915080821115612a5357600080fd5b50612a608a828b01612985565b989b979a50959850939692959293505050565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215612a9c57600080fd5b823591506020808401356001600160401b0380821115612abb57600080fd5b818601915086601f830112612acf57600080fd5b813581811115612ae157612ae1612a73565b8060051b604051601f19603f83011681018181108582111715612b0657612b06612a73565b604052918252848201925083810185019189831115612b2457600080fd5b938501935b82851015612b4257843584529385019392850192612b29565b8096505050505050509250929050565b63ffffffff81168114612b6457600080fd5b50565b600080600080600060808688031215612b7f57600080fd5b853594506020860135612b9181612b52565b93506040860135612ba181612b52565b925060608601356001600160401b03811115612bbc57600080fd5b612bc888828901612985565b969995985093965092949392505050565b60008060008060008060a08789031215612bf257600080fd5b863595506020870135612c0481612b52565b94506040870135612c1481612b52565b935060608701356001600160401b03811115612c2f57600080fd5b612c3b89828a01612985565b979a9699509497949695608090950135949350505050565b6001600160a01b0391909116815260200190565b60008060408385031215612c7a57600080fd5b50508035926020909101359150565b80356001600160401b0381168114612ca057600080fd5b919050565b600060208284031215612cb757600080fd5b6115e782612c89565b6001600160a01b0381168114612b6457600080fd5b600060208284031215612ce757600080fd5b8135612cf281612cc0565b9392505050565b8015158114612b6457600080fd5b600060208284031215612d1957600080fd5b8135612cf281612cf9565b600060208284031215612d3657600080fd5b8135612cf281612b52565b60008083601f840112612d5357600080fd5b5081356001600160401b03811115612d6a57600080fd5b6020830191508360208285010111156129c957600080fd5b60008060008060008060008060a0898b031215612d9e57600080fd5b8835612da981612cc0565b97506020890135612db981612cc0565b965060408901356001600160401b0380821115612dd557600080fd5b612de18c838d01612985565b909850965060608b0135915080821115612dfa57600080fd5b612e068c838d01612985565b909650945060808b0135915080821115612e1f57600080fd5b50612e2c8b828c01612d41565b999c989b5096995094979396929594505050565b600080600083850360c0811215612e5657600080fd5b84359350612e6660208601612c89565b92506080603f1982011215612e7a57600080fd5b506040840190509250925092565b60008060008060008060a08789031215612ea157600080fd5b8635612eac81612cc0565b95506020870135612ebc81612cc0565b9450604087013593506060870135925060808701356001600160401b03811115612ee557600080fd5b612ef189828a01612d41565b979a9699509497509295939492505050565b9182526001600160a01b0316602082015260400190565b600060208284031215612f2c57600080fd5b8151612cf281612cf9565b604081526000835180604084015260005b81811015612f655760208187018101516060868401015201612f48565b50600060608285018101919091526001600160a01b03949094166020840152601f01601f191690910190910192915050565b634e487b7160e01b600052603260045260246000fd5b6000808335601e19843603018112612fc457600080fd5b8301803591506001600160401b03821115612fde57600080fd5b6020019150600581901b36038213156129c957600080fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161301e5761301e612ff6565b5060010190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b808201808211156115ea576115ea612ff6565b81835260006001600160fb1b038311156130a357600080fd5b8260051b80836020870137939093016020019392505050565b86815263ffffffff86811660208301526001600160a01b03861660408301528416606082015260a06080820181905260009061118b908301848661308a565b60006020828403121561310d57600080fd5b8151612cf281612b52565b63ffffffff81811683821601908082111561313557613135612ff6565b5092915050565b63ffffffff82811682821603908082111561313557613135612ff6565b858152600063ffffffff80871660208401528086166040840152506080606083015261318960808301848661308a565b979650505050505050565b815463ffffffff8082168352602091821c169082015260018201546040820152600290910154606082015260800190565b6020808252601a908201527977687920796f75207472796e61206d696e74206e6f7468696e6760301b604082015260600190565b6020808252600a90820152695245454e5452414e435960b01b604082015260600190565b60208082526023908201527f646973747269626f6f7420772f206d696e74732073686f756c642062652066616040820152626c736560e81b606082015260800190565b6020808252601b908201527a1bdbd9d8589bdbd9d8481e5bdd4818d85b89dd08191bc81d1a185d602a1b604082015260600190565b60208082526023908201527f776974686472617746756e64733a3a6a616e692061646472657373206e6f74206040820152621cd95d60ea1b606082015260800190565b6000602082840312156132ea57600080fd5b5051919050565b81356132fc81612b52565b63ffffffff8116905081548163ffffffff198216178355602084013561332181612b52565b6001600160401b03199190911690911760209190911b63ffffffff60201b1617815560408201356001820155606090910135600290910155565b60006020828403121561336d57600080fd5b8151612cf281612cc0565b818103818111156115ea576115ea612ff6565b80820281158282048414176115ea576115ea612ff6565b6000826133bf57634e487b7160e01b600052601260045260246000fd5b50069056fed168ea0c23f28c79e79434ab061118c9928940fddf526760e980a0b2a9a5771ba26469706673582212200344dc3f07071f69f62ed717aecac472dcdf8f7ffc0181d2f5e417c1e379484d64736f6c63430008110033000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e6990900000000000000000000000021fdb00713c74147c2bb629de13531ab51a94b8b000000000000000000000000cb0477d1af5b8b05795d89d59f4667b59eae9244000000000000000000000000495f947276749ce646f68ac8c248420045cb7b5e00000000000000000000000064aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d500000000000000000000000010b27a31aa4d7544f89898ccaf3faf776f5671c40000000000000000000000000000000000000000000000000319522aba584000
Deployed Bytecode
0x6080604052600436106101d65760003560e01c8063016ba71f146101db5780630b06edd1146101fd5780630fd904d21461021d578063136f259714610246578063158ef93e146102665780631fe543e3146102975780632260e6fe146102b757806322ce99bb146102d75780632a8d40e7146102f75780632ed6d5e8146103175780633013ce291461032c578063307579e6146103595780633289f44d146103795780633e2831fe1461039957806353f836db146103b95780635a1a525d146103e65780635d84bbfa146103fc57806369077bc51461040f57806369c98a781461042f578063708f1e3f1461045c57806372f58b311461047c5780637f8a9ebd1461049c578063836fb8d8146104bc5780638724d112146104d2578063924c3e0214610538578063950db0171461054e5780639854471014610561578063a053884314610581578063a59c9c271461059b578063b4231563146105bb578063bc197c8114610635578063c19fe3941461067d578063d56022d71461069d578063da090755146106bd578063dbe7e3bd146106dd578063e086e5ec14610725578063e5c9b6b41461073a578063e6b62e481461075a578063e7cc72441461077a578063f23a6e61146107d2578063f3f1c954146107ff575b600080fd5b3480156101e757600080fd5b506101fb6101f636600461296c565b61081f565b005b34801561020957600080fd5b506101fb6102183660046129d0565b61092b565b34801561022957600080fd5b50610233600d5481565b6040519081526020015b60405180910390f35b34801561025257600080fd5b506101fb61026136600461296c565b610a33565b34801561027257600080fd5b5060125461028790600160a01b900460ff1681565b604051901515815260200161023d565b3480156102a357600080fd5b506101fb6102b2366004612a89565b610d38565b3480156102c357600080fd5b506101fb6102d2366004612b67565b610daf565b3480156102e357600080fd5b506101fb6102f236600461296c565b610fda565b34801561030357600080fd5b50610233610312366004612bd9565b6110ba565b34801561032357600080fd5b50610233611197565b34801561033857600080fd5b5060025461034c906001600160a01b031681565b60405161023d9190612c53565b34801561036557600080fd5b5060115461034c906001600160a01b031681565b34801561038557600080fd5b50610233610394366004612c67565b6114b3565b3480156103a557600080fd5b506101fb6103b4366004612ca5565b6114e4565b3480156103c557600080fd5b506102336103d436600461296c565b60176020526000908152604090205481565b3480156103f257600080fd5b50610233600f5481565b61023361040a366004612c67565b61159c565b34801561041b57600080fd5b506101fb61042a366004612cd5565b6115f0565b34801561043b57600080fd5b5061023361044a36600461296c565b60156020526000908152604090205481565b34801561046857600080fd5b506101fb610477366004612cd5565b6116a8565b34801561048857600080fd5b506101fb610497366004612d07565b611760565b3480156104a857600080fd5b506101fb6104b7366004612d24565b611809565b3480156104c857600080fd5b50610233600e5481565b3480156104de57600080fd5b506104f26104ed36600461296c565b6118f6565b60405161023d9190600060a08201905082518252602083015160208301526040830151604083015260608301511515606083015260808301511515608083015292915050565b34801561054457600080fd5b5061023360085481565b61023361055c366004612bd9565b611986565b34801561056d57600080fd5b506101fb61057c36600461296c565b611a38565b34801561058d57600080fd5b506007546102879060ff1681565b3480156105a757600080fd5b5060105461034c906001600160a01b031681565b3480156105c757600080fd5b506106096105d636600461296c565b60136020526000908152604090208054600182015460028301546003909301549192909160ff8082169161010090041685565b60408051958652602086019490945292840191909152151560608301521515608082015260a00161023d565b34801561064157600080fd5b50610664610650366004612d82565b63bc197c8160e01b98975050505050505050565b6040516001600160e01b0319909116815260200161023d565b34801561068957600080fd5b506101fb610698366004612e40565b611ad3565b3480156106a957600080fd5b5060035461034c906001600160a01b031681565b3480156106c957600080fd5b5060015461034c906001600160a01b031681565b3480156106e957600080fd5b506107106106f836600461296c565b60166020526000908152604090205463ffffffff1681565b60405163ffffffff909116815260200161023d565b34801561073157600080fd5b50610233611c15565b34801561074657600080fd5b50610233610755366004612c67565b611d7b565b34801561076657600080fd5b506101fb61077536600461296c565b611dc6565b34801561078657600080fd5b506004546005546006546107aa9263ffffffff80821693600160201b909204169184565b6040805163ffffffff958616815294909316602085015291830152606082015260800161023d565b3480156107de57600080fd5b506106646107ed366004612e88565b63f23a6e6160e01b9695505050505050565b34801561080b57600080fd5b506101fb61081a36600461296c565b611fe2565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d148549061085e9084903390600401612f03565b602060405180830381865afa15801561087b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061089f9190612f1a565b6108e2576040805160208101839052015b60408051601f1981840301815290829052637ed408ef60e11b82526108d9913390600401612f37565b60405180910390fd5b60045460008381526014602052604090205463ffffffff909116111561091e576040516312db150b60e31b8152600481018390526024016108d9565b610927826120c2565b5050565b8085811461094c5760405163d917240d60e01b815260040160405180910390fd5b80841461096c5760405163d917240d60e01b815260040160405180910390fd5b60005b81811015610a285783838281811061098957610989612f97565b905060200281019061099b9190612fad565b159050610a1857610a18898989848181106109b8576109b8612f97565b90506020020160208101906109cd9190612d24565b8888858181106109df576109df612f97565b90506020020160208101906109f49190612d24565b878786818110610a0657610a06612f97565b90506020028101906102d29190612fad565b610a218161300c565b905061096f565b505050505050505050565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d1485490610a729084903390600401612f03565b602060405180830381865afa158015610a8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab39190612f1a565b610ac8576040805160208101839052016108b0565b60035460405163e985e9c560e01b81526001600160a01b039091169063e985e9c590610afa9033903090600401613025565b602060405180830381865afa158015610b17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3b9190612f1a565b610b9f5760405162461bcd60e51b815260206004820152602f60248201527f47696262206361766520746f207065726d697373696f6e7320746f206869626560448201526e393730ba32903cb7bab9103132b0b960891b60648201526084016108d9565b600354604051637921219560e11b81526001600160a01b039091169063f242432a90610bd69033903090879060019060040161303f565b600060405180830381600087803b158015610bf057600080fd5b505af1158015610c04573d6000803e3d6000fd5b505050506040518060a0016040528083815260200160008152602001426203f480610c2f9190613077565b815260006020808301829052604092830182905285825260138152908290208351815590830151600182015582820151600282015560608301516003909101805460809094015115156101000261ff00199215159290921661ffff19909416939093171790915560105490516350af9ca960e01b81526001600160a01b03909116906350af9ca990610cc990859060040190815260200190565b600060405180830381600087803b158015610ce357600080fd5b505af1158015610cf7573d6000803e3d6000fd5b505050507f61e2076007ad48356518822eacd1d612e86d447a447b5364260a4899119699a882604051610d2c91815260200190565b60405180910390a15050565b336001600160a01b037f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e699091614610da557337f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e6990960405163073e64fd60e21b81526004016108d9929190613025565b6109278282612186565b6000819003610dd1576040516301285a3f60e41b815260040160405180910390fd5b6010546040516353b266a760e01b81526000916001600160a01b0316906353b266a790610e0c908990899033908a908a908a906004016130bc565b602060405180830381865afa158015610e29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4d91906130fb565b90508063ffffffff16600003610e635750610fd3565b60008681526016602052604090205460045463ffffffff91821691600160201b90910416610e918284613118565b63ffffffff161115610ebb57600454610eb8908290600160201b900463ffffffff1661313c565b91505b610ecb878363ffffffff166121bf565b610edc33888463ffffffff16612352565b5060008781526016602052604081208054849290610f0190849063ffffffff16613118565b825463ffffffff9182166101009390930a928302919092021990911617905550601054604051633988606560e11b81526001600160a01b0390911690637310c0ca90610f59908a908a9087908a908a90600401613159565b600060405180830381600087803b158015610f7357600080fd5b505af1158015610f87573d6000803e3d6000fd5b5050604080518a815233602082015263ffffffff89168183015290517f704231104994d1018f9af3562464a1cea318a14992757b82667a73b8025a72d29350908190036060019150a150505b5050505050565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d14854906110199084903390600401612f03565b602060405180830381865afa158015611036573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105a9190612f1a565b61106f576040805160208101839052016108b0565b611078306124c7565b1561109657604051633497d0d160e21b815260040160405180910390fd5b60068290556040516000805160206133c583398151915290610d2c90600490613194565b60008082116110db5760405162461bcd60e51b81526004016108d9906131c5565b6110e587836121bf565b601054604051630c3c43e160e41b81526000916001600160a01b03169063c3c43e1090611120908b908b9033908c908c908c906004016130bc565b602060405180830381865afa15801561113d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111619190612f1a565b905080611181576040516301285a3f60e41b815260040160405180910390fd5b61118b8884612539565b98975050505050505050565b600080546001146111ba5760405162461bcd60e51b81526004016108d9906131f9565b600260005560075460ff16156111e25760405162461bcd60e51b81526004016108d99061321d565b6111f2634a414e4960e01b6125b0565b8061120d575061120d682122a2a5a2a2a822a960b91b6125b0565b6112295760405162461bcd60e51b81526004016108d990613260565b600b546001600160a01b03166112925760405162461bcd60e51b815260206004820152602860248201527f776974686472617746756e64733a3a6265656b65657065722061646472657373604482015267081b9bdd081cd95d60c21b60648201526084016108d9565b600c546001600160a01b03166112ba5760405162461bcd60e51b81526004016108d990613295565b6002546040516370a0823160e01b81526000916001600160a01b0316906370a08231906112eb903090600401612c53565b602060405180830381865afa158015611308573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132c91906132d8565b90506000811161137e5760405162461bcd60e51b815260206004820152601d60248201527f6f6f6761626f6f676120746865726573206e6f7468696e67206865726500000060448201526064016108d9565b6000611389826125e3565b600b546002549192506113a9916001600160a01b039081169116836125fa565b600c546002546040516370a0823160e01b8152611436926001600160a01b039081169216906370a08231906113e2903090600401612c53565b602060405180830381865afa1580156113ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142391906132d8565b6002546001600160a01b031691906125fa565b6002546040516370a0823160e01b81526001600160a01b03909116906370a0823190611466903090600401612c53565b602060405180830381865afa158015611483573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a791906132d8565b92505050600160005590565b601460205281600052604060002081815481106114cf57600080fd5b90600052602060002001600091509150505481565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d14854906115239084903390600401612f03565b602060405180830381865afa158015611540573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115649190612f1a565b611579576040805160208101839052016108b0565b50600a80546001600160401b0319166001600160401b0392909216919091179055565b60006115a883836121bf565b6000838152601360205260409020600201544210156115dd57604051634a6c0a8960e01b8152600481018490526024016108d9565b6115e78383612678565b90505b92915050565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d148549061162f9084903390600401612f03565b602060405180830381865afa15801561164c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116709190612f1a565b611685576040805160208101839052016108b0565b50600b80546001600160a01b0319166001600160a01b0392909216919091179055565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d14854906116e79084903390600401612f03565b602060405180830381865afa158015611704573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117289190612f1a565b61173d576040805160208101839052016108b0565b50600c80546001600160a01b0319166001600160a01b0392909216919091179055565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d148549061179f9084903390600401612f03565b602060405180830381865afa1580156117bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e09190612f1a565b6117f5576040805160208101839052016108b0565b506007805460ff1916911515919091179055565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d14854906118489084903390600401612f03565b602060405180830381865afa158015611865573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118899190612f1a565b61189e576040805160208101839052016108b0565b6118a7306124c7565b156118c557604051633497d0d160e21b815260040160405180910390fd5b6004805463ffffffff191663ffffffff84161781556040516000805160206133c583398151915291610d2c91613194565b61192c6040518060a001604052806000815260200160008152602001600081526020016000151581526020016000151581525090565b50600090815260136020908152604091829020825160a0810184528154815260018201549281019290925260028101549282019290925260039091015460ff80821615156060840152610100909104161515608082015290565b600061199287836121bf565b601054604051630c3c43e160e41b81526000916001600160a01b03169063c3c43e10906119cd908b908b9033908c908c908c906004016130bc565b602060405180830381865afa1580156119ea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0e9190612f1a565b905080611a2e576040516301285a3f60e41b815260040160405180910390fd5b61118b8884612678565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d1485490611a779084903390600401612f03565b602060405180830381865afa158015611a94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ab89190612f1a565b611acd576040805160208101839052016108b0565b50600955565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d1485490611b129084903390600401612f03565b602060405180830381865afa158015611b2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b539190612f1a565b611b68576040805160208101839052016108b0565b601254600160a01b900460ff1615611b925760405162dc149f60e41b815260040160405180910390fd5b6012805460ff60a01b1916600160a01b1790556009849055600a80546001600160401b0385166001600160401b0319909116179055816004611bd482826132f1565b9050507f7dbc7344a75a1d1f4bc8ee6fac2781b881cbc08d46f769c0871e951f0f71da836004604051611c079190613194565b60405180910390a150505050565b60008054600114611c385760405162461bcd60e51b81526004016108d9906131f9565b600260005560075460ff1615611c605760405162461bcd60e51b81526004016108d99061321d565b611c70634a414e4960e01b6125b0565b80611c8b5750611c8b682122a2a5a2a2a822a960b91b6125b0565b611ca75760405162461bcd60e51b81526004016108d990613260565b600b546001600160a01b0316611d0e5760405162461bcd60e51b815260206004820152602660248201527f77697468647261774554483a3a6265656b65657065722061646472657373206e6044820152651bdd081cd95d60d21b60648201526084016108d9565b600c546001600160a01b0316611d365760405162461bcd60e51b81526004016108d990613295565b6000611d41476125e3565b600b54909150611d5a906001600160a01b031682612700565b600c54611d70906001600160a01b031647612700565b505060016000554790565b6000611d8783836121bf565b600083815260136020526040902060020154421015611dbc57604051634a6c0a8960e01b8152600481018490526024016108d9565b6115e78383612539565b600081815260136020908152604091829020825160a0810184528154815260018201549281019290925260028101549282019290925260039091015460ff80821615156060840152610100909104161580156080830152611e3d576040516369133f8560e11b8152600481018390526024016108d9565b60045460008381526014602052604090205463ffffffff9091161115611e79576040516312db150b60e31b8152600481018390526024016108d9565b8060600151611e9e5760405163632c741160e01b8152600481018390526024016108d9565b60115460208201516040516331a9108f60e11b8152600481019190915233916001600160a01b031690636352211e90602401602060405180830381865afa158015611eed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f11919061335b565b6001600160a01b031614611f48576020810151604051633ebc311560e21b81526108d9918491600401918252602082015260400190565b6003548151604051637921219560e11b81526001600160a01b039092169163f242432a91611f7f913091339160019060040161303f565b600060405180830381600087803b158015611f9957600080fd5b505af1158015611fad573d6000803e3d6000fd5b505050507f4b1eecdb9f1779e7ccded8615ff395d9646bae73af9701451832828abe3b05a68233604051610d2c929190612f03565b600154604051632474521560e21b81526923a0a6a2afa0a226a4a760b11b916001600160a01b0316906391d14854906120219084903390600401612f03565b602060405180830381865afa15801561203e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120629190612f1a565b612077576040805160208101839052016108b0565b612080306124c7565b1561209e57604051633497d0d160e21b815260040160405180910390fd5b60058290556040516000805160206133c583398151915290610d2c90600490613194565b601254600954600a546040516305d3b1d360e41b815260048101929092526001600160401b0381166024830152600160401b810461ffff166044830152600160501b900463ffffffff166064820152600260848201526000916001600160a01b031690635d3b1d309060a4016020604051808303816000875af115801561214d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217191906132d8565b60009081526017602052604090209190915550565b600082815260176020526040812054825190916121ba91839185916121ad576121ad612f97565b6020026020010151612751565b505050565b601254600160a01b900460ff166121e9576040516321c4e35760e21b815260040160405180910390fd5b600082815260136020908152604091829020825160a08101845281548082526001830154938201939093526002820154938101939093526003015460ff80821615156060850152610100909104161515608083015283146122885760405162461bcd60e51b8152602060048201526019602482015278446120626561722069736e27742068696265726e6174696e6760381b60448201526064016108d9565b8060800151156122ae576040516369133f8560e11b8152600481018490526024016108d9565b60045460008481526014602052604090205463ffffffff90911610156122ea57604051632c6bc1ab60e21b8152600481018490526024016108d9565b60045460008481526014602052604090205463ffffffff90911690612310908490613077565b111561233257604051636612aeb560e11b8152600481018490526024016108d9565b600082116121ba5760405162461bcd60e51b81526004016108d9906131c5565b600080601160009054906101000a90046001600160a01b03166001600160a01b03166375794a3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123cc91906132d8565b6011546040516343508b0560e01b81526001600160a01b038881166004830152602482018790529293509116906343508b0590604401600060405180830381600087803b15801561241c57600080fd5b505af1158015612430573d6000803e3d6000fd5b5050505060005b8381101561248a576000858152601460209081526040808320805460018101825590845282842001859055848352601590915290208590556124788261300c565b91506124838161300c565b9050612437565b5060045460008581526014602052604090205463ffffffff909116116124b3576124b3846120c2565b6124be600182613378565b95945050505050565b6001546040516379131a1960e01b81526000916001600160a01b0316906379131a19906124f8908590600401612c53565b602060405180830381865afa158015612515573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ea9190612f1a565b6005546007546000919060ff16156125625761255d612558848361338b565b612805565b61259d565b6125853330612571868561338b565b6002546001600160a01b03169291906128b3565b80600e60008282546125979190613077565b90915550505b6125a8338585612352565b949350505050565b600154604051632474521560e21b81526000916001600160a01b0316906391d14854906124f89085903390600401612f03565b60006115ea600d548361293690919063ffffffff16565b600060405163a9059cbb60e01b8152836004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806126725760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b60448201526064016108d9565b50505050565b600654600090612688838261338b565b34146126d05760405162461bcd60e51b81526020600482015260176024820152764d656b486f6e65793a3a45786163742065746820706c7360481b60448201526064016108d9565b60075460ff16156126e55761255d6000612805565b6126ef838261338b565b600f60008282546125979190613077565b600080600080600085875af19050806121ba5760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b60448201526064016108d9565b6000828152601460205260408120549061276b82846133a2565b6000858152601460205260408120805492935090918390811061279057612790612f97565b6000918252602080832091909101548783526013825260409283902060038101805460ff1916600190811790915581018290558351898152928301829052909350917fa1a7bb13b8503d61dfe9f285585ade3eca913687923f03c6288cf268f2b5de4d910160405180910390a1505050505050565b600061281c600d548361293690919063ffffffff16565b90506000612835600d543461293690919063ffffffff16565b9050811561287857600b5460025461285c916001600160a01b0391821691339116856128b3565b600c546128789033906001600160a01b03166125718587613378565b80156121ba57600b54612894906001600160a01b031682612700565b600c546121ba906001600160a01b03166128ae8334613378565b612700565b60006040516323b872dd60e01b81528460048201528360248201528260448201526020600060648360008a5af13d15601f3d1160016000511416171691505080610fd35760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b60448201526064016108d9565b60006115e78383670de0b6b3a7640000600082600019048411830215820261295d57600080fd5b50910281810615159190040190565b60006020828403121561297e57600080fd5b5035919050565b60008083601f84011261299757600080fd5b5081356001600160401b038111156129ae57600080fd5b6020830191508360208260051b85010111156129c957600080fd5b9250929050565b60008060008060008060006080888a0312156129eb57600080fd5b8735965060208801356001600160401b0380821115612a0957600080fd5b612a158b838c01612985565b909850965060408a0135915080821115612a2e57600080fd5b612a3a8b838c01612985565b909650945060608a0135915080821115612a5357600080fd5b50612a608a828b01612985565b989b979a50959850939692959293505050565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215612a9c57600080fd5b823591506020808401356001600160401b0380821115612abb57600080fd5b818601915086601f830112612acf57600080fd5b813581811115612ae157612ae1612a73565b8060051b604051601f19603f83011681018181108582111715612b0657612b06612a73565b604052918252848201925083810185019189831115612b2457600080fd5b938501935b82851015612b4257843584529385019392850192612b29565b8096505050505050509250929050565b63ffffffff81168114612b6457600080fd5b50565b600080600080600060808688031215612b7f57600080fd5b853594506020860135612b9181612b52565b93506040860135612ba181612b52565b925060608601356001600160401b03811115612bbc57600080fd5b612bc888828901612985565b969995985093965092949392505050565b60008060008060008060a08789031215612bf257600080fd5b863595506020870135612c0481612b52565b94506040870135612c1481612b52565b935060608701356001600160401b03811115612c2f57600080fd5b612c3b89828a01612985565b979a9699509497949695608090950135949350505050565b6001600160a01b0391909116815260200190565b60008060408385031215612c7a57600080fd5b50508035926020909101359150565b80356001600160401b0381168114612ca057600080fd5b919050565b600060208284031215612cb757600080fd5b6115e782612c89565b6001600160a01b0381168114612b6457600080fd5b600060208284031215612ce757600080fd5b8135612cf281612cc0565b9392505050565b8015158114612b6457600080fd5b600060208284031215612d1957600080fd5b8135612cf281612cf9565b600060208284031215612d3657600080fd5b8135612cf281612b52565b60008083601f840112612d5357600080fd5b5081356001600160401b03811115612d6a57600080fd5b6020830191508360208285010111156129c957600080fd5b60008060008060008060008060a0898b031215612d9e57600080fd5b8835612da981612cc0565b97506020890135612db981612cc0565b965060408901356001600160401b0380821115612dd557600080fd5b612de18c838d01612985565b909850965060608b0135915080821115612dfa57600080fd5b612e068c838d01612985565b909650945060808b0135915080821115612e1f57600080fd5b50612e2c8b828c01612d41565b999c989b5096995094979396929594505050565b600080600083850360c0811215612e5657600080fd5b84359350612e6660208601612c89565b92506080603f1982011215612e7a57600080fd5b506040840190509250925092565b60008060008060008060a08789031215612ea157600080fd5b8635612eac81612cc0565b95506020870135612ebc81612cc0565b9450604087013593506060870135925060808701356001600160401b03811115612ee557600080fd5b612ef189828a01612d41565b979a9699509497509295939492505050565b9182526001600160a01b0316602082015260400190565b600060208284031215612f2c57600080fd5b8151612cf281612cf9565b604081526000835180604084015260005b81811015612f655760208187018101516060868401015201612f48565b50600060608285018101919091526001600160a01b03949094166020840152601f01601f191690910190910192915050565b634e487b7160e01b600052603260045260246000fd5b6000808335601e19843603018112612fc457600080fd5b8301803591506001600160401b03821115612fde57600080fd5b6020019150600581901b36038213156129c957600080fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161301e5761301e612ff6565b5060010190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b808201808211156115ea576115ea612ff6565b81835260006001600160fb1b038311156130a357600080fd5b8260051b80836020870137939093016020019392505050565b86815263ffffffff86811660208301526001600160a01b03861660408301528416606082015260a06080820181905260009061118b908301848661308a565b60006020828403121561310d57600080fd5b8151612cf281612b52565b63ffffffff81811683821601908082111561313557613135612ff6565b5092915050565b63ffffffff82811682821603908082111561313557613135612ff6565b858152600063ffffffff80871660208401528086166040840152506080606083015261318960808301848661308a565b979650505050505050565b815463ffffffff8082168352602091821c169082015260018201546040820152600290910154606082015260800190565b6020808252601a908201527977687920796f75207472796e61206d696e74206e6f7468696e6760301b604082015260600190565b6020808252600a90820152695245454e5452414e435960b01b604082015260600190565b60208082526023908201527f646973747269626f6f7420772f206d696e74732073686f756c642062652066616040820152626c736560e81b606082015260800190565b6020808252601b908201527a1bdbd9d8589bdbd9d8481e5bdd4818d85b89dd08191bc81d1a185d602a1b604082015260600190565b60208082526023908201527f776974686472617746756e64733a3a6a616e692061646472657373206e6f74206040820152621cd95d60ea1b606082015260800190565b6000602082840312156132ea57600080fd5b5051919050565b81356132fc81612b52565b63ffffffff8116905081548163ffffffff198216178355602084013561332181612b52565b6001600160401b03199190911690911760209190911b63ffffffff60201b1617815560408201356001820155606090910135600290910155565b60006020828403121561336d57600080fd5b8151612cf281612cc0565b818103818111156115ea576115ea612ff6565b80820281158282048414176115ea576115ea612ff6565b6000826133bf57634e487b7160e01b600052601260045260246000fd5b50069056fed168ea0c23f28c79e79434ab061118c9928940fddf526760e980a0b2a9a5771ba26469706673582212200344dc3f07071f69f62ed717aecac472dcdf8f7ffc0181d2f5e417c1e379484d64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e6990900000000000000000000000021fdb00713c74147c2bb629de13531ab51a94b8b000000000000000000000000cb0477d1af5b8b05795d89d59f4667b59eae9244000000000000000000000000495f947276749ce646f68ac8c248420045cb7b5e00000000000000000000000064aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d500000000000000000000000010b27a31aa4d7544f89898ccaf3faf776f5671c40000000000000000000000000000000000000000000000000319522aba584000
-----Decoded View---------------
Arg [0] : _vrfCoordinator (address): 0x271682DEB8C4E0901D1a1550aD2e64D568E69909
Arg [1] : _gameRegistry (address): 0x21FDb00713C74147c2BB629De13531Ab51a94b8B
Arg [2] : _honeycombAddress (address): 0xCB0477d1Af5b8b05795D89D59F4667b59eAE9244
Arg [3] : _erc1155Address (address): 0x495f947276749Ce646f68AC8c248420045cb7b5e
Arg [4] : _paymentToken (address): 0x64aa3364F17a4D01c6f1751Fd97C2BD3D7e7f1D5
Arg [5] : _gatekeeper (address): 0x10b27a31AA4d7544F89898ccAf3Faf776F5671C4
Arg [6] : _honeyCombShare (uint256): 223300000000000000
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909
Arg [1] : 00000000000000000000000021fdb00713c74147c2bb629de13531ab51a94b8b
Arg [2] : 000000000000000000000000cb0477d1af5b8b05795d89d59f4667b59eae9244
Arg [3] : 000000000000000000000000495f947276749ce646f68ac8c248420045cb7b5e
Arg [4] : 00000000000000000000000064aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5
Arg [5] : 00000000000000000000000010b27a31aa4d7544f89898ccaf3faf776f5671c4
Arg [6] : 0000000000000000000000000000000000000000000000000319522aba584000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.