Feature Tip: Add private address tag to any address under My Name Tag !
ERC-721
Overview
Max Total Supply
2,007 TINYDMN
Holders
896
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
2 TINYDMNLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
TinyDaemons
Compiler Version
v0.8.15+commit.e14f2714
Optimization Enabled:
Yes with 100 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: TinyDaemons.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: TinyDaemons an LZ ERC 721 */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol"; import "./access/MaxAccess.sol"; import "./modules/TimeCop.sol"; import "./modules/NonblockingReceiver.sol"; import "./modules/ContractURI.sol"; import "./modules/PaymentSplitterV2.sol"; import "./modules/lzLlamas.sol"; import "./eip/2981/ERC2981Collection.sol"; contract TinyDaemons is MaxAccess , TimeCop , ContractURI , PaymentSplitterV2 , ERC2981Collection , lzLlamas , ERC721 , ERC721Burnable , NonblockingReceiver { using Strings for uint256; uint private gasForDestinationLzReceive = 350000; string base; event UpdatedBaseURI(string _old, string _new); event ThankYou(address user, uint amount); constructor() ERC721("TinyDaemons", "TINYDMN") {} modifier presaleChecks() { if (balanceOf(msg.sender) >= 4) { revert MaxSplaining({ reason: string( abi.encodePacked( "Token: Ok ", Strings.toHexString(uint160(msg.sender), 20), " you have ", Strings.toString(balanceOf(msg.sender)), " maximum at this time is 4." ) ) }); } _; } modifier saleChecks() { if (balanceOf(msg.sender) >= 10) { revert MaxSplaining({ reason: string( abi.encodePacked( "Token: Ok ", Strings.toHexString(uint160(msg.sender), 20), " you have ", Strings.toString(balanceOf(msg.sender)), " maximum at this time is 10." ) ) }); } _; } function presaleMint( uint quant ) external onlyPresale() presaleChecks() { if (quant > 2) { revert MaxSplaining({ reason: string( abi.encodePacked( "Token: Ok ", Strings.toHexString(uint160(msg.sender), 20), " you wanted to mint ", Strings.toString(quant), " 2 or less please." ) ) }); } for (uint x = 0; x < quant;) { // this is a little sneaky to ensure you can't mint 1-2-2 if (balanceOf(msg.sender) >= 4) { revert MaxSplaining({ reason: string( abi.encodePacked( "Token: Ok ", Strings.toHexString(uint160(msg.sender), 20), " you wanted to mint ", Strings.toString(quant), " that puts you at ", Strings.toString(quant + balanceOf(msg.sender)), " maximum at this time is 4." ) ) }); } // mint it _safeMint(msg.sender, _nextUp()); _oneRegularMint(); unchecked { ++x; } } } function publicMint() external onlySale() saleChecks() { _safeMint(msg.sender, _nextUp()); _oneRegularMint(); } function teamMint() external onlyDev() { uint quant = this.minterTeamMintsRemaining(); for (uint x = 0; x < quant;) { // mint it _safeMint(this.owner(), _nextUp()); _oneTeamMint(); unchecked { ++x; } } } function donate() external payable { // thank you emit ThankYou(msg.sender, msg.value); } // @notice: Function to receive ether, msg.data must be empty receive() external payable { // From PaymentSplitter.sol emit PaymentReceived(msg.sender, msg.value); } // @notice: Function to receive ether, msg.data is not empty fallback() external payable { // From PaymentSplitter.sol emit PaymentReceived(msg.sender, msg.value); } // @notice this is a public getter for ETH blance on contract function getBalance() external view returns (uint) { return address(this).balance; } // @notice: This sets the data for LZ minting // @param startNumber: What tokenID number to start with // @param authMint: How many to mint on this chain // @param teamMints: How many for team mint on this chain // @param string memory img: Provenance Hash of images in sequence // @param string memory json: Provenance Hash of metadata in sequence // @param newAddress: The address for the LZ Endpoint (see LZ docs) function setMinter ( uint startNumber , uint authMint , uint teamMints , string memory img , string memory json , address newAddress ) external onlyDev { _setLZLlamasEngine( startNumber , authMint , teamMints); _setProvenance( img , json); endpoint = ILayerZeroEndpoint(newAddress); } /* * #@+ . * -@@# =#*+=---+**- * %@@. .==*@@@@+- * =@@* -@@@* * .@@@ .#@@#: * *@@+ : :: -: +**@%@*=*- .: -- .: * @@% =%@@@#@@. -@@* +*: .*##+. @@- *@@= =%@@**++*+ .+##*. @@= *@@= .%@@% * +@@= #@@#--@@@. #@@* =@@+ =@@@%@+ +@@:#--*#- -#%%. -@@@#@* =@@:#-:*%*%@#-%= . * @@@ :#@@+.=@@@: .@@@ :*@@% =@@@%%= .@@#@- .#@* :@@@#%+ .%@#%= %@##*@#*@ * @@# .*@@@%#%-@@* +@@@#*@#@@#%@@+: .-#*@@@* *%% .... +@*: .-#*@@@* =@% :%%-: * =@@.=@@=-%#- +@%@#:-*#+.@@@*:.%++%%=.%@@+ @@%#%**#@%@@@@*@*+%%+.%@@* .%##@# * -==: .-: =%@@. ::. =%: =%##+-. .::::. -#- :-. * +@@@@= * .%@-*@# * %@.=@@. * =@%@%: * * @dev: This is the LayerZero functions for NonblockingReceiver.sol and more */ // @notice: This function transfers the nft from your address on the // source chain to the same address on the destination chain // @param _chainId: the uint16 of desination chain (see LZ docs) // @param tokenId: tokenID to be sent function traverseChains( uint16 _chainId , uint tokenId ) public payable { if (msg.sender != ownerOf(tokenId)) { revert Unauthorized(); } if (trustedRemoteLookup[_chainId].length == 0) { revert MaxSplaining({ reason: "Token: Ok the Dev didn't set this paramater, contact MaxFlowO2.eth." }); } // burn NFT, eliminating it from circulation on src chain _burn(tokenId); // fixes totalSupply() _subOne(); // abi.encode() the payload with the values to send bytes memory payload = abi.encode( msg.sender , tokenId); // encode adapterParams to specify more gas for the destination uint16 version = 1; bytes memory adapterParams = abi.encodePacked( version , gasForDestinationLzReceive); // get the fees we need to pay to LayerZero + Relayer to cover message delivery // you will be refunded for extra gas paid (uint messageFee, ) = endpoint.estimateFees( _chainId , address(this) , payload , false , adapterParams); // revert this transaction if the fees are not met if (messageFee > msg.value) { revert MaxSplaining({ reason: string( abi.encodePacked( "Token: ", Strings.toHexString(uint160(msg.sender), 20), " sent ", Strings.toString(msg.value), " instead of ", Strings.toString(messageFee) ) ) }); } // send the transaction to the endpoint endpoint.send{value: msg.value}( _chainId, // destination chainId trustedRemoteLookup[_chainId], // destination address of nft contract payload, // abi.encoded()'ed bytes payable(msg.sender), // refund address address(0x0), // 'zroPaymentAddress' unused for this adapterParams // txParameters ); } // @notice: just in case this fixed variable limits us from future integrations // @param newVal: new value for gas amount function setGasForDestinationLzReceive( uint newVal ) external onlyOwner { gasForDestinationLzReceive = newVal; } // @notice internal function to mint NFT from migration // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function _LzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) override internal { // decode (address toAddr, uint tokenId) = abi.decode(_payload, (address, uint)); // mint the tokens back into existence on destination chain _safeMint(toAddr, tokenId); // fixes totalSupply() _addOne(); } // @notice: will return gas value for LZ // @return: uint for gas value function currentLZGas() external view returns (uint256) { return gasForDestinationLzReceive; } /* * .=*#%@@@@%+ .:. * .-+*%@@@@@@@-:::-*+ =-=+**#%%@@@@%: -*%@@@@%*- #@@% * :*@%*=:-@@@* +%@@%##*+@@@@# =@@@@#=. =@: +@@@@@ * .@@@# =@@@%- -#@@@#: @@: +@@@@@@= * .@@@# *@@@* .#@@@%: =@@- =@@@@@@@% * :@@@* -*##%@@@@@#: :*##+ :@@# --@%@@= * .@@@@===- . .. *@@@@@+++. -@@% #%%@# * -#%@@@@@%##*= @@@ =@@@ -+*+- =@@@- =@@*. :@#@@. * +%@@@: =@@# #++@@:-*@@@@@= -@@@: .=%* =#@@# * %@@= =+ #@@:#=: .++*@@*.%@: .: :@@%. -*#- %#@@- * .@@@ -#%=.@@%%#. :@@* :--- @@@. :#+ .%@@@ * =@@+ .+%@%- *@@%%- *@@ =%%++ :@@* .-*+....:-*. -#@@#: * #@*.+@@@= :@@@@- +@%=#@@%- .%@- #%@@@@@@@@@@*. .++@@@@@* * -*#*+: -@@+. =###*: =- -**++++=-:::: :+**+=-. * * @dev: These are the ERC721 functions/overrides plus ERC165 at the end */ // @notice will update _baseURI() by onlyDeveloper() role // @param _base: Base for NFT's function setBaseURI( string memory _base ) public onlyDev() { string memory old = base; base = _base; emit UpdatedBaseURI(old, base); } // @notice: This override sets _base as the string for tokenURI(tokenId) function _baseURI() internal view override returns (string memory) { return base; } // @notice: This override is for making string/number now string/number.json // @param tokenId: tokenId to pull URI for function tokenURI( uint256 tokenId ) public view virtual override (ERC721) returns (string memory) { if (!_exists(tokenId)) { revert MaxSplaining({ reason: string( abi.encodePacked( "ERC721Metadata: URI query for ", Strings.toString(tokenId), " returns nonexistent token" ) ) }); } string memory baseURI = _baseURI(); string memory json = ".json"; return bytes(baseURI).length > 0 ? string( abi.encodePacked( baseURI , tokenId.toString() , json) ) : ""; } // @notice: This override is to correct totalSupply() // @param tokenId: tokenId to burn function burn( uint256 tokenId ) public virtual override(ERC721Burnable) { //solhint-disable-next-line max-line-length if (!_isApprovedOrOwner(_msgSender(), tokenId)) { revert MaxSplaining({ reason: string( abi.encodePacked( "ERC721Burnable: ", Strings.toHexString(uint160(msg.sender), 20), " is not owner nor approved" ) ) }); } _burn(tokenId); // fixes totalSupply() _subOne(); } // @notice: Standard override for ERC165 // @param interfaceId: interfaceId to check for compliance // @return: bool if interfaceId is supported function supportsInterface( bytes4 interfaceId ) public view virtual override ( ERC721 , IERC165 ) returns (bool) { return ( interfaceId == type(IRole).interfaceId || interfaceId == type(IDeveloper).interfaceId || interfaceId == type(IDeveloperV2).interfaceId || interfaceId == type(IOwner).interfaceId || interfaceId == type(IOwnerV2).interfaceId || interfaceId == type(IERC2981).interfaceId || interfaceId == type(IMAX2981).interfaceId || interfaceId == type(IMAXPaymentSplitter).interfaceId || interfaceId == type(IPaymentSplitter).interfaceId || interfaceId == type(IMAX721).interfaceId || interfaceId == type(ILlamas).interfaceId || interfaceId == type(lzILlamas).interfaceId || interfaceId == type(ITimeCop).interfaceId || interfaceId == type(IContractURI).interfaceId || interfaceId == type(IMAXContractURI).interfaceId || interfaceId == type(ILayerZeroReceiver).interfaceId || super.supportsInterface(interfaceId) ); } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: lzLlamas.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Solidity for Llama/BAYC Mint engine, does Provenance for Metadata/Images, for lzModules * Source: https://etherscan.io/address/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "./lzILlamas.sol"; import "../lib/PsuedoRand.sol"; import "../lib/CountersV2.sol"; abstract contract lzLlamas is lzILlamas { using PsuedoRand for PsuedoRand.Engine; using CountersV2 for CountersV2.Counter; PsuedoRand.Engine private llamas; CountersV2.Counter private tokensOnChain; uint private tokenStartNumber; event SetStartNumbers(uint numberToMint, uint startingID, uint endingID); // @dev this is for any team mint that happens, must be included in mint... function _oneTeamMint() internal { llamas.battersUp(); llamas.battersUpTeam(); tokensOnChain.increment(); } // @dev this is for any mint outside of a team mint, must be included in mint... function _oneRegularMint() internal { llamas.battersUp(); tokensOnChain.increment(); } // @dev this is to add one to on chain minted function _addOne() internal { tokensOnChain.increment(); } // @dev this is to substract one to on chain minted function _subOne() internal { tokensOnChain.decrement(); } // @dev this will set the boolean for minter status // @param toggle: bool for enabled or not function _setStatus( bool toggle ) internal { llamas.setStatus(toggle); } // @dev this will set the minter fees // @param number: uint for fees in wei. function _setMintFees( uint number ) internal { llamas.setFees(number); } // @dev this will set the mint engine // @param _startID: uint for startingID number (say 2000) // @param _mintingCap: uint for publicMint() capacity of this chain // @param _teamMints: uint for maximum teamMints() capacity on this chain function _setLZLlamasEngine( uint _startID , uint _mintingCap , uint _teamMints ) internal { tokenStartNumber = _startID; llamas.setMaxCap(_mintingCap); llamas.setMaxTeam(_teamMints); emit SetStartNumbers( _mintingCap , _startID , _mintingCap + _startID); } // @dev this will set the Provenance Hashes // @param string memory img - Provenance Hash of images in sequence // @param string memory json - Provenance Hash of metadata in sequence // @notice: This will set the start number as well, make sure to set MaxCap // also can be a hyperlink... sha3... ipfs.. whatever. function _setProvenance( string memory img , string memory json ) internal { llamas.setProvJSON(json); llamas.setProvIMG(img); llamas.setStartNumber(); } function _nextUp() internal view returns (uint) { return tokenStartNumber + llamas.mintID(); } // @dev will return status of Minter // @return - bool of active or not function minterStatus() external view virtual override returns (bool) { return llamas.status; } // @dev will return minting fees // @return - uint of mint costs in wei function minterFees() external view virtual override returns (uint) { return llamas.mintFee; } // @dev will return maximum mint capacity // @return - uint of maximum mints allowed function minterMaximumCapacity() external view virtual override returns (uint) { return llamas.maxCapacity; } // @dev will return maximum mint capacity // @return - uint of maximum mints allowed function minterMintsRemaining() external view virtual returns (uint) { return llamas.maxCapacity - llamas.showMinted(); } // @dev will return maximum mint capacity // @return - uint of maximum mints allowed function minterCurrentMints() external view virtual returns (uint) { return llamas.showMinted(); } // @dev will return maximum "team minting" capacity // @return - uint of maximum airdrops or team mints allowed function minterMaximumTeamMints() external view virtual override returns (uint) { return llamas.maxTeamMints; } // @dev will return "team mints" left // @return - uint of remaing airdrops or team mints function minterTeamMintsRemaining() external view virtual override returns (uint) { return llamas.maxTeamMints - llamas.showTeam(); } // @dev will return "team mints" count // @return - uint of airdrops or team mints done function minterTeamMintsCount() external view virtual override returns (uint) { return llamas.showTeam(); } // @dev: will return total supply for mint // @return: uint for this mint function totalSupply() external view virtual override returns (uint256) { return tokensOnChain.current(); } // @dev: will return Provenance hash of images // @return: string memory of the Images Hash (sha256) function RevealProvenanceImages() external view virtual override returns (string memory) { return llamas.ProvenanceIMG; } // @dev: will return Provenance hash of metadata // @return: string memory of the Metadata Hash (sha256) function RevealProvenanceJSON() external view virtual override returns (string memory) { return llamas.ProvenanceJSON; } // @dev: will return starting number for mint // @return: uint of the start number function RevealStartNumber() external view virtual override returns (uint256) { return llamas.startNumber; } // @dev: this is will show the start number for this chain's start number // @return: uint of start number function lzStartNumber() external view virtual override returns (uint256) { return tokenStartNumber; } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: lzILlamas.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Interface for Llama/BAYC Mint engine, does Provenance for Metadata/Images * Source: https://etherscan.io/address/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "./ILlamas.sol"; /// /// @dev Interface for the ILlamas Standard v2.0 for LayerZero /// this includes metadata with images /// interface lzILlamas is ILlamas { // @dev: this is will show the start number for this chain's start number // @return: uint of start number function lzStartNumber() external view returns (uint256); }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: TimeCop.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Time based mechanism for Solidity */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "./ITimeCop.sol"; import "../access/MaxAccess.sol"; abstract contract TimeCop is MaxAccess , ITimeCop { uint private startPresale; uint private presaleDuration; event PresaleSet(uint start, uint length); function setPresale( uint time , uint duration ) external onlyDev() { startPresale = time; presaleDuration = duration; emit PresaleSet(time, duration); } function showPresaleStart() external view virtual override (ITimeCop) returns (uint) { return startPresale; } function showStart() external view virtual override (ITimeCop) returns (uint) { return startPresale + presaleDuration; } function showPresaleTimes() external view virtual override (ITimeCop) returns (uint, uint) { return ( startPresale , startPresale + presaleDuration ); } modifier onlyPresale() { if (block.timestamp < startPresale) { revert TooSoonJunior({ yourTime: block.timestamp , hitTime: startPresale }); } if (block.timestamp >= startPresale + presaleDuration) { revert TooLateBoomer({ yourTime: block.timestamp , hitTime: startPresale + presaleDuration }); } _; } modifier onlySale() { if (block.timestamp < startPresale + presaleDuration) { revert TooSoonJunior({ yourTime: block.timestamp , hitTime: startPresale + presaleDuration }); } if (startPresale == 0) { revert MaxSplaining({ reason: "TimeCop: You've been Time Copped. NGL onlyDev() hasn't set the time" }); } _; } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: PaymentSplitterV2.sol * @author: OG was OZ, rewritten by Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Updated to add/subtract payees */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "./IMAXPaymentSplitter.sol"; import "../access/MaxAccess.sol"; import "@openzeppelin/contracts/utils/Address.sol"; // Removal of SafeMath due to ^0.8.0 standards, not needed /** * @title PaymentSplitter * @dev This contract allows to split Ether payments among a group of accounts. The sender does not need to be aware * that the Ether will be split in this way, since it is handled transparently by the contract. * * The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each * account to a number of shares. Of all the Ether that this contract receives, each account will then be able to claim * an amount proportional to the percentage of total shares they were assigned. * * `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the * accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release} * function. */ abstract contract PaymentSplitterV2 is MaxAccess , IMAXPaymentSplitter { event PayeeAdded(address account, uint256 shares); event PaymentReleased(address to, uint256 amount); event PaymentReceived(address from, uint256 amount); event PayeeRemoved(address account, uint256 shares); event PayeesReset(); uint256 private _totalShares; uint256 private _totalReleased; mapping(address => uint256) private _shares; mapping(address => uint256) private _released; address[] private _payees; /** * @dev The Ether received will be logged with {PaymentReceived} events. Note that these events are not fully * reliable: it's possible for a contract to receive Ether without triggering this function. This only affects the * reliability of the events, and not the actual splitting of Ether. * * To learn more about this see the Solidity documentation for * https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function[fallback * functions]. * * receive() external payable virtual { * emit PaymentReceived(msg.sender, msg.value); * } * * // Fallback function is called when msg.data is not empty * // Added to PaymentSplitter.sol * fallback() external payable { * emit PaymentReceived(msg.sender, msg.value); * } * * receive() and fallback() to be handled at final contract */ /** * @dev Getter for the total shares held by payees. */ function totalShares() external view virtual override returns (uint256) { return _totalShares; } /** * @dev Getter for the total amount of Ether already released. */ function totalReleased() external view virtual override returns (uint256) { return _totalReleased; } /** * @dev Getter for the amount of shares held by an account. */ function shares( address account ) external view virtual override returns (uint256) { return _shares[account]; } /** * @dev Getter for the amount of Ether already released to a payee. */ function released( address account ) external view virtual override returns (uint256) { return _released[account]; } /** * @dev Getter for the address of the payee number `index`. */ function payee( uint256 index ) external view virtual override returns (address) { return _payees[index]; } /** * @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the * total shares and their previous withdrawals. */ // This function was updated from "account" to msg.sender function claim() external virtual override { address check = msg.sender; if (_shares[check] == 0) { revert MaxSplaining({ reason: string( abi.encodePacked( "PaymentSplitter: ", Strings.toHexString(uint160(msg.sender), 20), " has no shares." ) ) }); } uint256 totalReceived = address(this).balance + _totalReleased; uint256 payment = (totalReceived * _shares[check]) / _totalShares - _released[check]; if (payment == 0) { revert MaxSplaining({ reason: string( abi.encodePacked( "PaymentSplitter: ", Strings.toHexString(uint160(msg.sender), 20), " is not due payment." ) ) }); } _released[check] = _released[check] + payment; _totalReleased = _totalReleased + payment; Address.sendValue(payable(check), payment); emit PaymentReleased(check, payment); } // now the internal logic of this contract /** * @dev Add a new payee to the contract. * @param account The address of the payee to add. * @param shares_ The number of shares owned by the payee. */ // This function was updated to internal function _addPayee( address account , uint256 shares_ ) internal { if (account == address(0)) { revert MaxSplaining({ reason: "PaymentSplitter: account is the zero address" }); } else if (shares_ == 0) { revert MaxSplaining({ reason: "PaymentSplitter: shares are 0" }); } else if (_shares[account] > 0) { revert MaxSplaining({ reason: string( abi.encodePacked( "PaymentSplitter: ", Strings.toHexString(uint160(account), 20), " already has ", Strings.toString(_shares[account]), " shares." ) ) }); } _payees.push(account); _shares[account] = shares_; _totalShares = _totalShares + shares_; emit PayeeAdded(account, shares_); } /** * @dev finds index in array * @param account The address of the payee */ function _findIndex( address account ) internal view returns (uint index) { uint max = _payees.length; for (uint i = 0; i < max;) { if (_payees[i] == account) { index = i; } unchecked { ++i; } } } /** * @dev Remove a payee to the contract. * @param account The address of the payee to remove. * leaves all payment data in the contract incase something was claimed */ function _removePayee( address account ) internal { if (account == address(0)) { revert MaxSplaining({ reason: "PaymentSplitter: account is the zero address" }); } // This finds the payee in the array _payees and removes it uint remove = _findIndex(account); address last = _payees[_payees.length - 1]; _payees[remove] = last; _payees.pop(); uint removeTwo = _shares[account]; _shares[account] = 0; _totalShares = _totalShares - removeTwo; emit PayeeRemoved(account, removeTwo); } /** * @dev clears all data in PaymentSplitterV2 * leaves all payment data in the contract incase something was claimed */ function _clearAll() internal { uint max = _payees.length; for (uint i = 0; i < max;) { address account = _payees[i]; _shares[account] = 0; unchecked { ++i; } } delete _totalShares; delete _payees; emit PayeesReset(); } // @notice: This adds a payment split to PaymentSplitterV2.sol // @param newSplit: Address of payee // @param newShares: Shares to send user function addSplit ( address newSplit , uint256 newShares ) external virtual override onlyDev() { _addPayee(newSplit, newShares); } // @notice: This removes a payment split on PaymentSplitterV2.sol // @param remSplit: Address of payee to remove function removeSplit ( address remSplit ) external virtual override onlyDev() { _removePayee(remSplit); } // @notice: This removes all payment splits on PaymentSplitterV2.sol function clearSplits() external virtual override onlyDev() { _clearAll(); } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: NonblockingReceiver.sol * @author: OG?? Rewrite: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: LZ non blocking reciever * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code * Remember to set all the trustedRemoteLookups with trustedRemoteLookup[chainID] = contract address */ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; import "./ILayerZeroReceiver.sol"; import "./ILayerZeroEndpoint.sol"; import "../access/MaxAccess.sol"; abstract contract NonblockingReceiver is MaxAccess, ILayerZeroReceiver { ILayerZeroEndpoint internal endpoint; struct FailedMessages { uint payloadLength; bytes32 payloadHash; } mapping(uint16 => mapping(bytes => mapping(uint => FailedMessages))) public failedMessages; mapping(uint16 => bytes) public trustedRemoteLookup; event TrustedRemoteSet( uint16 _chainId , bytes _trustedRemote); event MessageFailed( uint16 _srcChainId , bytes _srcAddress , uint64 _nonce , bytes _payload); // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) external override { if (msg.sender != address(endpoint)) { revert MaxSplaining({ reason: "NonblockingReceiver: This message did not come from the endpoint, you failed, I won!" }); } if ( _srcAddress.length != trustedRemoteLookup[_srcChainId].length || keccak256(_srcAddress) != keccak256(trustedRemoteLookup[_srcChainId]) ) { revert MaxSplaining({ reason: "NonblockingReceiver: This message did not come from a trusted contract, you failed, I won!" }); } // try-catch all errors/exceptions // having failed messages does not block messages passing try this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload) { // do nothing } catch { // error or exception failedMessages[_srcChainId][_srcAddress][_nonce] = FailedMessages(_payload.length, keccak256(_payload)); emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload); } } // @notice this is the catch all above (should be an internal?) // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function onLzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) public { // only internal transaction if (msg.sender != address(this)) { revert MaxSplaining({ reason: "NonblockingReceiver: This message did not come internally, you failed, I won!" }); } // handle incoming message _LzReceive( _srcChainId, _srcAddress, _nonce, _payload); } // @notice internal function to do something in the main contract // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function _LzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) virtual internal; // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function _lzSend( uint16 _dstChainId , bytes memory _payload , address payable _refundAddress , address _zroPaymentAddress , bytes memory _txParam ) internal { endpoint.send{value: msg.value}( _dstChainId , trustedRemoteLookup[_dstChainId] , _payload, _refundAddress , _zroPaymentAddress , _txParam); } // @notice this is to retry a failed message on LayerZero // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _nonce - the ordered message nonce // @param _payload - the payload to be retried function retryMessage( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes calldata _payload ) external payable { // assert there is message to retry FailedMessages storage failedMsg = failedMessages[_srcChainId][_srcAddress][_nonce]; if (failedMsg.payloadHash == bytes32(0)) { revert MaxSplaining({ reason: "NonblockingReceiver: This message was already executed, you failed, I won!" }); } if ( _payload.length != failedMsg.payloadLength || keccak256(_payload) != failedMsg.payloadHash ) { revert MaxSplaining({ reason: "NonblockingReceiver: This message was not stored, you failed, I won!" }); } // clear the stored message failedMsg.payloadLength = 0; failedMsg.payloadHash = bytes32(0); // execute the message. revert if it fails again this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setTrustedRemote( uint16 _chainId , bytes calldata _trustedRemote ) external onlyDev() { trustedRemoteLookup[_chainId] = _trustedRemote; emit TrustedRemoteSet(_chainId, _trustedRemote); } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ITimeCop.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Time based interface for Solidity */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; interface ITimeCop is IERC165 { function setPresale( uint time , uint duration ) external; function showPresaleStart() external view returns (uint); function showStart() external view returns (uint); function showPresaleTimes() external view returns (uint, uint); }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: IPaymentSplitter.sol * @author: OG was OZ, rewritten by Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Interface for PaymentSplitter.sol */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; /// /// @dev Interface for PaymentSplitter /// interface IPaymentSplitter is IERC165 { /** * @dev Getter for the total shares held by payees. */ function totalShares() external returns (uint256); /** * @dev Getter for the total amount of Ether already released. */ function totalReleased() external returns (uint256); /** * @dev Getter for the amount of shares held by an account. */ function shares( address account ) external view returns (uint256); /** * @dev Getter for the amount of Ether already released to a payee. */ function released( address account ) external view returns (uint256); /** * @dev Getter for the address of the payee number `index`. */ function payee( uint256 index ) external view returns (address); /** * @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the * total shares and their previous withdrawals. */ // This function was updated from "account" to msg.sender function claim() external; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: IMAXPaymentSplitter.sol * @author: OG was OZ, rewritten by Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Interface extension for PaymentSplitter.sol */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "./IPaymentSplitter.sol"; /// /// @dev Interface extension for PaymentSplitter /// interface IMAXPaymentSplitter is IPaymentSplitter { // @notice: This adds a payment split to PaymentSplitterV2.sol // @param newSplit: Address of payee // @param newShares: Shares to send user function addSplit ( address newSplit , uint256 newShares ) external; // @notice: This removes a payment split on PaymentSplitterV2.sol // @param remSplit: Address of payee to remove function removeSplit ( address remSplit ) external; // @notice: This removes all payment splits on PaymentSplitterV2.sol function clearSplits() external; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: IMAXContractURI.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Extension for IContractURI */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "./IContractURI.sol"; interface IMAXContractURI is IContractURI { // @notice this sets the contractURI, set to internal // @param URI - string to URI of Contract Metadata // @notice: let the metadata be in this format // { // "name": Project's name, // "description": Project's Description, // "image": pfp for project, // "external_link": web url, // "seller_fee_basis_points": 100 -> Indicates a 1% seller fee. // "fee_recipient": checksum address // } function setContractURI( string memory URI ) external; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: IMAX721.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Interface for UX/UI */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; /// /// @dev Interface for @MaxFlowO2's Contracts /// interface IMAX721 is IERC165 { // @dev will return status of Minter // @return - bool of active or not function minterStatus() external view returns (bool); // @dev will return minting fees // @return - uint of mint costs in wei function minterFees() external view returns (uint); // @dev will return maximum mint capacity // @return - uint of maximum mints allowed function minterMaximumCapacity() external view returns (uint); // @dev will return maximum "team minting" capacity // @return - uint of maximum airdrops or team mints allowed function minterMaximumTeamMints() external view returns (uint); // @dev will return "team mints" left // @return - uint of remaing airdrops or team mints function minterTeamMintsRemaining() external view returns (uint); // @dev will return "team mints" count // @return - uint of airdrops or team mints done function minterTeamMintsCount() external view returns (uint); // @dev: will return total supply for mint // @return: uint for this mint function totalSupply() external view returns (uint256); }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILlamas.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Interface for Llama/BAYC Mint engine, does Provenance for Metadata/Images * Source: https://etherscan.io/address/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "./IMAX721.sol"; /// /// @dev Interface for the ILlamas Standard v2.0 /// this includes metadata with images /// interface ILlamas is IMAX721{ // @dev: will return Provenance hash of images // @return: string memory of the Images Hash (sha256) function RevealProvenanceImages() external view returns (string memory); // @dev: will return Provenance hash of metadata // @return: string memory of the Metadata Hash (sha256) function RevealProvenanceJSON() external view returns (string memory); // @dev: will return starting number for mint // @return: uint of the start number function RevealStartNumber() external view returns (uint256); }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroUserApplicationConfig.sol * @author: OG?? Rewrite: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Interface for LayerZeroUserApplicationConfig * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroUserApplicationConfig { // @notice set the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _configType - type of configuration. every messaging library has its own convention. // @param _config - configuration in the bytes. can encode arbitrary content. function setConfig( uint16 _version , uint16 _chainId , uint _configType , bytes calldata _config ) external; // @notice set the send() LayerZero messaging library version to _version // @param _version - new messaging library version function setSendVersion( uint16 _version ) external; // @notice set the lzReceive() LayerZero messaging library version to _version // @param _version - new messaging library version function setReceiveVersion( uint16 _version ) external; // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload // @param _srcChainId - the chainId of the source chain // @param _srcAddress - the contract address of the source contract at the source chain function forceResumeReceive( uint16 _srcChainId , bytes calldata _srcAddress ) external; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroReceiver.sol * @author: OG?? Rewrite: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Interface for LayerZeroReceiver * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroReceiver { // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes calldata _srcAddress , uint64 _nonce , bytes calldata _payload ) external; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroEndpoint.sol * @author: OG?? Rewrite: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Interface for LayerZeroEndpoint * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; import "./ILayerZeroUserApplicationConfig.sol"; interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig { // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function send( uint16 _dstChainId , bytes calldata _destination , bytes calldata _payload , address payable _refundAddress , address _zroPaymentAddress , bytes calldata _adapterParams ) external payable; // @notice used by the messaging library to publish verified payload // @param _srcChainId - the source chain identifier // @param _srcAddress - the source contract (as bytes) at the source chain // @param _dstAddress - the address on destination chain // @param _nonce - the unbound message ordering nonce // @param _gasLimit - the gas limit for external contract execution // @param _payload - verified payload to send to the destination contract function receivePayload( uint16 _srcChainId , bytes calldata _srcAddress , address _dstAddress , uint64 _nonce , uint _gasLimit , bytes calldata _payload ) external; // @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function getInboundNonce( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (uint64); // @notice get the outboundNonce from this source chain which, consequently, is always an EVM // @param _srcAddress - the source chain contract address function getOutboundNonce( uint16 _dstChainId , address _srcAddress ) external view returns (uint64); // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery // @param _dstChainId - the destination chain identifier // @param _userApplication - the user app address on this EVM chain // @param _payload - the custom message to send over LayerZero // @param _payInZRO - if false, user app pays the protocol fee in native token // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain function estimateFees( uint16 _dstChainId , address _userApplication , bytes calldata _payload , bool _payInZRO , bytes calldata _adapterParam ) external view returns ( uint nativeFee , uint zroFee); // @notice get this Endpoint's immutable source identifier function getChainId() external view returns (uint16); // @notice the interface to retry failed message on this Endpoint destination // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _payload - the payload to be retried function retryPayload( uint16 _srcChainId , bytes calldata _srcAddress , bytes calldata _payload ) external; // @notice query if any STORED payload (message blocking) at the endpoint. // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function hasStoredPayload( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (bool); // @notice query if the _libraryAddress is valid for sending msgs. // @param _userApplication - the user app address on this EVM chain function getSendLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the _libraryAddress is valid for receiving msgs. // @param _userApplication - the user app address on this EVM chain function getReceiveLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the non-reentrancy guard for send() is on // @return true if the guard is on. false otherwise function isSendingPayload() external view returns (bool); // @notice query if the non-reentrancy guard for receive() is on // @return true if the guard is on. false otherwise function isReceivingPayload() external view returns (bool); // @notice get the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _userApplication - the contract address of the user application // @param _configType - type of configuration. every messaging library has its own convention. function getConfig( uint16 _version , uint16 _chainId , address _userApplication , uint _configType ) external view returns (bytes memory); // @notice get the send() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getSendVersion( address _userApplication ) external view returns (uint16); // @notice get the lzReceive() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getReceiveVersion( address _userApplication ) external view returns (uint16); }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: IContractURI.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Purely for OpenSea compliance */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; /// /// @dev Interface for the OpenSea Standard /// interface IContractURI is IERC165{ // @notice contractURI() called for retreval of // OpenSea style collections pages // @return - the string URI of the contract, usually IPFS function contractURI() external view returns (string memory); }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ContractURI.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Purely for OpenSea compliance */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "./IMAXContractURI.sol"; import "../access/MaxAccess.sol"; /// /// @dev Implementation of IMAXContractURI.sol /// abstract contract ContractURI is MaxAccess , IMAXContractURI { event ContractURIChange( string _old , string _new); string private thisContractURI; // @notice this sets the contractURI, set to internal // @param newURI - string to URI of Contract Metadata // @notice: let the metadata be in this format //{ // "name": Project's name, // "description": Project's Description, // "image": pfp for project, // "external_link": web url, // "seller_fee_basis_points": 100 -> Indicates a 1% seller fee. // "fee_recipient": checksum address //} function _setContractURI( string memory newURI ) internal { string memory old = thisContractURI; thisContractURI = newURI; emit ContractURIChange(old, thisContractURI); } // @notice this clears the contractURI, set to internal function _clearContractURI() internal { string memory old = thisContractURI; delete thisContractURI; emit ContractURIChange(old, thisContractURI); } // @notice this sets the contractURI, set to internal // @param URI - string to URI of Contract Metadata // @notice: let the metadata be in this format // { // "name": Project's name, // "description": Project's Description, // "image": pfp for project, // "external_link": web url, // "seller_fee_basis_points": 100 -> Indicates a 1% seller fee. // "fee_recipient": checksum address // } function setContractURI( string memory URI ) external virtual override onlyDev() { _setContractURI(URI); } // @notice contractURI() called for retreval of // OpenSea style collections pages // @return - string thisContractURI function contractURI() external view virtual override(IContractURI) returns (string memory) { return thisContractURI; } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Roles.sol * @author: OpenZeppelin, rewrite by Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Library for MaxAcess.sol * @dev: Rewritten for gas optimization, and from abstract -> library, added * multiple types instead of a solo role. * Original source: * https://github.com/hiddentao/openzeppelin-solidity/blob/master/contracts/access/Roles.sol * * Include with 'using Roles for Roles.Role;' */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts/utils/Strings.sol"; library Roles { // @dev: this is Unauthorized(), basically a catch all, zero description // @notice: 0x82b42900 bytes4 of this error Unauthorized(); // @dev: this is MaxSplaining(), giving you a reason, aka require(param, "reason") // @param reason: Use the "Contract name: error" // @notice: 0x0661b792 bytes4 of this error MaxSplaining( string reason ); event RoleChanged(bytes4 _type, address _user, bool _status); // 0x0baaa7ab struct Role { mapping(address => mapping(bytes4 => bool)) bearer; } /** * @dev give an account access to this role */ function add(Role storage role, bytes4 _type, address account) internal { if (account == address(0)) { revert Unauthorized(); } else if (has(role, _type, account)) { revert MaxSplaining({ reason: string( abi.encodePacked( "Lib Roles: ", Strings.toHexString(uint160(account), 20), " already has role ", Strings.toHexString(uint32(_type), 4) ) ) }); } role.bearer[account][_type] = true; emit RoleChanged(_type, account, true); } /** * @dev remove an account's access to this role */ function remove(Role storage role, bytes4 _type, address account) internal { if (account == address(0)) { revert Unauthorized(); } else if (!has(role, _type, account)) { revert MaxSplaining({ reason: string( abi.encodePacked( "Lib Roles: ", Strings.toHexString(uint160(account), 20), " does not have role ", Strings.toHexString(uint32(_type), 4) ) ) }); } role.bearer[account][_type] = false; emit RoleChanged(_type, account, false); } /** * @dev check if an account has this role * @return bool */ function has(Role storage role, bytes4 _type, address account) internal view returns (bool) { if (account == address(0)) { revert Unauthorized(); } return role.bearer[account][_type]; } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: PsuedoRand.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Library for Llama/BAYC Mint engine... * basically a random start point and a bookends mint to start * i.e. 0-2999 start at 500 -> 2999, then 0 -> 499. * * Covers IMAX721.sol and Illamas.sol * * Include with 'using PsuedoRand for PsuedoRand.Engine;' */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "./CountersV2.sol"; library PsuedoRand { using CountersV2 for CountersV2.Counter; event SetProvenanceIMG(string _new, string _old); event SetProvenanceJSON(string _new, string _old); event SetStartNumber(uint _new); event SetMaxCapacity(uint _new, uint _old); event SetMaxTeamMint(uint _new, uint _old); event SetMintFees(uint _new, uint _old); event SetStatus(bool _new); // @dev: this is MaxSplaining(), giving you a reason, aka require(param, "reason") // @param reason: Use the "Contract name: error" // @notice: 0x0661b792 bytes4 of this error MaxSplaining( string reason ); struct Engine { uint256 mintFee; uint256 startNumber; uint256 maxCapacity; uint256 maxTeamMints; string ProvenanceIMG; string ProvenanceJSON; CountersV2.Counter currentMinted; CountersV2.Counter currentTeam; bool status; } function setProvJSON( Engine storage engine , string memory provJSON ) internal { string memory old = engine.ProvenanceJSON; engine.ProvenanceJSON = provJSON; emit SetProvenanceJSON(provJSON, old); } function setProvIMG( Engine storage engine , string memory provIMG ) internal { string memory old = engine.ProvenanceIMG; engine.ProvenanceIMG = provIMG; emit SetProvenanceIMG(provIMG, old); } function setStartNumber( Engine storage engine ) internal { if (engine.maxCapacity == 0) { revert MaxSplaining({ reason : "PsuedoRandom Lib: Maximum Capacity not set!" }); } engine.startNumber = uint( keccak256( abi.encodePacked( block.timestamp , msg.sender , engine.ProvenanceIMG , engine.ProvenanceJSON , block.difficulty))) % engine.maxCapacity; emit SetStartNumber(engine.startNumber); } function setMaxCap( Engine storage engine , uint256 max ) internal { uint old = engine.maxCapacity; engine.maxCapacity = max; emit SetMaxCapacity(max, old); } function setMaxTeam( Engine storage engine , uint256 max ) internal { uint old = engine.maxTeamMints; engine.maxTeamMints = max; emit SetMaxTeamMint(max, old); } function setFees( Engine storage engine , uint256 max ) internal { uint old = engine.mintFee; engine.mintFee = max; emit SetMintFees(max, old); } function setStatus( Engine storage engine , bool change ) internal { engine.status = change; emit SetStatus(change); } function mintID( Engine storage engine ) internal view returns (uint256) { return (engine.startNumber + engine.currentMinted.current()) % engine.maxCapacity; } function showTeam( Engine storage engine ) internal view returns (uint256) { return engine.currentTeam.current(); } function showMinted( Engine storage engine ) internal view returns (uint256) { return engine.currentMinted.current(); } function battersUpTeam( Engine storage engine ) internal { engine.currentTeam.increment(); } function battersUp( Engine storage engine ) internal { engine.currentMinted.increment(); } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: CountersV2.sol * @author Matt Condon (@shrugs), Edits by Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Provides counters that can only be incremented, decremented, reset or set. * This can be used e.g. to track the number of elements in a mapping, issuing ERC721 ids * or counting request ids. * * Edited by @MaxFlowO2 for more NFT functionality on 13 Jan 2022 * added .set(uint) so if projects need to start at say 1 or some random number they can * and an event log for numbers being reset or set. * * Include with `using CountersV2 for CountersV2.Counter;` */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; library CountersV2 { // @dev: this is MaxSplaining(), giving you a reason, aka require(param, "reason") // @param reason: Use the "Contract name: error" // @notice: 0x0661b792 bytes4 of this error MaxSplaining( string reason ); event CounterNumberChangedTo(uint _number); struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current( Counter storage counter ) internal view returns (uint256) { return counter._value; } function increment( Counter storage counter ) internal { unchecked { ++counter._value; } } function decrement( Counter storage counter ) internal { uint256 value = counter._value; if (value == 0) { revert MaxSplaining({ reason : "CountersV2: No negatives in uints" }); } unchecked { --counter._value; } } function reset( Counter storage counter ) internal { counter._value = 0; emit CounterNumberChangedTo(counter._value); } function set( Counter storage counter , uint number ) internal { counter._value = number; emit CounterNumberChangedTo(counter._value); } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: MaxErrors.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Custom errors for all contracts, minus libraries */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; abstract contract MaxErrors { // @dev: this is Unauthorized(), basically a catch all, zero description // @notice: 0x82b42900 bytes4 of this error Unauthorized(); // @dev: this is MaxSplaining(), giving you a reason, aka require(param, "reason") // @param reason: Use the "Contract name: error" // @notice: 0x0661b792 bytes4 of this error MaxSplaining( string reason ); // @dev: this is TooSoonJunior(), using times // @param yourTime: should almost always be block.timestamp // @param hitTime: the time you should have started // @notice: 0xf3f82ac5 bytes4 of this error TooSoonJunior( uint yourTime , uint hitTime ); // @dev: this is TooLateBoomer(), using times // @param yourTime: should almost always be block.timestamp // @param hitTime: the time you should have ended // @notice: 0x43c540ef bytes4 of this error TooLateBoomer( uint yourTime , uint hitTime ); }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: IMAX2981.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: IERC2981 Extension */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "./IERC2981.sol"; interface IMAX2981 is IERC2981 { // @notice: This sets the contract as royalty reciever (useful with abstract PaymentSplitter) // @param permille: Percentage you want so 3.5% -> 35 function setRoyaltiesThis ( uint permille ) external; // @notice: This sets royalties per EIP-2981 // @param newAddress: Sets the address for royalties // @param permille: Percentage you want so 3.5% -> 35 function setRoyalties ( address newAddress , uint256 permille ) external; // @notice: This clears all EIP-2981 royalties (address(0) and 0%) function clearRoyalties() external; }
/*** * ███████╗██╗██████╗ ██████╗ █████╗ █████╗ ██╗ * ██╔════╝██║██╔══██╗ ╚════██╗██╔══██╗██╔══██╗███║ * █████╗ ██║██████╔╝█████╗ █████╔╝╚██████║╚█████╔╝╚██║ * ██╔══╝ ██║██╔═══╝ ╚════╝██╔═══╝ ╚═══██║██╔══██╗ ██║ * ███████╗██║██║ ███████╗ █████╔╝╚█████╔╝ ██║ * ╚══════╝╚═╝╚═╝ ╚══════╝ ╚════╝ ╚════╝ ╚═╝ * Zach Burks, James Morgan, Blaine Malone, James Seibel, * "EIP-2981: NFT Royalty Standard," * Ethereum Improvement Proposals, no. 2981, September 2020. [Online serial]. * Available: https://eips.ethereum.org/EIPS/eip-2981. */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; /// /// @dev Interface for the NFT Royalty Standard /// interface IERC2981 is IERC165 { // @notice Called with the sale price to determine how much royalty // is owed and to whom. // @param _tokenId - the NFT asset queried for royalty information // @param _salePrice - the sale price of the NFT asset specified by _tokenId // @return receiver - address of who should be sent the royalty payment // @return royaltyAmount - the royalty payment amount for _salePrice function royaltyInfo( uint256 _tokenId , uint256 _salePrice ) external view returns ( address receiver , uint256 royaltyAmount ); }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ERC2981Collection.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Use case for EIP 2981, steered more towards NFT Collections as a whole */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "./IMAX2981.sol"; import "../../access/MaxAccess.sol"; abstract contract ERC2981Collection is MaxAccess, IMAX2981 { address private royaltyAddress; uint256 private royaltyPermille; event royalatiesSet( uint value , address recipient ); // the internals to do logic flows later // @dev to set roaylties on contract via EIP 2891 // @param _receiver, address of recipient // @param _permille, permille xx.x -> xxx value function _setRoyalties( address _receiver , uint256 _permille ) internal { if (_permille >= 1000 || _permille == 0) { revert MaxSplaining({ reason: string( abi.encodePacked( "ERC2981Collection: ", Strings.toHexString(uint160(msg.sender), 20), " submitted ", Strings.toString(_permille), " and that is out of bounds!" ) ) }); } royaltyAddress = _receiver; royaltyPermille = _permille; emit royalatiesSet(royaltyPermille, royaltyAddress); } // @dev to remove royalties from contract function _removeRoyalties() internal { delete royaltyAddress; delete royaltyPermille; emit royalatiesSet(royaltyPermille, royaltyAddress); } // Logic for this contract (abstract) // @notice: This sets the contract as royalty reciever (useful with abstract PaymentSplitter) // @param permille: Percentage you want so 3.5% -> 35 function setRoyaltiesThis ( uint permille ) external virtual override onlyOwner() { _setRoyalties(address(this), permille); } // @notice: This sets royalties per EIP-2981 // @param newAddress: Sets the address for royalties // @param permille: Percentage you want so 3.5% -> 35 function setRoyalties ( address newAddress , uint256 permille ) external virtual override onlyOwner() { _setRoyalties(newAddress, permille); } // @notice: This clears all EIP-2981 royalties (address(0) and 0%) function clearRoyalties() external virtual override onlyOwner() { _removeRoyalties(); } // @dev Override for royaltyInfo(uint256, uint256) // @param _tokenId, uint of token ID to be checked // @param _salePrice, uint of amount of sale // @return receiver, address of recipient // @return royaltyAmount, amount royalties recieved function royaltyInfo( uint256 _tokenId , uint256 _salePrice ) external view virtual override returns ( address receiver , uint256 royaltyAmount ) { receiver = royaltyAddress; royaltyAmount = _salePrice * royaltyPermille / 1000; } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: MaxAccess.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Access control based off EIP 173/roles from OZ */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "./IOwnerV2.sol"; import "./IDeveloperV2.sol"; import "./IRole.sol"; import "../lib/Roles.sol"; import "../errors/MaxErrors.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; abstract contract MaxAccess is MaxErrors , IRole , IOwnerV2 , IDeveloperV2 { using Roles for Roles.Role; Roles.Role private contractRoles; // bytes4 caluclated as follows // bytes4(keccak256(bytes(signature))) // developer() => 0xca4b208b // owner() => 0x8da5cb5b // admin() => 0xf851a440 // was using trailing () for caluclations bytes4 constant private DEVS = 0xca4b208b; bytes4 constant private PENDING_DEVS = 0xca4b208a; // DEVS - 1 bytes4 constant private OWNERS = 0x8da5cb5b; bytes4 constant private PENDING_OWNERS = 0x8da5cb5a; // OWNERS - 1 bytes4 constant private ADMIN = 0xf851a440; // @dev you can sub your own address here... this is MaxFlowO2.eth // these are for displays anyways, and init(). address private TheDev = address(0x4CE69fd760AD0c07490178f9a47863Dc0358cCCD); address private TheOwner = address(0x44f750eB065596c150B3479B1DF6957da300a332); constructor() { // supercedes all the logic below contractRoles.add(ADMIN, address(this)); _grantRole(ADMIN, TheDev); _grantRole(OWNERS, TheOwner); _grantRole(DEVS, TheDev); } // modifiers modifier onlyRole(bytes4 role) { if (_checkRole(role, msg.sender) || _checkRole(ADMIN, msg.sender)) { _; } else { revert MaxSplaining({ reason: string( abi.encodePacked( "MaxAccess: You are a not an ", Strings.toHexString(uint32(role), 4), " or ", Strings.toHexString(uint32(ADMIN), 4), " ", Strings.toHexString(uint160(msg.sender), 20) ) ) }); } } modifier onlyDev() { if (!_checkRole(DEVS, msg.sender)) { revert Unauthorized(); } _; } modifier onlyOwner() { if (!_checkRole(OWNERS, msg.sender)) { revert Unauthorized(); } _; } // internal logic first // (sets the tone later, and for later contracts) // @dev: this is the bool for checking if the account has a role via lib roles.sol // @param role: bytes4 of the role to check for // @param account: address of account to check // @return: bool true/false function _checkRole( bytes4 role , address account ) internal view virtual returns (bool) { return contractRoles.has(role, account); } // @dev: this is the internal to grant roles // @param role: bytes4 of the role // @param account: address of account to add function _grantRole( bytes4 role , address account ) internal virtual { contractRoles.add(role, account); } // @dev: this is the internal to revoke roles // @param role: bytes4 of the role // @param account: address of account to remove function _revokeRole( bytes4 role , address account ) internal virtual { contractRoles.remove(role, account); } // @dev: Returns `true` if `account` has been granted `role`. // @param role: Bytes4 of a role // @param account: Address to check // @return: bool true/false if account has role function hasRole( bytes4 role , address account ) external view virtual override returns (bool) { return _checkRole(role, account); } // @dev: Returns the admin role that controls a role // @param role: Role to check // @return: admin role function getRoleAdmin( bytes4 role ) external view virtual override returns (bytes4) { return ADMIN; } // @dev: Grants `role` to `account` // @param role: Bytes4 of a role // @param account: account to give role to function grantRole( bytes4 role , address account ) external virtual override onlyRole(role) { if (role == PENDING_DEVS) { // locks out pending devs from mass swapping roles if (_checkRole(PENDING_DEVS, msg.sender)) { revert MaxSplaining({ reason: string( abi.encodePacked( "MaxAccess: You are a pending developer() ", Strings.toHexString(uint160(msg.sender), 20), " you can not grant role ", Strings.toHexString(uint32(role), 4), " to ", Strings.toHexString(uint160(account), 20) ) ) }); } } if (role == PENDING_OWNERS) { // locks out pending owners from mass swapping roles if (_checkRole(PENDING_OWNERS, msg.sender)) { revert MaxSplaining({ reason: string( abi.encodePacked( "MaxAccess: You are a pending owner() ", Strings.toHexString(uint160(msg.sender), 20), " you can not grant role ", Strings.toHexString(uint32(role), 4), " to ", Strings.toHexString(uint160(account), 20) ) ) }); } } _grantRole(role, account); } // @dev: Revokes `role` from `account` // @param role: Bytes4 of a role // @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external virtual override onlyRole(role) { if (role == PENDING_DEVS) { // locks out pending devs from mass swapping roles if (account != msg.sender) { revert MaxSplaining({ reason: string( abi.encodePacked( "MaxAccess: You are a pending developer() ", Strings.toHexString(uint160(msg.sender), 20), " you can not revoke role ", Strings.toHexString(uint32(role), 4), " to ", Strings.toHexString(uint160(account), 20) ) ) }); } } if (role == PENDING_OWNERS) { // locks out pending owners from mass swapping roles if (account != msg.sender) { revert MaxSplaining({ reason: string( abi.encodePacked( "MaxAccess: You are a pending owner() ", Strings.toHexString(uint160(msg.sender), 20), " you can not revoke role ", Strings.toHexString(uint32(role), 4), " to ", Strings.toHexString(uint160(account), 20) ) ) }); } } _revokeRole(role, account); } // @dev: Renounces `role` from `account` // @param role: Bytes4 of a role // @param account: account to renounce role from function renounceRole( bytes4 role ) external virtual override onlyRole(role) { address user = msg.sender; _revokeRole(role, user); } // Now the classic onlyDev() + "V2" suggested by auditors // @dev: Classic "EIP-173" but for onlyDev() // @return: Developer of contract function developer() external view virtual override returns (address) { return TheDev; } // @dev: This renounces your role as onlyDev() function renounceDeveloper() external virtual override onlyRole(DEVS) { address user = msg.sender; _revokeRole(DEVS, user); } // @dev: Classic "EIP-173" but for onlyDev() // @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external virtual override onlyRole(DEVS) { address user = msg.sender; _grantRole(DEVS, newDeveloper); _revokeRole(DEVS, user); } // @dev: This accepts the push-pull method of onlyDev() function acceptDeveloper() external virtual override onlyRole(PENDING_DEVS) { address user = msg.sender; _revokeRole(PENDING_DEVS, user); _grantRole(DEVS, user); } // @dev: This declines the push-pull method of onlyDev() function declineDeveloper() external virtual override onlyRole(PENDING_DEVS) { address user = msg.sender; _revokeRole(PENDING_DEVS, user); } // @dev: This starts the push-pull method of onlyDev() // @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external virtual override onlyRole(DEVS) { _grantRole(PENDING_DEVS, newDeveloper); } // @dev: This changes the display of developer() // @param newDisplay: new display addrss for developer() function setDeveloper( address newDisplay ) external onlyDev() { if (!_checkRole(DEVS, newDisplay)) { revert MaxSplaining({ reason: string( abi.encodePacked( "MaxAccess: The address ", Strings.toHexString(uint160(newDisplay), 20), " is not a developer and does not have the role ", Strings.toHexString(uint32(DEVS), 4), " there ", Strings.toHexString(uint160(msg.sender), 20) ) ) }); } TheDev = newDisplay; } // Now the classic onlyOwner() + "V2" suggested by auditors // @dev: Classic "EIP-173" getter for owner() // @return: owner of contract function owner() external view virtual override returns (address) { return TheOwner; } // @dev: This renounces your role as onlyOwner() function renounceOwnership() external virtual override onlyRole(OWNERS) { address user = msg.sender; _revokeRole(OWNERS, user); } // @dev: Classic "EIP-173" but for onlyOwner() // @param newOwner: addres of new pending Developer role function transferOwnership( address newOwner ) external virtual override onlyRole(OWNERS) { address user = msg.sender; _grantRole(OWNERS, newOwner); _revokeRole(OWNERS, user); } // @dev: This accepts the push-pull method of onlyOwner() function acceptOwnership() external virtual override onlyRole(PENDING_OWNERS) { address user = msg.sender; _revokeRole(PENDING_OWNERS, user); _grantRole(OWNERS, user); } // @dev: This declines the push-pull method of onlyOwner() function declineOwnership() external virtual override onlyRole(PENDING_OWNERS) { address user = msg.sender; _revokeRole(PENDING_OWNERS, user); } // @dev: This starts the push-pull method of onlyOwner() // @param newOwner: addres of new pending developer role function pushOwnership( address newOwner ) external virtual override onlyRole(OWNERS) { _grantRole(PENDING_OWNERS, newOwner); } // @dev: This changes the display of Ownership() // @param newDisplay: new display addrss for Ownership() function setOwner( address newDisplay ) external onlyOwner() { if (!_checkRole(OWNERS, newDisplay)) { revert MaxSplaining({ reason: string( abi.encodePacked( "MaxAccess: The address ", Strings.toHexString(uint160(newDisplay), 20), " is not an owner and does not have the role ", Strings.toHexString(uint32(OWNERS), 4), " there ", Strings.toHexString(uint160(msg.sender), 20) ) ) }); } TheOwner = newDisplay; } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: IRole.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Interface for MaxAccess version of roles */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; interface IRole is IERC165 { // @dev: Returns `true` if `account` has been granted `role`. // @param role: Bytes4 of a role // @param account: Address to check // @return: bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool); // @dev: Returns the admin role that controls a role // @param role: Role to check // @return: admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4); // @dev: Grants `role` to `account` // @param role: Bytes4 of a role // @param account: account to give role to function grantRole( bytes4 role , address account ) external; // @dev: Revokes `role` from `account` // @param role: Bytes4 of a role // @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external; // @dev: Renounces `role` from `account` // @param role: Bytes4 of a role // @param account: account to renounce role from function renounceRole( bytes4 role ) external; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: IOwnerV2.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Interface V2 for onlyOwner() role, suggested by Auditors... */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "./IOwner.sol"; interface IOwnerV2 is IOwner { // @dev: This accepts the push-pull method of onlyOwner() function acceptOwnership() external; // @dev: This declines the push-pull method of onlyOwner() function declineOwnership() external; // @dev: This starts the push-pull method of onlyOwner() // @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: IOwner.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Interface for onlyOwner() role */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; interface IOwner is IERC165 { // @dev: Classic "EIP-173" getter for owner() // @return: owner of contract function owner() external view returns (address); // @dev: This is the classic "EIP-173" method of setting onlyOwner() function renounceOwnership() external; // @dev: This is the classic "EIP-173" method of setting onlyOwner() // @param newOwner: addres of new pending owner role function transferOwnership( address newOwner ) external; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: IDeveloperV2.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Interface V2 for onlyDev() role, suggested by Auditors... */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "./IDeveloper.sol"; interface IDeveloperV2 is IDeveloper { // @dev: This accepts the push-pull method of onlyDev() function acceptDeveloper() external; // @dev: This declines the push-pull method of onlyDev() function declineDeveloper() external; // @dev: This starts the push-pull method of onlyDev() // @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: IDeveloper.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Interface for onlyDev() role */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; interface IDeveloper is IERC165 { // @dev: Classic "EIP-173" but for onlyDev() // @return: Developer of contract function developer() external view returns (address); // @dev: This renounces your role as onlyDev() function renounceDeveloper() external; // @dev: Classic "EIP-173" but for onlyDev() // @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (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 v4.4.0 (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.0 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @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] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (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 v4.4.0 (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/ERC721Burnable.sol) pragma solidity ^0.8.0; import "../ERC721.sol"; import "../../../utils/Context.sol"; /** * @title ERC721 Burnable Token * @dev ERC721 Token that can be irreversibly burned (destroyed). */ abstract contract ERC721Burnable is Context, ERC721 { /** * @dev Burns `tokenId`. See {ERC721-_burn}. * * Requirements: * * - The caller must own `tokenId` or be an approved operator. */ function burn(uint256 tokenId) public virtual { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved"); _burn(tokenId); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, 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 ) external; /** * @dev Transfers `tokenId` token 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; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @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 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); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; import "./IERC721.sol"; import "./IERC721Receiver.sol"; import "./extensions/IERC721Metadata.sol"; import "../../utils/Address.sol"; import "../../utils/Context.sol"; import "../../utils/Strings.sol"; import "../../utils/introspection/ERC165.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: owner query for nonexistent token"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overriden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransfer(from, to, tokenId, _data); } /** * @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. * * `_data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory _data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits a {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} }
{ "remappings": [], "optimizer": { "enabled": true, "runs": 100 }, "evmVersion": "london", "libraries": {}, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"MaxSplaining","type":"error"},{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"MaxSplaining","type":"error"},{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"MaxSplaining","type":"error"},{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"MaxSplaining","type":"error"},{"inputs":[{"internalType":"uint256","name":"yourTime","type":"uint256"},{"internalType":"uint256","name":"hitTime","type":"uint256"}],"name":"TooLateBoomer","type":"error"},{"inputs":[{"internalType":"uint256","name":"yourTime","type":"uint256"},{"internalType":"uint256","name":"hitTime","type":"uint256"}],"name":"TooSoonJunior","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_old","type":"string"},{"indexed":false,"internalType":"string","name":"_new","type":"string"}],"name":"ContractURIChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"MessageFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"PayeeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"PayeeRemoved","type":"event"},{"anonymous":false,"inputs":[],"name":"PayeesReset","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"start","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"length","type":"uint256"}],"name":"PresaleSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"numberToMint","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startingID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endingID","type":"uint256"}],"name":"SetStartNumbers","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ThankYou","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_chainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_trustedRemote","type":"bytes"}],"name":"TrustedRemoteSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_old","type":"string"},{"indexed":false,"internalType":"string","name":"_new","type":"string"}],"name":"UpdatedBaseURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"}],"name":"royalatiesSet","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"RevealProvenanceImages","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RevealProvenanceJSON","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RevealStartNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newSplit","type":"address"},{"internalType":"uint256","name":"newShares","type":"uint256"}],"name":"addSplit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"clearRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"clearSplits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentLZGas","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"declineDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"declineOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"developer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"donate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"failedMessages","outputs":[{"internalType":"uint256","name":"payloadLength","type":"uint256"},{"internalType":"bytes32","name":"payloadHash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lzStartNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterCurrentMints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterMaximumCapacity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterMaximumTeamMints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterMintsRemaining","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterTeamMintsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterTeamMintsRemaining","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"onLzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"payee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quant","type":"uint256"}],"name":"presaleMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"publicMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newDeveloper","type":"address"}],"name":"pushDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"pushOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"remSplit","type":"address"}],"name":"removeSplit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"retryMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_base","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"URI","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newDisplay","type":"address"}],"name":"setDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newVal","type":"uint256"}],"name":"setGasForDestinationLzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startNumber","type":"uint256"},{"internalType":"uint256","name":"authMint","type":"uint256"},{"internalType":"uint256","name":"teamMints","type":"uint256"},{"internalType":"string","name":"img","type":"string"},{"internalType":"string","name":"json","type":"string"},{"internalType":"address","name":"newAddress","type":"address"}],"name":"setMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newDisplay","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"setPresale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"},{"internalType":"uint256","name":"permille","type":"uint256"}],"name":"setRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"permille","type":"uint256"}],"name":"setRoyaltiesThis","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"bytes","name":"_trustedRemote","type":"bytes"}],"name":"setTrustedRemote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"shares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"showPresaleStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"showPresaleTimes","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"showStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"teamMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newDeveloper","type":"address"}],"name":"transferDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"traverseChains","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"trustedRemoteLookup","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6080604052600180546001600160a01b0319908116734ce69fd760ad0c07490178f9a47863dc0358cccd17909155600280549091167344f750eb065596c150b3479b1df6957da300a332179055620557306021553480156200006057600080fd5b506040518060400160405280600b81526020016a54696e794461656d6f6e7360a81b815250604051806040016040528060078152602001662a24a72ca226a760c91b815250620000c963f851a44060e01b3060006200014f60201b62002dd8179092919060201c565b600154620000e9906303e1469160e61b906001600160a01b03166200028e565b6002546200010990638da5cb5b60e01b906001600160a01b03166200028e565b600154620001299063ca4b208b60e01b906001600160a01b03166200028e565b601862000137838262000572565b50601962000146828262000572565b50505062000791565b6001600160a01b03811662000176576040516282b42960e81b815260040160405180910390fd5b62000183838383620002af565b156200021057620001aa816001600160a01b031660146200030d60201b62002eae1760201c565b620001cb8360e01c63ffffffff1660046200030d60201b62002eae1760201c565b604051602001620001de92919062000671565b60408051601f1981840301815290829052630330dbc960e11b82526200020791600401620006d9565b60405180910390fd5b6001600160a01b0381166000818152602085815260408083206001600160e01b03198716808552908352928190208054600160ff1990911681179091558151938452918301939093528183015290517fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f79181900360600190a1505050565b620002ab828260006200014f60201b62002dd8179092919060201c565b5050565b60006001600160a01b038216620002d8576040516282b42960e81b815260040160405180910390fd5b506001600160a01b03166000908152602092835260408082206001600160e01b03199390931682529190925290205460ff1690565b606060006200031e83600262000724565b6200032b90600262000746565b6001600160401b03811115620003455762000345620004cd565b6040519080825280601f01601f19166020018201604052801562000370576020820181803683370190505b509050600360fc1b816000815181106200038e576200038e62000761565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110620003c057620003c062000761565b60200101906001600160f81b031916908160001a9053506000620003e684600262000724565b620003f390600162000746565b90505b600181111562000475576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106200042b576200042b62000761565b1a60f81b82828151811062000444576200044462000761565b60200101906001600160f81b031916908160001a90535060049490941c936200046d8162000777565b9050620003f6565b508315620004c65760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640162000207565b9392505050565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620004f857607f821691505b6020821081036200051957634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200056d57600081815260208120601f850160051c81016020861015620005485750805b601f850160051c820191505b81811015620005695782815560010162000554565b5050505b505050565b81516001600160401b038111156200058e576200058e620004cd565b620005a6816200059f8454620004e3565b846200051f565b602080601f831160018114620005de5760008415620005c55750858301515b600019600386901b1c1916600185901b17855562000569565b600085815260208120601f198616915b828110156200060f57888601518255948401946001909101908401620005ee565b50858210156200062e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60005b838110156200065b57818101518382015260200162000641565b838111156200066b576000848401525b50505050565b6a02634b1102937b632b99d160ad1b8152600083516200069981600b8501602088016200063e565b7101030b63932b0b23c903430b9903937b632960751b600b918401918201528351620006cd81601d8401602088016200063e565b01601d01949350505050565b6020815260008251806020840152620006fa8160408501602087016200063e565b601f01601f19169190910160400192915050565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156200074157620007416200070e565b500290565b600082198211156200075c576200075c6200070e565b500190565b634e487b7160e01b600052603260045260246000fd5b6000816200078957620007896200070e565b506000190190565b615e4880620007a16000396000f3fe6080604052600436106104815760003560e01c80637544671611610255578063c87b56dd11610144578063de02cde7116100c1578063eb8d72b711610085578063eb8d72b714610db9578063ecc7afa914610dd9578063ed88c68e14610dee578063f2fde38b14610df6578063fd0198e814610e16578063ff70fa4914610e36576104c1565b8063de02cde714610d3a578063e33b7de314610d5a578063e68b796114610d6f578063e8a3d48514610d84578063e985e9c514610d99576104c1565b8063d1deba1f11610108578063d1deba1f14610cbd578063d39ce77c14610cd0578063d4d714be14610cf0578063d792d2a014610d10578063d95ae16214610d25576104c1565b8063c87b56dd14610c16578063c9b298f114610c36578063ca4b208b14610c56578063ce7c2ac214610c74578063cf89fa0314610caa576104c1565b806395d89b41116101d2578063aac3f28111610196578063aac3f28114610ba2578063ad6d9c1714610bb7578063ae47b2da14610bcc578063b88d4fde14610be1578063ba7a86b814610c01576104c1565b806395d89b4114610b0d5780639852595c14610b225780639c12b17f14610b58578063a22cb46514610b6d578063a86ff96014610b8d576104c1565b80638da5cb5b116102195780638da5cb5b14610a2f5780638ee7491214610a4d578063938e3d7b14610ab85780639435267614610ad8578063943fb87214610aed576104c1565b806375446716146109b057806378c5939b146109c557806379ba5097146109da5780638b83209b146109ef5780638c7ea24b14610a0f576104c1565b8063312744261161037157806355f804b3116102ee57806364cb4edb116102b257806364cb4edb1461091b57806366278a6c1461093b57806370a082311461095b578063715018a61461097b5780637533d78814610990576104c1565b806355f804b3146108665780635ba5e9f0146108865780635c17e370146108c65780636149d871146108db5780636352211e146108fb576104c1565b806342966c681161033557806342966c68146107e757806344faded014610807578063475de12e1461082757806348e3bab21461083c5780634e71d92d14610851576104c1565b8063312744261461075d57806331e26cfd1461077d5780633400ec63146107925780633a98ef39146107b257806342842e0e146107c7576104c1565b806313af4035116103ff57806323b872dd116103c357806323b872dd146106cd57806326092b83146106ed5780632a55205a146107025780632bfcf0f2146107305780632ecd28ab14610745576104c1565b806313af40351461064e57806318160ddd1461066e57806318a66a7e146106835780631c37a822146106985780631efb051a146106b8576104c1565b8063081812fc11610446578063081812fc146105a3578063095ea7b3146105db5780630f0efdbc146105fb57806310ab94321461061b57806312065fe01461063b576104c1565b80621d3567146104f2578063018f007e1461051457806301ffc9a71461053c578063049157bb1461056c57806306fdde0314610581576104c1565b366104c1577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033346040516104b7929190614559565b60405180910390a1005b7f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033346040516104b7929190614559565b3480156104fe57600080fd5b5061051261050d366004614642565b610e56565b005b34801561052057600080fd5b506105296110e3565b6040519081526020015b60405180910390f35b34801561054857600080fd5b5061055c6105573660046146dc565b6110f4565b6040519015158152602001610533565b34801561057857600080fd5b50601054610529565b34801561058d57600080fd5b506105966112b3565b6040516105339190614751565b3480156105af57600080fd5b506105c36105be366004614764565b611345565b6040516001600160a01b039091168152602001610533565b3480156105e757600080fd5b506105126105f6366004614792565b6113cd565b34801561060757600080fd5b50610512610616366004614792565b6114dd565b34801561062757600080fd5b5061055c6106363660046147be565b611518565b34801561064757600080fd5b5047610529565b34801561065a57600080fd5b506105126106693660046147f7565b61152b565b34801561067a57600080fd5b506105296115f6565b34801561068f57600080fd5b50610512611601565b3480156106a457600080fd5b506105126106b3366004614642565b611638565b3480156106c457600080fd5b50600e54610529565b3480156106d957600080fd5b506105126106e8366004614814565b6116be565b3480156106f957600080fd5b506105126116f0565b34801561070e57600080fd5b5061072261071d366004614855565b611815565b604051610533929190614559565b34801561073c57600080fd5b5061051261184b565b34801561075157600080fd5b5060155460ff1661055c565b34801561076957600080fd5b50610512610778366004614764565b6118da565b34801561078957600080fd5b50610512611911565b34801561079e57600080fd5b506105126107ad3660046147f7565b611951565b3480156107be57600080fd5b50600654610529565b3480156107d357600080fd5b506105126107e2366004614814565b611987565b3480156107f357600080fd5b50610512610802366004614764565b6119a2565b34801561081357600080fd5b506105126108223660046147be565b6119db565b34801561083357600080fd5b50602154610529565b34801561084857600080fd5b50601754610529565b34801561085d57600080fd5b50610512611adc565b34801561087257600080fd5b50610512610881366004614877565b611c23565b34801561089257600080fd5b506108ad6108a13660046146dc565b506303e1469160e61b90565b6040516001600160e01b03199091168152602001610533565b3480156108d257600080fd5b50610529611d2d565b3480156108e757600080fd5b506105126108f63660046147f7565b611d46565b34801561090757600080fd5b506105c3610916366004614764565b611d85565b34801561092757600080fd5b506105126109363660046147f7565b611dfc565b34801561094757600080fd5b506105126109563660046146dc565b611e4d565b34801561096757600080fd5b506105296109763660046147f7565b611e7f565b34801561098757600080fd5b50610512611f06565b34801561099c57600080fd5b506105966109ab3660046148ab565b611f46565b3480156109bc57600080fd5b50610529611fdf565b3480156109d157600080fd5b50600f54610529565b3480156109e657600080fd5b50610512611ff1565b3480156109fb57600080fd5b506105c3610a0a366004614764565b612042565b348015610a1b57600080fd5b50610512610a2a366004614792565b612072565b348015610a3b57600080fd5b506002546001600160a01b03166105c3565b348015610a5957600080fd5b50610aa3610a683660046148c6565b601f60209081526000938452604080852084518086018401805192815290840195840195909520945292905282529020805460019091015482565b60408051928352602083019190915201610533565b348015610ac457600080fd5b50610512610ad3366004614877565b6120a9565b348015610ae457600080fd5b506105966120df565b348015610af957600080fd5b50610512610b08366004614764565b6120f1565b348015610b1957600080fd5b50610596612123565b348015610b2e57600080fd5b50610529610b3d3660046147f7565b6001600160a01b031660009081526009602052604090205490565b348015610b6457600080fd5b50610aa3612132565b348015610b7957600080fd5b50610512610b8836600461491c565b612150565b348015610b9957600080fd5b5061051261215b565b348015610bae57600080fd5b50600354610529565b348015610bc357600080fd5b5061051261219b565b348015610bd857600080fd5b506105126121db565b348015610bed57600080fd5b50610512610bfc36600461494f565b612210565b348015610c0d57600080fd5b50610512612242565b348015610c2257600080fd5b50610596610c31366004614764565b61235d565b348015610c4257600080fd5b50610512610c51366004614764565b6123ff565b348015610c6257600080fd5b506001546001600160a01b03166105c3565b348015610c8057600080fd5b50610529610c8f3660046147f7565b6001600160a01b031660009081526008602052604090205490565b610512610cb83660046149ae565b612551565b610512610ccb366004614a12565b6127c9565b348015610cdc57600080fd5b50610512610ceb3660046147f7565b612994565b348015610cfc57600080fd5b50610512610d0b366004614855565b6129d3565b348015610d1c57600080fd5b50610596612a40565b348015610d3157600080fd5b50600d54610529565b348015610d4657600080fd5b50610512610d553660046147be565b612a52565b348015610d6657600080fd5b50600754610529565b348015610d7b57600080fd5b50610529612b5f565b348015610d9057600080fd5b50610596612b6b565b348015610da557600080fd5b5061055c610db4366004614a9d565b612b7a565b348015610dc557600080fd5b50610512610dd4366004614abb565b612ba8565b348015610de557600080fd5b50610529612c26565b610512612c3f565b348015610e0257600080fd5b50610512610e113660046147f7565b612c7a565b348015610e2257600080fd5b50610512610e31366004614b0d565b612ccb565b348015610e4257600080fd5b50610512610e513660046147f7565b612d34565b601e546001600160a01b03163314610ee757604051630330dbc960e11b81526020600482015260546024820152600080516020615dd383398151915260448201527f6520646964206e6f7420636f6d652066726f6d2074686520656e64706f696e746064820152732c20796f75206661696c65642c204920776f6e2160601b608482015260a4015b60405180910390fd5b61ffff8416600090815260208052604090208054610f0490614ba0565b90508351141580610f43575061ffff84166000908152602080526040908190209051610f309190614c4d565b6040518091039020838051906020012014155b15610fcb57604051630330dbc960e11b815260206004820152605a6024820152600080516020615dd383398151915260448201527f6520646964206e6f7420636f6d652066726f6d2061207472757374656420636f60648201527f6e74726163742c20796f75206661696c65642c204920776f6e21000000000000608482015260a401610ede565b604051630e1bd41160e11b81523090631c37a82290610ff4908790879087908790600401614c59565b600060405180830381600087803b15801561100e57600080fd5b505af192505050801561101f575060015b6110dd576040518060400160405280825181526020018280519060200120815250601f60008661ffff1661ffff168152602001908152602001600020846040516110699190614ca2565b9081526040805191829003602090810183206001600160401b038716600090815290825291909120835181559201516001909201919091557fe6f254030bcb01ffd20558175c13fcaed6d1520be7becee4c961b65f79243b0d906110d4908690869086908690614c59565b60405180910390a15b50505050565b60006110ef600d613049565b905090565b60006001600160e01b0319821663b7d1e49960e01b148061112557506001600160e01b031982166303edf24760e01b145b8061114057506001600160e01b03198216633daba23f60e11b145b8061115b57506001600160e01b03198216630704183b60e11b145b8061117657506001600160e01b031982166302494e8b60e01b145b8061119157506001600160e01b0319821663152a902d60e11b145b806111ac57506001600160e01b0319821663131e54b760e01b145b806111c757506001600160e01b031982166323a87ba160e01b145b806111e257506001600160e01b0319821663253f8c7960e11b145b806111fd57506001600160e01b031982166329499a2560e01b145b8061121857506001600160e01b031982166317573c7360e21b145b8061123357506001600160e01b03198216632471dd5960e11b145b8061124e57506001600160e01b03198216634ba1182b60e11b145b8061126957506001600160e01b0319821663e8a3d48560e01b145b8061128457506001600160e01b0319821663938e3d7b60e01b145b8061129e57506001600160e01b03198216621d356760e01b145b806112ad57506112ad82613056565b92915050565b6060601880546112c290614ba0565b80601f01602080910402602001604051908101604052809291908181526020018280546112ee90614ba0565b801561133b5780601f106113105761010080835404028352916020019161133b565b820191906000526020600020905b81548152906001019060200180831161131e57829003601f168201915b5050505050905090565b6000611350826130a6565b6113b15760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ede565b506000908152601c60205260409020546001600160a01b031690565b60006113d882611d85565b9050806001600160a01b0316836001600160a01b0316036114455760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610ede565b336001600160a01b038216148061146157506114618133612b7a565b6114ce5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776044820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b6064820152608401610ede565b6114d883836130c3565b505050565b6114ee63ca4b208b60e01b33613131565b61150a576040516282b42960e81b815260040160405180910390fd5b611514828261313e565b5050565b60006115248383613131565b9392505050565b61153c638da5cb5b60e01b33613131565b611558576040516282b42960e81b815260040160405180910390fd5b611569638da5cb5b60e01b82613131565b6115d457611581816001600160a01b03166014612eae565b611590638da5cb5b6004612eae565b61159b336014612eae565b6040516020016115ad93929190614cbe565b60408051601f1981840301815290829052630330dbc960e11b8252610ede91600401614751565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60006110ef60165490565b61161263ca4b208b60e01b33613131565b61162e576040516282b42960e81b815260040160405180910390fd5b6116366132b8565b565b3330146116b257604051630330dbc960e11b815260206004820152604d6024820152600080516020615dd383398151915260448201527f6520646964206e6f7420636f6d6520696e7465726e616c6c792c20796f75206660648201526c61696c65642c204920776f6e2160981b608482015260a401610ede565b6110dd84848484613347565b6116c9335b8261337c565b6116e55760405162461bcd60e51b8152600401610ede90614d77565b6114d883838361343e565b6004546003546117009190614dde565b42101561173a57426004546003546117189190614dde565b60405163f3f82ac560e01b815260048101929092526024820152604401610ede565b6003546000036117bf57604051630330dbc960e11b815260206004820152604360248201527f54696d65436f703a20596f75277665206265656e2054696d6520436f7070656460448201527f2e204e474c206f6e6c794465762829206861736e277420736574207468652074606482015262696d6560e81b608482015260a401610ede565b600a6117ca33611e7f565b106117fc576117da336014612eae565b6117eb6117e633611e7f565b6135cc565b6040516020016115ad929190614df6565b61180d336118086136cc565b6136e5565b6116366136ff565b600b54600c546001600160a01b03909116906000906103e8906118389085614e7b565b6118429190614eb0565b90509250929050565b636525904560e11b61185d8133613131565b8061187457506118746303e1469160e61b33613131565b1561189c573361188b636525904560e11b82613717565b61151463ca4b208b60e01b82613723565b6118ab60e082901c6004612eae565b6118ba63f851a4406004612eae565b6118c5336014612eae565b6040516020016115ad93929190614ec4565b50565b6118eb638da5cb5b60e01b33613131565b611907576040516282b42960e81b815260040160405180910390fd5b6118d7308261372f565b636525904560e11b6119238133613131565b8061193a575061193a6303e1469160e61b33613131565b1561189c5733611514636525904560e11b82613717565b61196263ca4b208b60e01b33613131565b61197e576040516282b42960e81b815260040160405180910390fd5b6118d7816137c2565b6114d883838360405180602001604052806000815250612210565b6119ab336116c3565b6119ca576119ba336014612eae565b6040516020016115ad9190614f51565b6119d38161390a565b6118d7613993565b816119e68133613131565b806119fd57506119fd6303e1469160e61b33613131565b1561189c57631ada6fbb60e11b6001600160e01b0319841601611a6a576001600160a01b0382163314611a6a57611a35336014612eae565b611a4460e085901c6004612eae565b611a58846001600160a01b03166014612eae565b6040516020016115ad93929190614feb565b63392d1a5360e11b6001600160e01b0319841601611ad2576001600160a01b0382163314611ad257611a9d336014612eae565b611aac60e085901c6004612eae565b611ac0846001600160a01b03166014612eae565b6040516020016115ad939291906150a4565b6114d88383613717565b336000818152600860205260408120549003611b0d57611afd336014612eae565b6040516020016115ad91906150af565b600060075447611b1d9190614dde565b6001600160a01b0383166000908152600960209081526040808320546006546008909352908320549394509192611b549085614e7b565b611b5e9190614eb0565b611b689190615101565b905080600003611b8d57611b7d336014612eae565b6040516020016115ad9190615118565b6001600160a01b038316600090815260096020526040902054611bb1908290614dde565b6001600160a01b038416600090815260096020526040902055600754611bd8908290614dde565b600755611be5838261399d565b7fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b0568382604051611c16929190614559565b60405180910390a1505050565b611c3463ca4b208b60e01b33613131565b611c50576040516282b42960e81b815260040160405180910390fd5b600060228054611c5f90614ba0565b80601f0160208091040260200160405190810160405280929190818152602001828054611c8b90614ba0565b8015611cd85780601f10611cad57610100808354040283529160200191611cd8565b820191906000526020600020905b815481529060010190602001808311611cbb57829003601f168201915b505050505090508160229081611cee91906151ca565b507fd2877107a884510f506ed0bd833e6601f4344691e32a0ce4bcdedb1d9d9d28e1816022604051611d21929190615300565b60405180910390a15050565b6000611d39600d613ab6565b6010546110ef9190615101565b63ca4b208b60e01b611d588133613131565b80611d6f5750611d6f6303e1469160e61b33613131565b1561189c57611514636525904560e11b83613723565b6000818152601a60205260408120546001600160a01b0316806112ad5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610ede565b63ca4b208b60e01b611e0e8133613131565b80611e255750611e256303e1469160e61b33613131565b1561189c5733611e3c63ca4b208b60e01b84613723565b6114d863ca4b208b60e01b82613717565b80611e588133613131565b80611e6f5750611e6f6303e1469160e61b33613131565b1561189c57336114d88382613717565b60006001600160a01b038216611eea5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610ede565b506001600160a01b03166000908152601b602052604090205490565b638da5cb5b60e01b611f188133613131565b80611f2f5750611f2f6303e1469160e61b33613131565b1561189c5733611514638da5cb5b60e01b82613717565b602080526000908152604090208054611f5e90614ba0565b80601f0160208091040260200160405190810160405280929190818152602001828054611f8a90614ba0565b8015611fd75780601f10611fac57610100808354040283529160200191611fd7565b820191906000526020600020905b815481529060010190602001808311611fba57829003601f168201915b505050505081565b60006004546003546110ef9190614dde565b6346d2e5ad60e11b6120038133613131565b8061201a575061201a6303e1469160e61b33613131565b1561189c57336120316346d2e5ad60e11b82613717565b611514638da5cb5b60e01b82613723565b6000600a82815481106120575761205761532e565b6000918252602090912001546001600160a01b031692915050565b612083638da5cb5b60e01b33613131565b61209f576040516282b42960e81b815260040160405180910390fd5b611514828261372f565b6120ba63ca4b208b60e01b33613131565b6120d6576040516282b42960e81b815260040160405180910390fd5b6118d781613ac3565b6060600d60050180546112c290614ba0565b612102638da5cb5b60e01b33613131565b61211e576040516282b42960e81b815260040160405180910390fd5b602155565b6060601980546112c290614ba0565b6000806003546004546003546121489190614dde565b915091509091565b611514338383613b94565b6346d2e5ad60e11b61216d8133613131565b8061218457506121846303e1469160e61b33613131565b1561189c57336115146346d2e5ad60e11b82613717565b63ca4b208b60e01b6121ad8133613131565b806121c457506121c46303e1469160e61b33613131565b1561189c573361151463ca4b208b60e01b82613717565b6121ec638da5cb5b60e01b33613131565b612208576040516282b42960e81b815260040160405180910390fd5b611636613c5e565b61221a338361337c565b6122365760405162461bcd60e51b8152600401610ede90614d77565b6110dd84848484613cac565b61225363ca4b208b60e01b33613131565b61226f576040516282b42960e81b815260040160405180910390fd5b6000306001600160a01b0316635c17e3706040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d39190615344565b905060005b818110156115145761234d306001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612321573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612345919061535d565b6118086136cc565b612355613cdf565b6001016122d8565b6060612368826130a6565b61238557612375826135cc565b6040516020016115ad919061537a565b600061238f613cf3565b604080518082019091526005815264173539b7b760d91b60208201528151919250906123ca57604051806020016040528060008152506123f7565b816123d4856135cc565b826040516020016123e7939291906153e6565b6040516020818303038152906040525b949350505050565b60035442101561242f5760035460405163f3f82ac560e01b81524260048201526024810191909152604401610ede565b60045460035461243f9190614dde565b421061247857426004546003546124569190614dde565b6040516343c540ef60e01b815260048101929092526024820152604401610ede565b600461248333611e7f565b106124b057612493336014612eae565b61249f6117e633611e7f565b6040516020016115ad929190615429565b60028111156124de576124c4336014612eae565b6124cd826135cc565b6040516020016115ad9291906154ac565b60005b818110156115145760046124f433611e7f565b1061253557612504336014612eae565b61250d836135cc565b61252361251933611e7f565b6117e69086614dde565b6040516020016115ad93929190615530565b612541336118086136cc565b6125496136ff565b6001016124e1565b61255a81611d85565b6001600160a01b0316336001600160a01b03161461258a576040516282b42960e81b815260040160405180910390fd5b61ffff82166000908152602080526040902080546125a790614ba0565b905060000361262b57604051630330dbc960e11b815260206004820152604360248201527f546f6b656e3a204f6b2074686520446576206469646e2774207365742074686960448201527f7320706172616d617465722c20636f6e74616374204d6178466c6f774f322e656064820152623a341760e91b608482015260a401610ede565b6126348161390a565b61263c613993565b60003382604051602001612651929190614559565b60408051601f1981840301815290829052602154600160f01b60208401526022830152915060019060009060420160408051601f1981840301815290829052601e5463040a7bb160e41b83529092506000916001600160a01b03909116906340a7bb10906126cb90899030908990879089906004016155f1565b6040805180830381865afa1580156126e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061270b9190615645565b5090503481111561274557612721336014612eae565b61272a346135cc565b612733836135cc565b6040516020016115ad93929190615669565b601e5461ffff87166000908152602080526040808220905162c5803160e81b81526001600160a01b039093169263c580310092349261278f928c928b913391908b906004016156eb565b6000604051808303818588803b1580156127a857600080fd5b505af11580156127bc573d6000803e3d6000fd5b5050505050505050505050565b61ffff85166000908152601f602052604080822090516127ea908790614ca2565b90815260408051602092819003830190206001600160401b038716600090815292529020600181015490915061288a57604051630330dbc960e11b815260206004820152604a6024820152600080516020615dd383398151915260448201527f652077617320616c72656164792065786563757465642c20796f75206661696c60648201526965642c204920776f6e2160b01b608482015260a401610ede565b8054821415806128b55750806001015483836040516128aa929190615752565b604051809103902014155b1561292557604051630330dbc960e11b815260206004820152604460248201819052600080516020615dd3833981519152908201527f6520776173206e6f742073746f7265642c20796f75206661696c65642c204920606482015263776f6e2160e01b608482015260a401610ede565b60008082556001820155604051630e1bd41160e11b81523090631c37a8229061295a908990899089908990899060040161578b565b600060405180830381600087803b15801561297457600080fd5b505af1158015612988573d6000803e3d6000fd5b50505050505050505050565b638da5cb5b60e01b6129a68133613131565b806129bd57506129bd6303e1469160e61b33613131565b1561189c576115146346d2e5ad60e11b83613723565b6129e463ca4b208b60e01b33613131565b612a00576040516282b42960e81b815260040160405180910390fd5b6003829055600481905560408051838152602081018390527f5ef81ff0fe28d74938986521db9f3fb5637cae3d1cec04a94b4a0d3a3b0fc3c49101611d21565b6060600d60040180546112c290614ba0565b81612a5d8133613131565b80612a745750612a746303e1469160e61b33613131565b1561189c57631ada6fbb60e11b6001600160e01b0319841601612ae757612aa2636525904560e11b33613131565b15612ae757612ab2336014612eae565b612ac160e085901c6004612eae565b612ad5846001600160a01b03166014612eae565b6040516020016115ad939291906157ca565b63392d1a5360e11b6001600160e01b0319841601612b5557612b106346d2e5ad60e11b33613131565b15612b5557612b20336014612eae565b612b2f60e085901c6004612eae565b612b43846001600160a01b03166014612eae565b6040516020016115ad9392919061584b565b6114d88383613723565b60006110ef600d613ab6565b6060600580546112c290614ba0565b6001600160a01b039182166000908152601d6020908152604080832093909416825291909152205460ff1690565b612bb963ca4b208b60e01b33613131565b612bd5576040516282b42960e81b815260040160405180910390fd5b61ffff831660009081526020805260409020612bf2828483615856565b507f93c35c217d799290d33244ef8905b63167d13758ab18343cd8055ed1b8056748838383604051611c1693929190615910565b6000612c32600d613049565b600f546110ef9190615101565b7f9a064d674ddc42ac41b38566457161f1ded37e65a59162da003dd25bcb057b603334604051612c70929190614559565b60405180910390a1565b638da5cb5b60e01b612c8c8133613131565b80612ca35750612ca36303e1469160e61b33613131565b1561189c5733612cba638da5cb5b60e01b84613723565b6114d8638da5cb5b60e01b82613717565b612cdc63ca4b208b60e01b33613131565b612cf8576040516282b42960e81b815260040160405180910390fd5b612d03868686613d02565b612d0d8383613d65565b601e80546001600160a01b0319166001600160a01b03929092169190911790555050505050565b612d4563ca4b208b60e01b33613131565b612d61576040516282b42960e81b815260040160405180910390fd5b612d7263ca4b208b60e01b82613131565b612db657612d8a816001600160a01b03166014612eae565b612d9963ca4b208b6004612eae565b612da4336014612eae565b6040516020016115ad9392919061592e565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038116612dfe576040516282b42960e81b815260040160405180910390fd5b612e09838383613d85565b15612e4257612e22816001600160a01b03166014612eae565b612e3160e084901c6004612eae565b6040516020016115ad9291906159ea565b6001600160a01b0381166000908152602084815260408083206001600160e01b03198616845290915290819020805460ff1916600190811790915590517fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f791611c169185918591615a4e565b60606000612ebd836002614e7b565b612ec8906002614dde565b6001600160401b03811115612edf57612edf614589565b6040519080825280601f01601f191660200182016040528015612f09576020820181803683370190505b509050600360fc1b81600081518110612f2457612f2461532e565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612f5357612f5361532e565b60200101906001600160f81b031916908160001a9053506000612f77846002614e7b565b612f82906001614dde565b90505b6001811115612ffa576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612fb657612fb661532e565b1a60f81b828281518110612fcc57612fcc61532e565b60200101906001600160f81b031916908160001a90535060049490941c93612ff381615a7b565b9050612f85565b5083156115245760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610ede565b60006112ad826006015490565b60006001600160e01b031982166380ac58cd60e01b148061308757506001600160e01b03198216635b5e139f60e01b145b806112ad57506301ffc9a760e01b6001600160e01b03198316146112ad565b6000908152601a60205260409020546001600160a01b0316151590565b6000818152601c6020526040902080546001600160a01b0319166001600160a01b03841690811790915581906130f882611d85565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611524818484613d85565b6001600160a01b03821661316557604051630330dbc960e11b8152600401610ede90615a92565b806000036131b657604051630330dbc960e11b815260206004820152601d60248201527f5061796d656e7453706c69747465723a207368617265732061726520300000006044820152606401610ede565b6001600160a01b0382166000908152600860205260409020541561321b576131e8826001600160a01b03166014612eae565b6001600160a01b03831660009081526008602052604090205461320a906135cc565b6040516020016115ad929190615ade565b600a8054600181019091557fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a80180546001600160a01b0319166001600160a01b0384169081179091556000908152600860205260409020819055600654613283908290614dde565b6006556040517f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac90611d219084908490614559565b600a5460005b81811015613306576000600a82815481106132db576132db61532e565b60009182526020808320909101546001600160a01b03168252600890526040812055506001016132be565b50600660009055600a600061331b9190614527565b6040517f3407fd525bf6581e0ae8e3a3636bd90d02112bea34d66802743c28ced73f910e90600090a150565b6000808280602001905181019061335e9190615b58565b9150915061336c82826136e5565b613374613709565b505050505050565b6000613387826130a6565b6133e85760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ede565b60006133f383611d85565b9050806001600160a01b0316846001600160a01b0316148061342e5750836001600160a01b031661342384611345565b6001600160a01b0316145b806123f757506123f78185612b7a565b826001600160a01b031661345182611d85565b6001600160a01b0316146134b95760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610ede565b6001600160a01b03821661351b5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610ede565b6135266000826130c3565b6001600160a01b0383166000908152601b6020526040812080546001929061354f908490615101565b90915550506001600160a01b0382166000908152601b6020526040812080546001929061357d908490614dde565b90915550506000818152601a602052604080822080546001600160a01b0319166001600160a01b038681169182179092559151849391871691600080516020615df383398151915291a4505050565b6060816000036135f35750506040805180820190915260018152600360fc1b602082015290565b8160005b811561361d578061360781615b86565b91506136169050600a83614eb0565b91506135f7565b6000816001600160401b0381111561363757613637614589565b6040519080825280601f01601f191660200182016040528015613661576020820181803683370190505b5090505b84156123f757613676600183615101565b9150613683600a86615b9f565b61368e906030614dde565b60f81b8183815181106136a3576136a361532e565b60200101906001600160f81b031916908160001a9053506136c5600a86614eb0565b9450613665565b60006136d8600d613de2565b6017546110ef9190614dde565b611514828260405180602001604052806000815250613e0d565b613709600d613e40565b611636601680546001019055565b61151460008383613e50565b61151460008383612dd8565b6103e88110158061373e575080155b156137685761374e336014612eae565b613757826135cc565b6040516020016115ad929190615bb3565b600b80546001600160a01b0319166001600160a01b038416908117909155600c8290556040805183815260208101929092527f184520f1b2fcf99836992b9a6b987afc0e4867f26a00ef438c654318763fe1e39101611d21565b6001600160a01b0381166137e957604051630330dbc960e11b8152600401610ede90615a92565b60006137f482613f1d565b600a805491925060009161380a90600190615101565b8154811061381a5761381a61532e565b600091825260209091200154600a80546001600160a01b0390921692508291849081106138495761384961532e565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600a80548061388857613888615c42565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0385168252600890526040812080549190556006546138d5908290615101565b6006556040517f104b8837ec12e86f303ac7ce5e3bf20c6790f843fabd7451943f3390fc8376cb906110d49086908490614559565b600061391582611d85565b90506139226000836130c3565b6001600160a01b0381166000908152601b6020526040812080546001929061394b908490615101565b90915550506000828152601a602052604080822080546001600160a01b0319169055518391906001600160a01b03841690600080516020615df3833981519152908390a45050565b6116366016613f77565b804710156139ed5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610ede565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613a3a576040519150601f19603f3d011682016040523d82523d6000602084013e613a3f565b606091505b50509050806114d85760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610ede565b60006112ad826007015490565b600060058054613ad290614ba0565b80601f0160208091040260200160405190810160405280929190818152602001828054613afe90614ba0565b8015613b4b5780601f10613b2057610100808354040283529160200191613b4b565b820191906000526020600020905b815481529060010190602001808311613b2e57829003601f168201915b505050505090508160059081613b6191906151ca565b507f17f75bb1e35b058872a221a8c16d8b3e39eacbda214fd7da20f192b9291ecc3b816005604051611d21929190615300565b816001600160a01b0316836001600160a01b031603613bf15760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b6044820152606401610ede565b6001600160a01b038381166000818152601d6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b600b80546001600160a01b03191690556000600c8190556040805182815260208101929092527f184520f1b2fcf99836992b9a6b987afc0e4867f26a00ef438c654318763fe1e39101612c70565b613cb784848461343e565b613cc384848484613fe0565b6110dd5760405162461bcd60e51b8152600401610ede90615c58565b613ce9600d613e40565b613709600d6140e1565b6060602280546112c290614ba0565b6017839055613d12600d836140f1565b613d1d600d82614131565b7f0e59e2733e85d32179b3dffa920faef60cc432823591194c4e5f0ac15db3dcec8284613d4a8183614dde565b60408051938452602084019290925290820152606001611c16565b613d70600d82614171565b613d7b600d83614245565b611514600d614319565b60006001600160a01b038216613dad576040516282b42960e81b815260040160405180910390fd5b506001600160a01b03166000908152602092835260408082206001600160e01b03199390931682529190925290205460ff1690565b60008160020154613df4836006015490565b8360010154613e039190614dde565b6112ad9190615b9f565b613e178383614406565b613e246000848484613fe0565b6114d85760405162461bcd60e51b8152600401610ede90615c58565b6118d78160060180546001019055565b6001600160a01b038116613e76576040516282b42960e81b815260040160405180910390fd5b613e81838383613d85565b613eb957613e99816001600160a01b03166014612eae565b613ea860e084901c6004612eae565b6040516020016115ad929190615caa565b6001600160a01b0381166000908152602084815260408083206001600160e01b031986168452909152808220805460ff19169055517fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f791611c169185918591615a4e565b600a54600090815b81811015613f7057836001600160a01b0316600a8281548110613f4a57613f4a61532e565b6000918252602090912001546001600160a01b031603613f68578092505b600101613f25565b5050919050565b80546000819003613fd557604051630330dbc960e11b815260206004820152602160248201527f436f756e7465727356323a204e6f206e656761746976657320696e2075696e746044820152607360f81b6064820152608401610ede565b508054600019019055565b60006001600160a01b0384163b156140d657604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614024903390899088908890600401615d10565b6020604051808303816000875af192505050801561405f575060408051601f3d908101601f1916820190925261405c91810190615d4d565b60015b6140bc573d80801561408d576040519150601f19603f3d011682016040523d82523d6000602084013e614092565b606091505b5080516000036140b45760405162461bcd60e51b8152600401610ede90615c58565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506123f7565b506001949350505050565b6118d78160070180546001019055565b6002820180549082905560408051838152602081018390527fe26aa1327aec5016c96875498202eebb896e3c2a79cd281ff17ed5bde4e545db9101611c16565b6003820180549082905560408051838152602081018390527fef40c7688f323b7ccad323bec82bfee336d16c0939c46bee1f3e5df296dadde39101611c16565b600082600501805461418290614ba0565b80601f01602080910402602001604051908101604052809291908181526020018280546141ae90614ba0565b80156141fb5780601f106141d0576101008083540402835291602001916141fb565b820191906000526020600020905b8154815290600101906020018083116141de57829003601f168201915b505050505090508183600501908161421391906151ca565b507f5769620297eb5047703c0ba55dd28b8ea50ba49818a91a43217fedce8eb69a308282604051611c16929190615d6a565b600082600401805461425690614ba0565b80601f016020809104026020016040519081016040528092919081815260200182805461428290614ba0565b80156142cf5780601f106142a4576101008083540402835291602001916142cf565b820191906000526020600020905b8154815290600101906020018083116142b257829003601f168201915b50505050509050818360040190816142e791906151ca565b507f7058c986a2931f38a70c3f70689d1f2bb75efb4d0082511082db4b2d40492b4f8282604051611c16929190615d6a565b806002015460000361438257604051630330dbc960e11b815260206004820152602b60248201527f50737565646f52616e646f6d204c69623a204d6178696d756d2043617061636960448201526a7479206e6f74207365742160a81b6064820152608401610ede565b806002015442338360040184600501446040516020016143a6959493929190615d8f565b6040516020818303038152906040528051906020012060001c6143c99190615b9f565b600182018190556040519081527f74d17dde2d5b61215fe87f93cddcd2470527e8b0381734da7d0dfeb3fcf6f8179060200160405180910390a150565b6001600160a01b03821661445c5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610ede565b614465816130a6565b156144b25760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610ede565b6001600160a01b0382166000908152601b602052604081208054600192906144db908490614dde565b90915550506000818152601a602052604080822080546001600160a01b0319166001600160a01b0386169081179091559051839290600080516020615df3833981519152908290a45050565b50805460008255906000526020600020908101906118d791905b808211156145555760008155600101614541565b5090565b6001600160a01b03929092168252602082015260400190565b803561ffff8116811461458457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126145b057600080fd5b81356001600160401b03808211156145ca576145ca614589565b604051601f8301601f19908116603f011681019082821181831017156145f2576145f2614589565b8160405283815286602085880101111561460b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b80356001600160401b038116811461458457600080fd5b6000806000806080858703121561465857600080fd5b61466185614572565b935060208501356001600160401b038082111561467d57600080fd5b6146898883890161459f565b94506146976040880161462b565b935060608701359150808211156146ad57600080fd5b506146ba8782880161459f565b91505092959194509250565b6001600160e01b0319811681146118d757600080fd5b6000602082840312156146ee57600080fd5b8135611524816146c6565b60005b838110156147145781810151838201526020016146fc565b838111156110dd5750506000910152565b6000815180845261473d8160208601602086016146f9565b601f01601f19169290920160200192915050565b6020815260006115246020830184614725565b60006020828403121561477657600080fd5b5035919050565b6001600160a01b03811681146118d757600080fd5b600080604083850312156147a557600080fd5b82356147b08161477d565b946020939093013593505050565b600080604083850312156147d157600080fd5b82356147dc816146c6565b915060208301356147ec8161477d565b809150509250929050565b60006020828403121561480957600080fd5b81356115248161477d565b60008060006060848603121561482957600080fd5b83356148348161477d565b925060208401356148448161477d565b929592945050506040919091013590565b6000806040838503121561486857600080fd5b50508035926020909101359150565b60006020828403121561488957600080fd5b81356001600160401b0381111561489f57600080fd5b6123f78482850161459f565b6000602082840312156148bd57600080fd5b61152482614572565b6000806000606084860312156148db57600080fd5b6148e484614572565b925060208401356001600160401b038111156148ff57600080fd5b61490b8682870161459f565b925050604084013590509250925092565b6000806040838503121561492f57600080fd5b823561493a8161477d565b9150602083013580151581146147ec57600080fd5b6000806000806080858703121561496557600080fd5b84356149708161477d565b935060208501356149808161477d565b92506040850135915060608501356001600160401b038111156149a257600080fd5b6146ba8782880161459f565b600080604083850312156149c157600080fd5b6147b083614572565b60008083601f8401126149dc57600080fd5b5081356001600160401b038111156149f357600080fd5b602083019150836020828501011115614a0b57600080fd5b9250929050565b600080600080600060808688031215614a2a57600080fd5b614a3386614572565b945060208601356001600160401b0380821115614a4f57600080fd5b614a5b89838a0161459f565b9550614a696040890161462b565b94506060880135915080821115614a7f57600080fd5b50614a8c888289016149ca565b969995985093965092949392505050565b60008060408385031215614ab057600080fd5b82356147dc8161477d565b600080600060408486031215614ad057600080fd5b614ad984614572565b925060208401356001600160401b03811115614af457600080fd5b614b00868287016149ca565b9497909650939450505050565b60008060008060008060c08789031215614b2657600080fd5b86359550602087013594506040870135935060608701356001600160401b0380821115614b5257600080fd5b614b5e8a838b0161459f565b94506080890135915080821115614b7457600080fd5b50614b8189828a0161459f565b92505060a0870135614b928161477d565b809150509295509295509295565b600181811c90821680614bb457607f821691505b602082108103614bd457634e487b7160e01b600052602260045260246000fd5b50919050565b60008154614be781614ba0565b60018281168015614bff5760018114614c1457614c43565b60ff1984168752821515830287019450614c43565b8560005260208060002060005b85811015614c3a5781548a820152908401908201614c21565b50505082870194505b5050505092915050565b60006115248284614bda565b61ffff85168152608060208201526000614c766080830186614725565b6001600160401b03851660408401528281036060840152614c978185614725565b979650505050505050565b60008251614cb48184602087016146f9565b9190910192915050565b76026b0bc20b1b1b2b9b99d102a34329030b2323932b9b99604d1b815260008451614cf08160178501602089016146f9565b7f206973206e6f7420616e206f776e657220616e6420646f6573206e6f742068616017918401918201526b03b32903a3432903937b632960a51b60378201528451614d428160438401602089016146f9565b660103a3432b932960cd1b604392909101918201528351614d6a81604a8401602088016146f9565b01604a0195945050505050565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008219821115614df157614df1614dc8565b500190565b6902a37b5b2b71d1027b5960b51b815260008351614e1b81600a8501602088016146f9565b690103cb7ba903430bb32960b51b600a918401918201528351614e458160148401602088016146f9565b7f206d6178696d756d20617420746869732074696d652069732031302e0000000060149290910191820152603001949350505050565b6000816000190483118215151615614e9557614e95614dc8565b500290565b634e487b7160e01b600052601260045260246000fd5b600082614ebf57614ebf614e9a565b500490565b7f4d61784163636573733a20596f75206172652061206e6f7420616e2000000000815260008451614efc81601c8501602089016146f9565b80830190506301037b9160e51b601c8201528451614f218160208401602089016146f9565b808201915050600160fd1b60208201528351614f448160218401602088016146f9565b0160210195945050505050565b6f022a9219b9918a13ab93730b136329d160851b815260008251614f7c8160108501602087016146f9565b7f206973206e6f74206f776e6572206e6f7220617070726f7665640000000000006010939091019283015250602a01919050565b7f4d61784163636573733a20596f752061726520612070656e64696e6720646576815268032b637b832b91414960bd1b602082015260290190565b6000614ff682614fb0565b8551615006818360208a016146f9565b780103cb7ba9031b0b7103737ba103932bb37b5b2903937b6329603d1b9101908152845161503b8160198401602089016146f9565b630103a37960e51b60199290910191820152835161506081601d8401602088016146f9565b01601d0195945050505050565b7f4d61784163636573733a20596f752061726520612070656e64696e67206f776e815264032b91414960dd1b602082015260250190565b6000614ff68261506d565b7002830bcb6b2b73a29b83634ba3a32b91d1607d1b8152600082516150db8160118501602087016146f9565b6e103430b99037379039b430b932b99760891b6011939091019283015250602001919050565b60008282101561511357615113614dc8565b500390565b7002830bcb6b2b73a29b83634ba3a32b91d1607d1b8152600082516151448160118501602087016146f9565b731034b9903737ba10323ab2903830bcb6b2b73a1760611b6011939091019283015250602501919050565b601f8211156114d857600081815260208120601f850160051c810160208610156151965750805b601f850160051c820191505b81811015613374578281556001016151a2565b600019600383901b1c191660019190911b1790565b81516001600160401b038111156151e3576151e3614589565b6151f7816151f18454614ba0565b8461516f565b602080601f83116001811461522657600084156152145750858301515b61521e85826151b5565b865550613374565b600085815260208120601f198616915b8281101561525557888601518255948401946001909101908401615236565b50858210156152735787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000815461529081614ba0565b8085526020600183811680156152ad57600181146152c7576152f5565b60ff1985168884015283151560051b8801830195506152f5565b866000528260002060005b858110156152ed5781548a82018601529083019084016152d2565b890184019650505b505050505092915050565b6040815260006153136040830185614725565b82810360208401526153258185615283565b95945050505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561535657600080fd5b5051919050565b60006020828403121561536f57600080fd5b81516115248161477d565b7f4552433732314d657461646174613a2055524920717565727920666f722000008152600082516153b281601e8501602087016146f9565b7f2072657475726e73206e6f6e6578697374656e7420746f6b656e000000000000601e939091019283015250603801919050565b600084516153f88184602089016146f9565b84519083019061540c8183602089016146f9565b845191019061541f8183602088016146f9565b0195945050505050565b6902a37b5b2b71d1027b5960b51b81526000835161544e81600a8501602088016146f9565b690103cb7ba903430bb32960b51b600a9184019182015283516154788160148401602088016146f9565b7a1036b0bc34b6bab69030ba103a3434b9903a34b6b29034b9901a1760291b60149290910191820152602f01949350505050565b6902a37b5b2b71d1027b5960b51b8152600083516154d181600a8501602088016146f9565b730103cb7ba903bb0b73a32b2103a379036b4b73a160651b600a91840191820152835161550581601e8401602088016146f9565b7110191037b9103632b9b990383632b0b9b29760711b601e9290910191820152603001949350505050565b6902a37b5b2b71d1027b5960b51b81526000845161555581600a8501602089016146f9565b730103cb7ba903bb0b73a32b2103a379036b4b73a160651b600a91840191820152845161558981601e8401602089016146f9565b710103a3430ba10383aba39903cb7ba9030ba160751b601e929091019182015283516155bc8160308401602088016146f9565b7a1036b0bc34b6bab69030ba103a3434b9903a34b6b29034b9901a1760291b60309290910191820152604b0195945050505050565b61ffff861681526001600160a01b038516602082015260a06040820181905260009061561f90830186614725565b841515606084015282810360808401526156398185614725565b98975050505050505050565b6000806040838503121561565857600080fd5b505080516020909101519092909150565b6602a37b5b2b71d160cd1b81526000845161568b8160078501602089016146f9565b6501039b2b73a160d51b60079184019182015284516156b181600d8401602089016146f9565b6b01034b739ba32b0b21037b3160a51b600d929091019182015283516156de8160198401602088016146f9565b0160190195945050505050565b61ffff8716815260c06020820152600061570860c0830188615283565b828103604084015261571a8188614725565b6001600160a01b0387811660608601528616608085015283810360a085015290506157458185614725565b9998505050505050505050565b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff861681526080602082015260006157a86080830187614725565b6001600160401b03861660408401528281036060840152615639818587615762565b60006157d582614fb0565b85516157e5818360208a016146f9565b770103cb7ba9031b0b7103737ba1033b930b73a103937b632960451b910190815284516158198160188401602089016146f9565b630103a37960e51b60189290910191820152835161583e81601c8401602088016146f9565b01601c0195945050505050565b60006157d58261506d565b6001600160401b0383111561586d5761586d614589565b6158818361587b8354614ba0565b8361516f565b6000601f8411600181146158af576000851561589d5750838201355b6158a786826151b5565b845550615909565b600083815260209020601f19861690835b828110156158e057868501358255602094850194600190920191016158c0565b50868210156158fd5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b61ffff84168152604060208201526000615325604083018486615762565b76026b0bc20b1b1b2b9b99d102a34329030b2323932b9b99604d1b8152600084516159608160178501602089016146f9565b7f206973206e6f74206120646576656c6f70657220616e6420646f6573206e6f746017918401918201526e0103430bb32903a3432903937b6329608d1b603782015284516159b58160468401602089016146f9565b660103a3432b932960cd1b6046929091019182015283516159dd81604d8401602088016146f9565b01604d0195945050505050565b6a02634b1102937b632b99d160ad1b815260008351615a1081600b8501602088016146f9565b7101030b63932b0b23c903430b9903937b632960751b600b918401918201528351615a4281601d8401602088016146f9565b01601d01949350505050565b6001600160e01b03199390931683526001600160a01b039190911660208301521515604082015260600190565b600081615a8a57615a8a614dc8565b506000190190565b6020808252602c908201527f5061796d656e7453706c69747465723a206163636f756e74206973207468652060408201526b7a65726f206164647265737360a01b606082015260800190565b7002830bcb6b2b73a29b83634ba3a32b91d1607d1b815260008351615b0a8160118501602088016146f9565b6c01030b63932b0b23c903430b99609d1b6011918401918201528351615b3781601e8401602088016146f9565b671039b430b932b99760c11b601e9290910191820152602601949350505050565b60008060408385031215615b6b57600080fd5b8251615b768161477d565b6020939093015192949293505050565b600060018201615b9857615b98614dc8565b5060010190565b600082615bae57615bae614e9a565b500690565b72022a921991c9c18a1b7b63632b1ba34b7b71d1606d1b815260008351615be18160138501602088016146f9565b6a01039bab136b4ba3a32b2160ad1b6013918401918201528351615c0c81601e8401602088016146f9565b7f20616e642074686174206973206f7574206f6620626f756e6473210000000000601e9290910191820152603901949350505050565b634e487b7160e01b600052603160045260246000fd5b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6a02634b1102937b632b99d160ad1b815260008351615cd081600b8501602088016146f9565b730103237b2b9903737ba103430bb32903937b632960651b600b918401918201528351615d0481601f8401602088016146f9565b01601f01949350505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090615d4390830184614725565b9695505050505050565b600060208284031215615d5f57600080fd5b8151611524816146c6565b604081526000615d7d6040830185614725565b82810360208401526153258185614725565b8581526bffffffffffffffffffffffff198560601b1660208201526000615dc2615dbc6034840187614bda565b85614bda565b928352505060200194935050505056fe4e6f6e626c6f636b696e6752656365697665723a2054686973206d6573736167ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212203141b7ea1d69d1dba90a4aa8c8ceb739713a9cc2ac8d184bde9f9da53c19d3bb64736f6c634300080f0033
Deployed Bytecode
0x6080604052600436106104815760003560e01c80637544671611610255578063c87b56dd11610144578063de02cde7116100c1578063eb8d72b711610085578063eb8d72b714610db9578063ecc7afa914610dd9578063ed88c68e14610dee578063f2fde38b14610df6578063fd0198e814610e16578063ff70fa4914610e36576104c1565b8063de02cde714610d3a578063e33b7de314610d5a578063e68b796114610d6f578063e8a3d48514610d84578063e985e9c514610d99576104c1565b8063d1deba1f11610108578063d1deba1f14610cbd578063d39ce77c14610cd0578063d4d714be14610cf0578063d792d2a014610d10578063d95ae16214610d25576104c1565b8063c87b56dd14610c16578063c9b298f114610c36578063ca4b208b14610c56578063ce7c2ac214610c74578063cf89fa0314610caa576104c1565b806395d89b41116101d2578063aac3f28111610196578063aac3f28114610ba2578063ad6d9c1714610bb7578063ae47b2da14610bcc578063b88d4fde14610be1578063ba7a86b814610c01576104c1565b806395d89b4114610b0d5780639852595c14610b225780639c12b17f14610b58578063a22cb46514610b6d578063a86ff96014610b8d576104c1565b80638da5cb5b116102195780638da5cb5b14610a2f5780638ee7491214610a4d578063938e3d7b14610ab85780639435267614610ad8578063943fb87214610aed576104c1565b806375446716146109b057806378c5939b146109c557806379ba5097146109da5780638b83209b146109ef5780638c7ea24b14610a0f576104c1565b8063312744261161037157806355f804b3116102ee57806364cb4edb116102b257806364cb4edb1461091b57806366278a6c1461093b57806370a082311461095b578063715018a61461097b5780637533d78814610990576104c1565b806355f804b3146108665780635ba5e9f0146108865780635c17e370146108c65780636149d871146108db5780636352211e146108fb576104c1565b806342966c681161033557806342966c68146107e757806344faded014610807578063475de12e1461082757806348e3bab21461083c5780634e71d92d14610851576104c1565b8063312744261461075d57806331e26cfd1461077d5780633400ec63146107925780633a98ef39146107b257806342842e0e146107c7576104c1565b806313af4035116103ff57806323b872dd116103c357806323b872dd146106cd57806326092b83146106ed5780632a55205a146107025780632bfcf0f2146107305780632ecd28ab14610745576104c1565b806313af40351461064e57806318160ddd1461066e57806318a66a7e146106835780631c37a822146106985780631efb051a146106b8576104c1565b8063081812fc11610446578063081812fc146105a3578063095ea7b3146105db5780630f0efdbc146105fb57806310ab94321461061b57806312065fe01461063b576104c1565b80621d3567146104f2578063018f007e1461051457806301ffc9a71461053c578063049157bb1461056c57806306fdde0314610581576104c1565b366104c1577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033346040516104b7929190614559565b60405180910390a1005b7f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033346040516104b7929190614559565b3480156104fe57600080fd5b5061051261050d366004614642565b610e56565b005b34801561052057600080fd5b506105296110e3565b6040519081526020015b60405180910390f35b34801561054857600080fd5b5061055c6105573660046146dc565b6110f4565b6040519015158152602001610533565b34801561057857600080fd5b50601054610529565b34801561058d57600080fd5b506105966112b3565b6040516105339190614751565b3480156105af57600080fd5b506105c36105be366004614764565b611345565b6040516001600160a01b039091168152602001610533565b3480156105e757600080fd5b506105126105f6366004614792565b6113cd565b34801561060757600080fd5b50610512610616366004614792565b6114dd565b34801561062757600080fd5b5061055c6106363660046147be565b611518565b34801561064757600080fd5b5047610529565b34801561065a57600080fd5b506105126106693660046147f7565b61152b565b34801561067a57600080fd5b506105296115f6565b34801561068f57600080fd5b50610512611601565b3480156106a457600080fd5b506105126106b3366004614642565b611638565b3480156106c457600080fd5b50600e54610529565b3480156106d957600080fd5b506105126106e8366004614814565b6116be565b3480156106f957600080fd5b506105126116f0565b34801561070e57600080fd5b5061072261071d366004614855565b611815565b604051610533929190614559565b34801561073c57600080fd5b5061051261184b565b34801561075157600080fd5b5060155460ff1661055c565b34801561076957600080fd5b50610512610778366004614764565b6118da565b34801561078957600080fd5b50610512611911565b34801561079e57600080fd5b506105126107ad3660046147f7565b611951565b3480156107be57600080fd5b50600654610529565b3480156107d357600080fd5b506105126107e2366004614814565b611987565b3480156107f357600080fd5b50610512610802366004614764565b6119a2565b34801561081357600080fd5b506105126108223660046147be565b6119db565b34801561083357600080fd5b50602154610529565b34801561084857600080fd5b50601754610529565b34801561085d57600080fd5b50610512611adc565b34801561087257600080fd5b50610512610881366004614877565b611c23565b34801561089257600080fd5b506108ad6108a13660046146dc565b506303e1469160e61b90565b6040516001600160e01b03199091168152602001610533565b3480156108d257600080fd5b50610529611d2d565b3480156108e757600080fd5b506105126108f63660046147f7565b611d46565b34801561090757600080fd5b506105c3610916366004614764565b611d85565b34801561092757600080fd5b506105126109363660046147f7565b611dfc565b34801561094757600080fd5b506105126109563660046146dc565b611e4d565b34801561096757600080fd5b506105296109763660046147f7565b611e7f565b34801561098757600080fd5b50610512611f06565b34801561099c57600080fd5b506105966109ab3660046148ab565b611f46565b3480156109bc57600080fd5b50610529611fdf565b3480156109d157600080fd5b50600f54610529565b3480156109e657600080fd5b50610512611ff1565b3480156109fb57600080fd5b506105c3610a0a366004614764565b612042565b348015610a1b57600080fd5b50610512610a2a366004614792565b612072565b348015610a3b57600080fd5b506002546001600160a01b03166105c3565b348015610a5957600080fd5b50610aa3610a683660046148c6565b601f60209081526000938452604080852084518086018401805192815290840195840195909520945292905282529020805460019091015482565b60408051928352602083019190915201610533565b348015610ac457600080fd5b50610512610ad3366004614877565b6120a9565b348015610ae457600080fd5b506105966120df565b348015610af957600080fd5b50610512610b08366004614764565b6120f1565b348015610b1957600080fd5b50610596612123565b348015610b2e57600080fd5b50610529610b3d3660046147f7565b6001600160a01b031660009081526009602052604090205490565b348015610b6457600080fd5b50610aa3612132565b348015610b7957600080fd5b50610512610b8836600461491c565b612150565b348015610b9957600080fd5b5061051261215b565b348015610bae57600080fd5b50600354610529565b348015610bc357600080fd5b5061051261219b565b348015610bd857600080fd5b506105126121db565b348015610bed57600080fd5b50610512610bfc36600461494f565b612210565b348015610c0d57600080fd5b50610512612242565b348015610c2257600080fd5b50610596610c31366004614764565b61235d565b348015610c4257600080fd5b50610512610c51366004614764565b6123ff565b348015610c6257600080fd5b506001546001600160a01b03166105c3565b348015610c8057600080fd5b50610529610c8f3660046147f7565b6001600160a01b031660009081526008602052604090205490565b610512610cb83660046149ae565b612551565b610512610ccb366004614a12565b6127c9565b348015610cdc57600080fd5b50610512610ceb3660046147f7565b612994565b348015610cfc57600080fd5b50610512610d0b366004614855565b6129d3565b348015610d1c57600080fd5b50610596612a40565b348015610d3157600080fd5b50600d54610529565b348015610d4657600080fd5b50610512610d553660046147be565b612a52565b348015610d6657600080fd5b50600754610529565b348015610d7b57600080fd5b50610529612b5f565b348015610d9057600080fd5b50610596612b6b565b348015610da557600080fd5b5061055c610db4366004614a9d565b612b7a565b348015610dc557600080fd5b50610512610dd4366004614abb565b612ba8565b348015610de557600080fd5b50610529612c26565b610512612c3f565b348015610e0257600080fd5b50610512610e113660046147f7565b612c7a565b348015610e2257600080fd5b50610512610e31366004614b0d565b612ccb565b348015610e4257600080fd5b50610512610e513660046147f7565b612d34565b601e546001600160a01b03163314610ee757604051630330dbc960e11b81526020600482015260546024820152600080516020615dd383398151915260448201527f6520646964206e6f7420636f6d652066726f6d2074686520656e64706f696e746064820152732c20796f75206661696c65642c204920776f6e2160601b608482015260a4015b60405180910390fd5b61ffff8416600090815260208052604090208054610f0490614ba0565b90508351141580610f43575061ffff84166000908152602080526040908190209051610f309190614c4d565b6040518091039020838051906020012014155b15610fcb57604051630330dbc960e11b815260206004820152605a6024820152600080516020615dd383398151915260448201527f6520646964206e6f7420636f6d652066726f6d2061207472757374656420636f60648201527f6e74726163742c20796f75206661696c65642c204920776f6e21000000000000608482015260a401610ede565b604051630e1bd41160e11b81523090631c37a82290610ff4908790879087908790600401614c59565b600060405180830381600087803b15801561100e57600080fd5b505af192505050801561101f575060015b6110dd576040518060400160405280825181526020018280519060200120815250601f60008661ffff1661ffff168152602001908152602001600020846040516110699190614ca2565b9081526040805191829003602090810183206001600160401b038716600090815290825291909120835181559201516001909201919091557fe6f254030bcb01ffd20558175c13fcaed6d1520be7becee4c961b65f79243b0d906110d4908690869086908690614c59565b60405180910390a15b50505050565b60006110ef600d613049565b905090565b60006001600160e01b0319821663b7d1e49960e01b148061112557506001600160e01b031982166303edf24760e01b145b8061114057506001600160e01b03198216633daba23f60e11b145b8061115b57506001600160e01b03198216630704183b60e11b145b8061117657506001600160e01b031982166302494e8b60e01b145b8061119157506001600160e01b0319821663152a902d60e11b145b806111ac57506001600160e01b0319821663131e54b760e01b145b806111c757506001600160e01b031982166323a87ba160e01b145b806111e257506001600160e01b0319821663253f8c7960e11b145b806111fd57506001600160e01b031982166329499a2560e01b145b8061121857506001600160e01b031982166317573c7360e21b145b8061123357506001600160e01b03198216632471dd5960e11b145b8061124e57506001600160e01b03198216634ba1182b60e11b145b8061126957506001600160e01b0319821663e8a3d48560e01b145b8061128457506001600160e01b0319821663938e3d7b60e01b145b8061129e57506001600160e01b03198216621d356760e01b145b806112ad57506112ad82613056565b92915050565b6060601880546112c290614ba0565b80601f01602080910402602001604051908101604052809291908181526020018280546112ee90614ba0565b801561133b5780601f106113105761010080835404028352916020019161133b565b820191906000526020600020905b81548152906001019060200180831161131e57829003601f168201915b5050505050905090565b6000611350826130a6565b6113b15760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ede565b506000908152601c60205260409020546001600160a01b031690565b60006113d882611d85565b9050806001600160a01b0316836001600160a01b0316036114455760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610ede565b336001600160a01b038216148061146157506114618133612b7a565b6114ce5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776044820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b6064820152608401610ede565b6114d883836130c3565b505050565b6114ee63ca4b208b60e01b33613131565b61150a576040516282b42960e81b815260040160405180910390fd5b611514828261313e565b5050565b60006115248383613131565b9392505050565b61153c638da5cb5b60e01b33613131565b611558576040516282b42960e81b815260040160405180910390fd5b611569638da5cb5b60e01b82613131565b6115d457611581816001600160a01b03166014612eae565b611590638da5cb5b6004612eae565b61159b336014612eae565b6040516020016115ad93929190614cbe565b60408051601f1981840301815290829052630330dbc960e11b8252610ede91600401614751565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60006110ef60165490565b61161263ca4b208b60e01b33613131565b61162e576040516282b42960e81b815260040160405180910390fd5b6116366132b8565b565b3330146116b257604051630330dbc960e11b815260206004820152604d6024820152600080516020615dd383398151915260448201527f6520646964206e6f7420636f6d6520696e7465726e616c6c792c20796f75206660648201526c61696c65642c204920776f6e2160981b608482015260a401610ede565b6110dd84848484613347565b6116c9335b8261337c565b6116e55760405162461bcd60e51b8152600401610ede90614d77565b6114d883838361343e565b6004546003546117009190614dde565b42101561173a57426004546003546117189190614dde565b60405163f3f82ac560e01b815260048101929092526024820152604401610ede565b6003546000036117bf57604051630330dbc960e11b815260206004820152604360248201527f54696d65436f703a20596f75277665206265656e2054696d6520436f7070656460448201527f2e204e474c206f6e6c794465762829206861736e277420736574207468652074606482015262696d6560e81b608482015260a401610ede565b600a6117ca33611e7f565b106117fc576117da336014612eae565b6117eb6117e633611e7f565b6135cc565b6040516020016115ad929190614df6565b61180d336118086136cc565b6136e5565b6116366136ff565b600b54600c546001600160a01b03909116906000906103e8906118389085614e7b565b6118429190614eb0565b90509250929050565b636525904560e11b61185d8133613131565b8061187457506118746303e1469160e61b33613131565b1561189c573361188b636525904560e11b82613717565b61151463ca4b208b60e01b82613723565b6118ab60e082901c6004612eae565b6118ba63f851a4406004612eae565b6118c5336014612eae565b6040516020016115ad93929190614ec4565b50565b6118eb638da5cb5b60e01b33613131565b611907576040516282b42960e81b815260040160405180910390fd5b6118d7308261372f565b636525904560e11b6119238133613131565b8061193a575061193a6303e1469160e61b33613131565b1561189c5733611514636525904560e11b82613717565b61196263ca4b208b60e01b33613131565b61197e576040516282b42960e81b815260040160405180910390fd5b6118d7816137c2565b6114d883838360405180602001604052806000815250612210565b6119ab336116c3565b6119ca576119ba336014612eae565b6040516020016115ad9190614f51565b6119d38161390a565b6118d7613993565b816119e68133613131565b806119fd57506119fd6303e1469160e61b33613131565b1561189c57631ada6fbb60e11b6001600160e01b0319841601611a6a576001600160a01b0382163314611a6a57611a35336014612eae565b611a4460e085901c6004612eae565b611a58846001600160a01b03166014612eae565b6040516020016115ad93929190614feb565b63392d1a5360e11b6001600160e01b0319841601611ad2576001600160a01b0382163314611ad257611a9d336014612eae565b611aac60e085901c6004612eae565b611ac0846001600160a01b03166014612eae565b6040516020016115ad939291906150a4565b6114d88383613717565b336000818152600860205260408120549003611b0d57611afd336014612eae565b6040516020016115ad91906150af565b600060075447611b1d9190614dde565b6001600160a01b0383166000908152600960209081526040808320546006546008909352908320549394509192611b549085614e7b565b611b5e9190614eb0565b611b689190615101565b905080600003611b8d57611b7d336014612eae565b6040516020016115ad9190615118565b6001600160a01b038316600090815260096020526040902054611bb1908290614dde565b6001600160a01b038416600090815260096020526040902055600754611bd8908290614dde565b600755611be5838261399d565b7fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b0568382604051611c16929190614559565b60405180910390a1505050565b611c3463ca4b208b60e01b33613131565b611c50576040516282b42960e81b815260040160405180910390fd5b600060228054611c5f90614ba0565b80601f0160208091040260200160405190810160405280929190818152602001828054611c8b90614ba0565b8015611cd85780601f10611cad57610100808354040283529160200191611cd8565b820191906000526020600020905b815481529060010190602001808311611cbb57829003601f168201915b505050505090508160229081611cee91906151ca565b507fd2877107a884510f506ed0bd833e6601f4344691e32a0ce4bcdedb1d9d9d28e1816022604051611d21929190615300565b60405180910390a15050565b6000611d39600d613ab6565b6010546110ef9190615101565b63ca4b208b60e01b611d588133613131565b80611d6f5750611d6f6303e1469160e61b33613131565b1561189c57611514636525904560e11b83613723565b6000818152601a60205260408120546001600160a01b0316806112ad5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610ede565b63ca4b208b60e01b611e0e8133613131565b80611e255750611e256303e1469160e61b33613131565b1561189c5733611e3c63ca4b208b60e01b84613723565b6114d863ca4b208b60e01b82613717565b80611e588133613131565b80611e6f5750611e6f6303e1469160e61b33613131565b1561189c57336114d88382613717565b60006001600160a01b038216611eea5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610ede565b506001600160a01b03166000908152601b602052604090205490565b638da5cb5b60e01b611f188133613131565b80611f2f5750611f2f6303e1469160e61b33613131565b1561189c5733611514638da5cb5b60e01b82613717565b602080526000908152604090208054611f5e90614ba0565b80601f0160208091040260200160405190810160405280929190818152602001828054611f8a90614ba0565b8015611fd75780601f10611fac57610100808354040283529160200191611fd7565b820191906000526020600020905b815481529060010190602001808311611fba57829003601f168201915b505050505081565b60006004546003546110ef9190614dde565b6346d2e5ad60e11b6120038133613131565b8061201a575061201a6303e1469160e61b33613131565b1561189c57336120316346d2e5ad60e11b82613717565b611514638da5cb5b60e01b82613723565b6000600a82815481106120575761205761532e565b6000918252602090912001546001600160a01b031692915050565b612083638da5cb5b60e01b33613131565b61209f576040516282b42960e81b815260040160405180910390fd5b611514828261372f565b6120ba63ca4b208b60e01b33613131565b6120d6576040516282b42960e81b815260040160405180910390fd5b6118d781613ac3565b6060600d60050180546112c290614ba0565b612102638da5cb5b60e01b33613131565b61211e576040516282b42960e81b815260040160405180910390fd5b602155565b6060601980546112c290614ba0565b6000806003546004546003546121489190614dde565b915091509091565b611514338383613b94565b6346d2e5ad60e11b61216d8133613131565b8061218457506121846303e1469160e61b33613131565b1561189c57336115146346d2e5ad60e11b82613717565b63ca4b208b60e01b6121ad8133613131565b806121c457506121c46303e1469160e61b33613131565b1561189c573361151463ca4b208b60e01b82613717565b6121ec638da5cb5b60e01b33613131565b612208576040516282b42960e81b815260040160405180910390fd5b611636613c5e565b61221a338361337c565b6122365760405162461bcd60e51b8152600401610ede90614d77565b6110dd84848484613cac565b61225363ca4b208b60e01b33613131565b61226f576040516282b42960e81b815260040160405180910390fd5b6000306001600160a01b0316635c17e3706040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d39190615344565b905060005b818110156115145761234d306001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612321573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612345919061535d565b6118086136cc565b612355613cdf565b6001016122d8565b6060612368826130a6565b61238557612375826135cc565b6040516020016115ad919061537a565b600061238f613cf3565b604080518082019091526005815264173539b7b760d91b60208201528151919250906123ca57604051806020016040528060008152506123f7565b816123d4856135cc565b826040516020016123e7939291906153e6565b6040516020818303038152906040525b949350505050565b60035442101561242f5760035460405163f3f82ac560e01b81524260048201526024810191909152604401610ede565b60045460035461243f9190614dde565b421061247857426004546003546124569190614dde565b6040516343c540ef60e01b815260048101929092526024820152604401610ede565b600461248333611e7f565b106124b057612493336014612eae565b61249f6117e633611e7f565b6040516020016115ad929190615429565b60028111156124de576124c4336014612eae565b6124cd826135cc565b6040516020016115ad9291906154ac565b60005b818110156115145760046124f433611e7f565b1061253557612504336014612eae565b61250d836135cc565b61252361251933611e7f565b6117e69086614dde565b6040516020016115ad93929190615530565b612541336118086136cc565b6125496136ff565b6001016124e1565b61255a81611d85565b6001600160a01b0316336001600160a01b03161461258a576040516282b42960e81b815260040160405180910390fd5b61ffff82166000908152602080526040902080546125a790614ba0565b905060000361262b57604051630330dbc960e11b815260206004820152604360248201527f546f6b656e3a204f6b2074686520446576206469646e2774207365742074686960448201527f7320706172616d617465722c20636f6e74616374204d6178466c6f774f322e656064820152623a341760e91b608482015260a401610ede565b6126348161390a565b61263c613993565b60003382604051602001612651929190614559565b60408051601f1981840301815290829052602154600160f01b60208401526022830152915060019060009060420160408051601f1981840301815290829052601e5463040a7bb160e41b83529092506000916001600160a01b03909116906340a7bb10906126cb90899030908990879089906004016155f1565b6040805180830381865afa1580156126e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061270b9190615645565b5090503481111561274557612721336014612eae565b61272a346135cc565b612733836135cc565b6040516020016115ad93929190615669565b601e5461ffff87166000908152602080526040808220905162c5803160e81b81526001600160a01b039093169263c580310092349261278f928c928b913391908b906004016156eb565b6000604051808303818588803b1580156127a857600080fd5b505af11580156127bc573d6000803e3d6000fd5b5050505050505050505050565b61ffff85166000908152601f602052604080822090516127ea908790614ca2565b90815260408051602092819003830190206001600160401b038716600090815292529020600181015490915061288a57604051630330dbc960e11b815260206004820152604a6024820152600080516020615dd383398151915260448201527f652077617320616c72656164792065786563757465642c20796f75206661696c60648201526965642c204920776f6e2160b01b608482015260a401610ede565b8054821415806128b55750806001015483836040516128aa929190615752565b604051809103902014155b1561292557604051630330dbc960e11b815260206004820152604460248201819052600080516020615dd3833981519152908201527f6520776173206e6f742073746f7265642c20796f75206661696c65642c204920606482015263776f6e2160e01b608482015260a401610ede565b60008082556001820155604051630e1bd41160e11b81523090631c37a8229061295a908990899089908990899060040161578b565b600060405180830381600087803b15801561297457600080fd5b505af1158015612988573d6000803e3d6000fd5b50505050505050505050565b638da5cb5b60e01b6129a68133613131565b806129bd57506129bd6303e1469160e61b33613131565b1561189c576115146346d2e5ad60e11b83613723565b6129e463ca4b208b60e01b33613131565b612a00576040516282b42960e81b815260040160405180910390fd5b6003829055600481905560408051838152602081018390527f5ef81ff0fe28d74938986521db9f3fb5637cae3d1cec04a94b4a0d3a3b0fc3c49101611d21565b6060600d60040180546112c290614ba0565b81612a5d8133613131565b80612a745750612a746303e1469160e61b33613131565b1561189c57631ada6fbb60e11b6001600160e01b0319841601612ae757612aa2636525904560e11b33613131565b15612ae757612ab2336014612eae565b612ac160e085901c6004612eae565b612ad5846001600160a01b03166014612eae565b6040516020016115ad939291906157ca565b63392d1a5360e11b6001600160e01b0319841601612b5557612b106346d2e5ad60e11b33613131565b15612b5557612b20336014612eae565b612b2f60e085901c6004612eae565b612b43846001600160a01b03166014612eae565b6040516020016115ad9392919061584b565b6114d88383613723565b60006110ef600d613ab6565b6060600580546112c290614ba0565b6001600160a01b039182166000908152601d6020908152604080832093909416825291909152205460ff1690565b612bb963ca4b208b60e01b33613131565b612bd5576040516282b42960e81b815260040160405180910390fd5b61ffff831660009081526020805260409020612bf2828483615856565b507f93c35c217d799290d33244ef8905b63167d13758ab18343cd8055ed1b8056748838383604051611c1693929190615910565b6000612c32600d613049565b600f546110ef9190615101565b7f9a064d674ddc42ac41b38566457161f1ded37e65a59162da003dd25bcb057b603334604051612c70929190614559565b60405180910390a1565b638da5cb5b60e01b612c8c8133613131565b80612ca35750612ca36303e1469160e61b33613131565b1561189c5733612cba638da5cb5b60e01b84613723565b6114d8638da5cb5b60e01b82613717565b612cdc63ca4b208b60e01b33613131565b612cf8576040516282b42960e81b815260040160405180910390fd5b612d03868686613d02565b612d0d8383613d65565b601e80546001600160a01b0319166001600160a01b03929092169190911790555050505050565b612d4563ca4b208b60e01b33613131565b612d61576040516282b42960e81b815260040160405180910390fd5b612d7263ca4b208b60e01b82613131565b612db657612d8a816001600160a01b03166014612eae565b612d9963ca4b208b6004612eae565b612da4336014612eae565b6040516020016115ad9392919061592e565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038116612dfe576040516282b42960e81b815260040160405180910390fd5b612e09838383613d85565b15612e4257612e22816001600160a01b03166014612eae565b612e3160e084901c6004612eae565b6040516020016115ad9291906159ea565b6001600160a01b0381166000908152602084815260408083206001600160e01b03198616845290915290819020805460ff1916600190811790915590517fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f791611c169185918591615a4e565b60606000612ebd836002614e7b565b612ec8906002614dde565b6001600160401b03811115612edf57612edf614589565b6040519080825280601f01601f191660200182016040528015612f09576020820181803683370190505b509050600360fc1b81600081518110612f2457612f2461532e565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612f5357612f5361532e565b60200101906001600160f81b031916908160001a9053506000612f77846002614e7b565b612f82906001614dde565b90505b6001811115612ffa576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612fb657612fb661532e565b1a60f81b828281518110612fcc57612fcc61532e565b60200101906001600160f81b031916908160001a90535060049490941c93612ff381615a7b565b9050612f85565b5083156115245760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610ede565b60006112ad826006015490565b60006001600160e01b031982166380ac58cd60e01b148061308757506001600160e01b03198216635b5e139f60e01b145b806112ad57506301ffc9a760e01b6001600160e01b03198316146112ad565b6000908152601a60205260409020546001600160a01b0316151590565b6000818152601c6020526040902080546001600160a01b0319166001600160a01b03841690811790915581906130f882611d85565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611524818484613d85565b6001600160a01b03821661316557604051630330dbc960e11b8152600401610ede90615a92565b806000036131b657604051630330dbc960e11b815260206004820152601d60248201527f5061796d656e7453706c69747465723a207368617265732061726520300000006044820152606401610ede565b6001600160a01b0382166000908152600860205260409020541561321b576131e8826001600160a01b03166014612eae565b6001600160a01b03831660009081526008602052604090205461320a906135cc565b6040516020016115ad929190615ade565b600a8054600181019091557fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a80180546001600160a01b0319166001600160a01b0384169081179091556000908152600860205260409020819055600654613283908290614dde565b6006556040517f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac90611d219084908490614559565b600a5460005b81811015613306576000600a82815481106132db576132db61532e565b60009182526020808320909101546001600160a01b03168252600890526040812055506001016132be565b50600660009055600a600061331b9190614527565b6040517f3407fd525bf6581e0ae8e3a3636bd90d02112bea34d66802743c28ced73f910e90600090a150565b6000808280602001905181019061335e9190615b58565b9150915061336c82826136e5565b613374613709565b505050505050565b6000613387826130a6565b6133e85760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ede565b60006133f383611d85565b9050806001600160a01b0316846001600160a01b0316148061342e5750836001600160a01b031661342384611345565b6001600160a01b0316145b806123f757506123f78185612b7a565b826001600160a01b031661345182611d85565b6001600160a01b0316146134b95760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610ede565b6001600160a01b03821661351b5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610ede565b6135266000826130c3565b6001600160a01b0383166000908152601b6020526040812080546001929061354f908490615101565b90915550506001600160a01b0382166000908152601b6020526040812080546001929061357d908490614dde565b90915550506000818152601a602052604080822080546001600160a01b0319166001600160a01b038681169182179092559151849391871691600080516020615df383398151915291a4505050565b6060816000036135f35750506040805180820190915260018152600360fc1b602082015290565b8160005b811561361d578061360781615b86565b91506136169050600a83614eb0565b91506135f7565b6000816001600160401b0381111561363757613637614589565b6040519080825280601f01601f191660200182016040528015613661576020820181803683370190505b5090505b84156123f757613676600183615101565b9150613683600a86615b9f565b61368e906030614dde565b60f81b8183815181106136a3576136a361532e565b60200101906001600160f81b031916908160001a9053506136c5600a86614eb0565b9450613665565b60006136d8600d613de2565b6017546110ef9190614dde565b611514828260405180602001604052806000815250613e0d565b613709600d613e40565b611636601680546001019055565b61151460008383613e50565b61151460008383612dd8565b6103e88110158061373e575080155b156137685761374e336014612eae565b613757826135cc565b6040516020016115ad929190615bb3565b600b80546001600160a01b0319166001600160a01b038416908117909155600c8290556040805183815260208101929092527f184520f1b2fcf99836992b9a6b987afc0e4867f26a00ef438c654318763fe1e39101611d21565b6001600160a01b0381166137e957604051630330dbc960e11b8152600401610ede90615a92565b60006137f482613f1d565b600a805491925060009161380a90600190615101565b8154811061381a5761381a61532e565b600091825260209091200154600a80546001600160a01b0390921692508291849081106138495761384961532e565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600a80548061388857613888615c42565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0385168252600890526040812080549190556006546138d5908290615101565b6006556040517f104b8837ec12e86f303ac7ce5e3bf20c6790f843fabd7451943f3390fc8376cb906110d49086908490614559565b600061391582611d85565b90506139226000836130c3565b6001600160a01b0381166000908152601b6020526040812080546001929061394b908490615101565b90915550506000828152601a602052604080822080546001600160a01b0319169055518391906001600160a01b03841690600080516020615df3833981519152908390a45050565b6116366016613f77565b804710156139ed5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610ede565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613a3a576040519150601f19603f3d011682016040523d82523d6000602084013e613a3f565b606091505b50509050806114d85760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610ede565b60006112ad826007015490565b600060058054613ad290614ba0565b80601f0160208091040260200160405190810160405280929190818152602001828054613afe90614ba0565b8015613b4b5780601f10613b2057610100808354040283529160200191613b4b565b820191906000526020600020905b815481529060010190602001808311613b2e57829003601f168201915b505050505090508160059081613b6191906151ca565b507f17f75bb1e35b058872a221a8c16d8b3e39eacbda214fd7da20f192b9291ecc3b816005604051611d21929190615300565b816001600160a01b0316836001600160a01b031603613bf15760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b6044820152606401610ede565b6001600160a01b038381166000818152601d6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b600b80546001600160a01b03191690556000600c8190556040805182815260208101929092527f184520f1b2fcf99836992b9a6b987afc0e4867f26a00ef438c654318763fe1e39101612c70565b613cb784848461343e565b613cc384848484613fe0565b6110dd5760405162461bcd60e51b8152600401610ede90615c58565b613ce9600d613e40565b613709600d6140e1565b6060602280546112c290614ba0565b6017839055613d12600d836140f1565b613d1d600d82614131565b7f0e59e2733e85d32179b3dffa920faef60cc432823591194c4e5f0ac15db3dcec8284613d4a8183614dde565b60408051938452602084019290925290820152606001611c16565b613d70600d82614171565b613d7b600d83614245565b611514600d614319565b60006001600160a01b038216613dad576040516282b42960e81b815260040160405180910390fd5b506001600160a01b03166000908152602092835260408082206001600160e01b03199390931682529190925290205460ff1690565b60008160020154613df4836006015490565b8360010154613e039190614dde565b6112ad9190615b9f565b613e178383614406565b613e246000848484613fe0565b6114d85760405162461bcd60e51b8152600401610ede90615c58565b6118d78160060180546001019055565b6001600160a01b038116613e76576040516282b42960e81b815260040160405180910390fd5b613e81838383613d85565b613eb957613e99816001600160a01b03166014612eae565b613ea860e084901c6004612eae565b6040516020016115ad929190615caa565b6001600160a01b0381166000908152602084815260408083206001600160e01b031986168452909152808220805460ff19169055517fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f791611c169185918591615a4e565b600a54600090815b81811015613f7057836001600160a01b0316600a8281548110613f4a57613f4a61532e565b6000918252602090912001546001600160a01b031603613f68578092505b600101613f25565b5050919050565b80546000819003613fd557604051630330dbc960e11b815260206004820152602160248201527f436f756e7465727356323a204e6f206e656761746976657320696e2075696e746044820152607360f81b6064820152608401610ede565b508054600019019055565b60006001600160a01b0384163b156140d657604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614024903390899088908890600401615d10565b6020604051808303816000875af192505050801561405f575060408051601f3d908101601f1916820190925261405c91810190615d4d565b60015b6140bc573d80801561408d576040519150601f19603f3d011682016040523d82523d6000602084013e614092565b606091505b5080516000036140b45760405162461bcd60e51b8152600401610ede90615c58565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506123f7565b506001949350505050565b6118d78160070180546001019055565b6002820180549082905560408051838152602081018390527fe26aa1327aec5016c96875498202eebb896e3c2a79cd281ff17ed5bde4e545db9101611c16565b6003820180549082905560408051838152602081018390527fef40c7688f323b7ccad323bec82bfee336d16c0939c46bee1f3e5df296dadde39101611c16565b600082600501805461418290614ba0565b80601f01602080910402602001604051908101604052809291908181526020018280546141ae90614ba0565b80156141fb5780601f106141d0576101008083540402835291602001916141fb565b820191906000526020600020905b8154815290600101906020018083116141de57829003601f168201915b505050505090508183600501908161421391906151ca565b507f5769620297eb5047703c0ba55dd28b8ea50ba49818a91a43217fedce8eb69a308282604051611c16929190615d6a565b600082600401805461425690614ba0565b80601f016020809104026020016040519081016040528092919081815260200182805461428290614ba0565b80156142cf5780601f106142a4576101008083540402835291602001916142cf565b820191906000526020600020905b8154815290600101906020018083116142b257829003601f168201915b50505050509050818360040190816142e791906151ca565b507f7058c986a2931f38a70c3f70689d1f2bb75efb4d0082511082db4b2d40492b4f8282604051611c16929190615d6a565b806002015460000361438257604051630330dbc960e11b815260206004820152602b60248201527f50737565646f52616e646f6d204c69623a204d6178696d756d2043617061636960448201526a7479206e6f74207365742160a81b6064820152608401610ede565b806002015442338360040184600501446040516020016143a6959493929190615d8f565b6040516020818303038152906040528051906020012060001c6143c99190615b9f565b600182018190556040519081527f74d17dde2d5b61215fe87f93cddcd2470527e8b0381734da7d0dfeb3fcf6f8179060200160405180910390a150565b6001600160a01b03821661445c5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610ede565b614465816130a6565b156144b25760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610ede565b6001600160a01b0382166000908152601b602052604081208054600192906144db908490614dde565b90915550506000818152601a602052604080822080546001600160a01b0319166001600160a01b0386169081179091559051839290600080516020615df3833981519152908290a45050565b50805460008255906000526020600020908101906118d791905b808211156145555760008155600101614541565b5090565b6001600160a01b03929092168252602082015260400190565b803561ffff8116811461458457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126145b057600080fd5b81356001600160401b03808211156145ca576145ca614589565b604051601f8301601f19908116603f011681019082821181831017156145f2576145f2614589565b8160405283815286602085880101111561460b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b80356001600160401b038116811461458457600080fd5b6000806000806080858703121561465857600080fd5b61466185614572565b935060208501356001600160401b038082111561467d57600080fd5b6146898883890161459f565b94506146976040880161462b565b935060608701359150808211156146ad57600080fd5b506146ba8782880161459f565b91505092959194509250565b6001600160e01b0319811681146118d757600080fd5b6000602082840312156146ee57600080fd5b8135611524816146c6565b60005b838110156147145781810151838201526020016146fc565b838111156110dd5750506000910152565b6000815180845261473d8160208601602086016146f9565b601f01601f19169290920160200192915050565b6020815260006115246020830184614725565b60006020828403121561477657600080fd5b5035919050565b6001600160a01b03811681146118d757600080fd5b600080604083850312156147a557600080fd5b82356147b08161477d565b946020939093013593505050565b600080604083850312156147d157600080fd5b82356147dc816146c6565b915060208301356147ec8161477d565b809150509250929050565b60006020828403121561480957600080fd5b81356115248161477d565b60008060006060848603121561482957600080fd5b83356148348161477d565b925060208401356148448161477d565b929592945050506040919091013590565b6000806040838503121561486857600080fd5b50508035926020909101359150565b60006020828403121561488957600080fd5b81356001600160401b0381111561489f57600080fd5b6123f78482850161459f565b6000602082840312156148bd57600080fd5b61152482614572565b6000806000606084860312156148db57600080fd5b6148e484614572565b925060208401356001600160401b038111156148ff57600080fd5b61490b8682870161459f565b925050604084013590509250925092565b6000806040838503121561492f57600080fd5b823561493a8161477d565b9150602083013580151581146147ec57600080fd5b6000806000806080858703121561496557600080fd5b84356149708161477d565b935060208501356149808161477d565b92506040850135915060608501356001600160401b038111156149a257600080fd5b6146ba8782880161459f565b600080604083850312156149c157600080fd5b6147b083614572565b60008083601f8401126149dc57600080fd5b5081356001600160401b038111156149f357600080fd5b602083019150836020828501011115614a0b57600080fd5b9250929050565b600080600080600060808688031215614a2a57600080fd5b614a3386614572565b945060208601356001600160401b0380821115614a4f57600080fd5b614a5b89838a0161459f565b9550614a696040890161462b565b94506060880135915080821115614a7f57600080fd5b50614a8c888289016149ca565b969995985093965092949392505050565b60008060408385031215614ab057600080fd5b82356147dc8161477d565b600080600060408486031215614ad057600080fd5b614ad984614572565b925060208401356001600160401b03811115614af457600080fd5b614b00868287016149ca565b9497909650939450505050565b60008060008060008060c08789031215614b2657600080fd5b86359550602087013594506040870135935060608701356001600160401b0380821115614b5257600080fd5b614b5e8a838b0161459f565b94506080890135915080821115614b7457600080fd5b50614b8189828a0161459f565b92505060a0870135614b928161477d565b809150509295509295509295565b600181811c90821680614bb457607f821691505b602082108103614bd457634e487b7160e01b600052602260045260246000fd5b50919050565b60008154614be781614ba0565b60018281168015614bff5760018114614c1457614c43565b60ff1984168752821515830287019450614c43565b8560005260208060002060005b85811015614c3a5781548a820152908401908201614c21565b50505082870194505b5050505092915050565b60006115248284614bda565b61ffff85168152608060208201526000614c766080830186614725565b6001600160401b03851660408401528281036060840152614c978185614725565b979650505050505050565b60008251614cb48184602087016146f9565b9190910192915050565b76026b0bc20b1b1b2b9b99d102a34329030b2323932b9b99604d1b815260008451614cf08160178501602089016146f9565b7f206973206e6f7420616e206f776e657220616e6420646f6573206e6f742068616017918401918201526b03b32903a3432903937b632960a51b60378201528451614d428160438401602089016146f9565b660103a3432b932960cd1b604392909101918201528351614d6a81604a8401602088016146f9565b01604a0195945050505050565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008219821115614df157614df1614dc8565b500190565b6902a37b5b2b71d1027b5960b51b815260008351614e1b81600a8501602088016146f9565b690103cb7ba903430bb32960b51b600a918401918201528351614e458160148401602088016146f9565b7f206d6178696d756d20617420746869732074696d652069732031302e0000000060149290910191820152603001949350505050565b6000816000190483118215151615614e9557614e95614dc8565b500290565b634e487b7160e01b600052601260045260246000fd5b600082614ebf57614ebf614e9a565b500490565b7f4d61784163636573733a20596f75206172652061206e6f7420616e2000000000815260008451614efc81601c8501602089016146f9565b80830190506301037b9160e51b601c8201528451614f218160208401602089016146f9565b808201915050600160fd1b60208201528351614f448160218401602088016146f9565b0160210195945050505050565b6f022a9219b9918a13ab93730b136329d160851b815260008251614f7c8160108501602087016146f9565b7f206973206e6f74206f776e6572206e6f7220617070726f7665640000000000006010939091019283015250602a01919050565b7f4d61784163636573733a20596f752061726520612070656e64696e6720646576815268032b637b832b91414960bd1b602082015260290190565b6000614ff682614fb0565b8551615006818360208a016146f9565b780103cb7ba9031b0b7103737ba103932bb37b5b2903937b6329603d1b9101908152845161503b8160198401602089016146f9565b630103a37960e51b60199290910191820152835161506081601d8401602088016146f9565b01601d0195945050505050565b7f4d61784163636573733a20596f752061726520612070656e64696e67206f776e815264032b91414960dd1b602082015260250190565b6000614ff68261506d565b7002830bcb6b2b73a29b83634ba3a32b91d1607d1b8152600082516150db8160118501602087016146f9565b6e103430b99037379039b430b932b99760891b6011939091019283015250602001919050565b60008282101561511357615113614dc8565b500390565b7002830bcb6b2b73a29b83634ba3a32b91d1607d1b8152600082516151448160118501602087016146f9565b731034b9903737ba10323ab2903830bcb6b2b73a1760611b6011939091019283015250602501919050565b601f8211156114d857600081815260208120601f850160051c810160208610156151965750805b601f850160051c820191505b81811015613374578281556001016151a2565b600019600383901b1c191660019190911b1790565b81516001600160401b038111156151e3576151e3614589565b6151f7816151f18454614ba0565b8461516f565b602080601f83116001811461522657600084156152145750858301515b61521e85826151b5565b865550613374565b600085815260208120601f198616915b8281101561525557888601518255948401946001909101908401615236565b50858210156152735787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000815461529081614ba0565b8085526020600183811680156152ad57600181146152c7576152f5565b60ff1985168884015283151560051b8801830195506152f5565b866000528260002060005b858110156152ed5781548a82018601529083019084016152d2565b890184019650505b505050505092915050565b6040815260006153136040830185614725565b82810360208401526153258185615283565b95945050505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561535657600080fd5b5051919050565b60006020828403121561536f57600080fd5b81516115248161477d565b7f4552433732314d657461646174613a2055524920717565727920666f722000008152600082516153b281601e8501602087016146f9565b7f2072657475726e73206e6f6e6578697374656e7420746f6b656e000000000000601e939091019283015250603801919050565b600084516153f88184602089016146f9565b84519083019061540c8183602089016146f9565b845191019061541f8183602088016146f9565b0195945050505050565b6902a37b5b2b71d1027b5960b51b81526000835161544e81600a8501602088016146f9565b690103cb7ba903430bb32960b51b600a9184019182015283516154788160148401602088016146f9565b7a1036b0bc34b6bab69030ba103a3434b9903a34b6b29034b9901a1760291b60149290910191820152602f01949350505050565b6902a37b5b2b71d1027b5960b51b8152600083516154d181600a8501602088016146f9565b730103cb7ba903bb0b73a32b2103a379036b4b73a160651b600a91840191820152835161550581601e8401602088016146f9565b7110191037b9103632b9b990383632b0b9b29760711b601e9290910191820152603001949350505050565b6902a37b5b2b71d1027b5960b51b81526000845161555581600a8501602089016146f9565b730103cb7ba903bb0b73a32b2103a379036b4b73a160651b600a91840191820152845161558981601e8401602089016146f9565b710103a3430ba10383aba39903cb7ba9030ba160751b601e929091019182015283516155bc8160308401602088016146f9565b7a1036b0bc34b6bab69030ba103a3434b9903a34b6b29034b9901a1760291b60309290910191820152604b0195945050505050565b61ffff861681526001600160a01b038516602082015260a06040820181905260009061561f90830186614725565b841515606084015282810360808401526156398185614725565b98975050505050505050565b6000806040838503121561565857600080fd5b505080516020909101519092909150565b6602a37b5b2b71d160cd1b81526000845161568b8160078501602089016146f9565b6501039b2b73a160d51b60079184019182015284516156b181600d8401602089016146f9565b6b01034b739ba32b0b21037b3160a51b600d929091019182015283516156de8160198401602088016146f9565b0160190195945050505050565b61ffff8716815260c06020820152600061570860c0830188615283565b828103604084015261571a8188614725565b6001600160a01b0387811660608601528616608085015283810360a085015290506157458185614725565b9998505050505050505050565b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff861681526080602082015260006157a86080830187614725565b6001600160401b03861660408401528281036060840152615639818587615762565b60006157d582614fb0565b85516157e5818360208a016146f9565b770103cb7ba9031b0b7103737ba1033b930b73a103937b632960451b910190815284516158198160188401602089016146f9565b630103a37960e51b60189290910191820152835161583e81601c8401602088016146f9565b01601c0195945050505050565b60006157d58261506d565b6001600160401b0383111561586d5761586d614589565b6158818361587b8354614ba0565b8361516f565b6000601f8411600181146158af576000851561589d5750838201355b6158a786826151b5565b845550615909565b600083815260209020601f19861690835b828110156158e057868501358255602094850194600190920191016158c0565b50868210156158fd5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b61ffff84168152604060208201526000615325604083018486615762565b76026b0bc20b1b1b2b9b99d102a34329030b2323932b9b99604d1b8152600084516159608160178501602089016146f9565b7f206973206e6f74206120646576656c6f70657220616e6420646f6573206e6f746017918401918201526e0103430bb32903a3432903937b6329608d1b603782015284516159b58160468401602089016146f9565b660103a3432b932960cd1b6046929091019182015283516159dd81604d8401602088016146f9565b01604d0195945050505050565b6a02634b1102937b632b99d160ad1b815260008351615a1081600b8501602088016146f9565b7101030b63932b0b23c903430b9903937b632960751b600b918401918201528351615a4281601d8401602088016146f9565b01601d01949350505050565b6001600160e01b03199390931683526001600160a01b039190911660208301521515604082015260600190565b600081615a8a57615a8a614dc8565b506000190190565b6020808252602c908201527f5061796d656e7453706c69747465723a206163636f756e74206973207468652060408201526b7a65726f206164647265737360a01b606082015260800190565b7002830bcb6b2b73a29b83634ba3a32b91d1607d1b815260008351615b0a8160118501602088016146f9565b6c01030b63932b0b23c903430b99609d1b6011918401918201528351615b3781601e8401602088016146f9565b671039b430b932b99760c11b601e9290910191820152602601949350505050565b60008060408385031215615b6b57600080fd5b8251615b768161477d565b6020939093015192949293505050565b600060018201615b9857615b98614dc8565b5060010190565b600082615bae57615bae614e9a565b500690565b72022a921991c9c18a1b7b63632b1ba34b7b71d1606d1b815260008351615be18160138501602088016146f9565b6a01039bab136b4ba3a32b2160ad1b6013918401918201528351615c0c81601e8401602088016146f9565b7f20616e642074686174206973206f7574206f6620626f756e6473210000000000601e9290910191820152603901949350505050565b634e487b7160e01b600052603160045260246000fd5b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6a02634b1102937b632b99d160ad1b815260008351615cd081600b8501602088016146f9565b730103237b2b9903737ba103430bb32903937b632960651b600b918401918201528351615d0481601f8401602088016146f9565b01601f01949350505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090615d4390830184614725565b9695505050505050565b600060208284031215615d5f57600080fd5b8151611524816146c6565b604081526000615d7d6040830185614725565b82810360208401526153258185614725565b8581526bffffffffffffffffffffffff198560601b1660208201526000615dc2615dbc6034840187614bda565b85614bda565b928352505060200194935050505056fe4e6f6e626c6f636b696e6752656365697665723a2054686973206d6573736167ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212203141b7ea1d69d1dba90a4aa8c8ceb739713a9cc2ac8d184bde9f9da53c19d3bb64736f6c634300080f0033
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.