Feature Tip: Add private address tag to any address under My Name Tag !
ERC-721
Overview
Max Total Supply
690 HoW3
Holders
411
Market
Volume (24H)
0.0652 ETH
Min Price (24H)
$69.00 @ 0.021700 ETH
Max Price (24H)
$69.32 @ 0.021800 ETH
Other Info
Token Contract
Balance
5 HoW3Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
HOW
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 1000 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [EIP721] HOW NFT * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice ERC721 Implementation with: * Enhanced EIP173 - Ownership via roles * EIP2981 - NFT Royalties * PaymentSplitter v2 - For "ETH" payments */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.17 <0.9.0; import "./Max-721-2981-PSv2.sol"; import "./lib/721.sol"; import "./lib/Lists.sol"; import "./lib/CountersV2.sol"; import {MerkleProof} from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import "@openzeppelin/contracts/utils/Base64.sol"; contract HOW is Max721 { using Lib721 for Lib721.Token; using Lists for Lists.Access; using CountersV2 for CountersV2.Counter; CountersV2.Counter internal theTokenID; event Claimed(uint256 index, address account, uint256 amount, string what); constructor( string memory _name , string memory _symbol , address _admin , address _dev , address _owner , uint256 _start ) { __Max721_init(_name, _symbol, _admin, _dev, _owner); theTokenID.set(_start); } // set time block modifier preSale() { if (block.timestamp < startTime + period && block.timestamp >= startTime) { _; } else { revert Unauthorized(); } } modifier Sale() { if (block.timestamp >= startTime + period) { _; } else { revert Unauthorized(); } } function setTime( uint256 _start , uint256 _period ) external onlyDev() { startTime = _start; period = _period; } function showTimes() external view returns (uint256, uint256) { return (startTime, startTime + period); } function setCap( uint256 _amount ) external onlyDev() { maxCap = _amount; } function setMerks( bytes32 _admin , bytes32 _homies , bytes32 _normies ) external onlyDev() { admin = _admin; homies = _homies; normies = _normies; } function isClaimedAdmin( uint256 index ) public view returns (bool) { uint256 claimedWordIndex = index / 256; uint256 claimedBitIndex = index % 256; uint256 claimedWord = claimedAdmin[claimedWordIndex]; uint256 mask = (1 << claimedBitIndex); return claimedWord & mask == mask; } function isClaimedHomies( uint256 index ) public view returns (bool) { uint256 claimedWordIndex = index / 256; uint256 claimedBitIndex = index % 256; uint256 claimedWord = claimedHomies[claimedWordIndex]; uint256 mask = (1 << claimedBitIndex); return claimedWord & mask == mask; } function isClaimedNormies( uint256 index ) public view returns (bool) { uint256 claimedWordIndex = index / 256; uint256 claimedBitIndex = index % 256; uint256 claimedWord = claimedNormies[claimedWordIndex]; uint256 mask = (1 << claimedBitIndex); return claimedWord & mask == mask; } function _setClaimedAdmin( uint256 index ) internal { uint256 claimedWordIndex = index / 256; uint256 claimedBitIndex = index % 256; claimedAdmin[claimedWordIndex] = claimedAdmin[claimedWordIndex] | (1 << claimedBitIndex); } function _setClaimedHomies( uint256 index ) internal { uint256 claimedWordIndex = index / 256; uint256 claimedBitIndex = index % 256; claimedHomies[claimedWordIndex] = claimedHomies[claimedWordIndex] | (1 << claimedBitIndex); } function _setClaimedNormies( uint256 index ) internal { uint256 claimedWordIndex = index / 256; uint256 claimedBitIndex = index % 256; claimedNormies[claimedWordIndex] = claimedNormies[claimedWordIndex] | (1 << claimedBitIndex); } function adminMint( uint256 index , address account , uint256 amount , bytes32[] calldata merkleProof ) external preSale() { if (startTime == 0) { revert Unauthorized(); } if (isClaimedAdmin(index)) { revert MaxSplaining({ reason: "Already Claimed" }); } // Verify the merkle proof. bytes32 node = keccak256(abi.encodePacked(index, account, amount)); if (!MerkleProof.verify(merkleProof, admin, node)) { revert MaxSplaining({ reason: "Invalid Proof" }); } // Mark it claimed and send the token. _setClaimedAdmin(index); if (token721.getSupply() + amount > maxCap) { revert Unauthorized(); } else { for (uint c = 0; c < amount;) { // mint each token721.mint(account, theTokenID.current()); emit Transfer(address(0), account, theTokenID.current()); theTokenID.increment(); unchecked { ++c; } } } emit Claimed(index, account, amount, "Admin"); } function homiesMint( uint256 index , address account , bytes32[] calldata merkleProof ) external preSale() { if (startTime == 0) { revert Unauthorized(); } if (isClaimedHomies(index)) { revert MaxSplaining({ reason: "Already Claimed" }); } // Verify the merkle proof. bytes32 node = keccak256(abi.encodePacked(index, account)); if (!MerkleProof.verify(merkleProof, homies, node)) { revert MaxSplaining({ reason: "Invalid Proof" }); } // Mark it claimed and send the token. _setClaimedHomies(index); if (token721.getSupply() + 1 > maxCap) { revert Unauthorized(); } else { token721.mint(account, theTokenID.current()); emit Transfer(address(0), account, theTokenID.current()); theTokenID.increment(); } emit Claimed(index, account, 1, "Homies"); } function normiesMint( uint256 index , address account , bytes32[] calldata merkleProof ) external payable preSale() { if (startTime == 0) { revert Unauthorized(); } if (msg.value != normiesCost) { revert MaxSplaining ({ reason: "msg.value too low" }); } if (isClaimedNormies(index)) { revert MaxSplaining({ reason: "Already Claimed" }); } // Verify the merkle proof. bytes32 node = keccak256(abi.encodePacked(index, account)); if (!MerkleProof.verify(merkleProof, normies, node)) { revert MaxSplaining({ reason: "Invalid Proof" }); } // Mark it claimed and send the token. _setClaimedNormies(index); if (token721.getSupply() + 1 > maxCap) { revert Unauthorized(); } else { token721.mint(account, theTokenID.current()); emit Transfer(address(0), account, theTokenID.current()); theTokenID.increment(); } emit Claimed(index, account, 1, "Normies"); } function publicMint( uint256 quant ) external payable Sale() { if (quant > 5) { revert Unauthorized(); } if (startTime == 0) { revert Unauthorized(); } if (msg.value != publicCost * quant) { revert MaxSplaining ({ reason: "msg.value too low" }); } if (token721.getSupply() + quant > maxCap) { revert Unauthorized(); } else { for (uint c = 0; c < quant;) { // mint each token721.mint(msg.sender, theTokenID.current()); emit Transfer(address(0), msg.sender, theTokenID.current()); theTokenID.increment(); unchecked { ++c; } } } } function setFees( uint256 _normies , uint256 _public ) external onlyDev() { normiesCost = _normies; publicCost = _public; } function setContractURI( string memory newURI ) external onlyDev() { contractURL = newURI; } function contractURI() public view returns (string memory) { return contractURL; } function setJSON( string memory _description , string memory _image , string memory _animation ) external onlyDev() { description = _description; image = _image; animationURI = _animation; } function tokenURI( uint256 tokenId ) public view virtual override returns (string memory) { bytes memory json = abi.encodePacked( "{", '"name": "Homies Genesis #', Strings.toString(uint256(tokenId)), '",', '"description": "', description, '",', '"image": "', image, '",', '"animation_url": "', animationURI, '"', "}" ); return string( abi.encodePacked( "data:application/json;base64,", Base64.encode(json) ) ); } /// @dev Function to receive ether, msg.data must be empty receive() external payable { // From PaymentSplitter.sol emit PaymentReceived(msg.sender, msg.value); } /// @dev Function to receive ether, msg.data is not empty fallback() external payable { // From PaymentSplitter.sol emit PaymentReceived(msg.sender, msg.value); } /// @dev this is a public getter for ETH blance on contract function getBalance() external view returns (uint) { return address(this).balance; } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP] Payment Splitter, interface for ether payments * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Interface for Payment Splitter */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface ISplitter is IERC165 { /// @dev returns total shares /// @return uint256 of all shares on contract function totalShares() external view returns (uint256); /// @dev returns shares of an address /// @param payee address of payee to return /// @return mapping(address => uint) of _shares function shares( address payee ) external view returns (uint256); /// @dev returns total releases in "eth" /// @return uint256 of all "eth" released in wei function totalReleased() external view returns (uint256); /// @dev returns released "eth" of an payee /// @param payee address of payee to look up /// @return mapping(address => uint) of _released function released( address payee ) external view returns (uint256); /// @dev returns amount of "eth" that can be released to payee /// @param payee address of payee to look up /// @return uint in wei of "eth" to release function releasable( address payee ) external view returns (uint256); /// @dev returns index number of payee /// @param payee number of index /// @return address at _payees[index] function payeeIndex( address payee ) external view returns (uint256); /// @dev this returns the array of payees[] /// @return address[] payees function payees() external view returns (address[] memory); /// @dev this claims all "eth" on contract for msg.sender function claim() external; /// @dev This pays all payees function payClaims() external; /// @dev This adds a payee /// @param payee Address of payee /// @param _shares Shares to send user function addPayee( address payee , uint256 _shares ) external; /// @dev This removes a payee /// @param payee Address of payee to remove /// @dev use payPayees() prior to use if anything is on the contract function removePayee( address payee ) external; /// @dev This removes all payees /// @dev use payPayees() prior to use if anything is on the contract function clearPayees() external; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxFlow's 173/Dev/Roles Interface * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Interface for MaxAccess */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "./IMAX173.sol"; import "./IMAXDEV.sol"; import "./IRoles.sol"; interface MaxAccess is IMAX173 , IMAXDEV , IRoles { ///@dev this just imports all 3 and pushes to Implementation }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Roles Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Interface for MaxAccess version of Roles */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IRoles 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 function renounceRole( bytes4 role ) external; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Developer Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Interface for onlyDev() role */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IMAXDEV 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; /// @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: EIP-173: Contract Ownership Standard, MaxFlowO2's extension * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Interface for enhancing EIP-173 * @custom:change-log UUPS Upgradable */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/173/IERC173.sol"; interface IMAX173 is IERC173 { /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external; /// @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: EIP-2981: NFT Royalty Standard, admin extension * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: the ERC-165 identifier for this interface is unknown. * @custom:source https://eips.ethereum.org/EIPS/eip-2981 * @custom:change-log MIT -> Apache-2.0 * */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/2981/IERC2981.sol"; interface IERC2981Admin is IERC2981 { /// @dev function (state storage) sets the royalty data for a token /// @param tokenId uint256 for the token /// @param receiver address for the royalty reciever for token /// @param permille uint16 for the permille of royalties 20 -> 2.0% function setRoyalties( uint256 tokenId , address receiver , uint16 permille ) external; /// @dev function (state storage) revokes the royalty data for a token /// @param tokenId uint256 for the token function revokeRoyalties( uint256 tokenId ) external; /// @dev function (state storage) sets the royalty data for a collection /// @param receiver address for the royalty reciever for token /// @param permille uint16 for the permille of royalties 20 -> 2.0% function setRoyalties( address receiver , uint16 permille ) external; /// @dev function (state storage) revokes the royalty data for a collection function revokeRoyalties() external; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Strings * @author: OpenZeppelin * @notice: Strings Library * @custom:source https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts-upgradeable/v4.7.3/contracts/utils/StringsUpgradeable.sol * @custom:change-log Readable, External/Public, Removed code comments, MIT -> Apache-2.0 * @custom:change-log Added MaxSplaining * @custom:error-code Str:1 "hex length insufficient" * * Include with 'using Strings for <insert type>' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; error MaxSplaining(string reason); 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); } 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); } 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; } if (value != 0) { revert MaxSplaining({ reason: "Str:1" }); } return string(buffer); } function toHexString( address addr ) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Roles.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Library for MaxAcess.sol * @custom:change-log cleaned up variables * * Include with 'using Roles for Roles.Role;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Roles { bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal ADMIN = 0xf851a440; struct Role { mapping(address => mapping(bytes4 => bool)) bearer; address owner; address developer; address admin; } event RoleChanged(bytes4 _role, address _user, bool _status); event AdminTransferred(address indexed previousAdmin, address indexed newAdmin); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event DeveloperTransferred(address indexed previousDeveloper, address indexed newDeveloper); error Unauthorized(); function add( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (has(role, userRole, account)) { revert Unauthorized(); } role.bearer[account][userRole] = true; emit RoleChanged(userRole, account, true); } function remove( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (!has(role, userRole, account)) { revert Unauthorized(); } role.bearer[account][userRole] = false; emit RoleChanged(userRole, account, false); } function has( Role storage role , bytes4 userRole , address account ) internal view returns (bool) { if (account == address(0)) { revert Unauthorized(); } return role.bearer[account][userRole]; } function setAdmin( Role storage role , address account ) internal { if (has(role, ADMIN, account)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setDeveloper( Role storage role , address account ) internal { if (has(role, DEVS, account)) { address old = role.developer; role.developer = account; emit DeveloperTransferred(old, role.developer); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setOwner( Role storage role , address account ) internal { if (has(role, OWNERS, account)) { address old = role.owner; role.owner = account; emit OwnershipTransferred(old, role.owner); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function getAdmin( Role storage role ) internal view returns (address) { return role.admin; } function getDeveloper( Role storage role ) internal view returns (address) { return role.developer; } function getOwner( Role storage role ) internal view returns (address) { return role.owner; } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP] Payment Splitter * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Library for two structs one with "ERC-20's" and one without * @custom:error-code PS:1 No Shares for address * @custom:error-code PS:2 No payment due for address * @custom:error-code PS:3 Can not use address(0) * @custom:error-code PS:4 Shares can not be 0 * @custom:error-code PS:5 User has shares already * @custom:error-code PS:6 User not in payees * @custom:change-log added custom error-codes above */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Payments { struct GasTokens { uint256 totalShares; uint256 totalReleased; mapping(address => uint256) shares; mapping(address => uint256) released; address[] payees; } event PayeeAdded(address account, uint256 _shares); event PayeeRemoved(address account, uint256 _shares); event PayeesReset(); event PaymentReleased(address to, uint256 amount); error MaxSplaining(string reason); function findIndex( address[] memory array , address query ) internal pure returns (bool found, uint256 index) { uint256 len = array.length; for (uint x = 0; x < len;) { if (array[x] == query) { found = true; index = x; } unchecked { ++x; } } } function getTotalReleased( GasTokens storage gasTokens ) internal view returns (uint256) { return gasTokens.totalReleased; } function getTotalShares( GasTokens storage gasTokens ) internal view returns (uint256) { return gasTokens.totalShares; } function payeeShares( GasTokens storage gasTokens , address payee ) internal view returns (uint256) { return gasTokens.shares[payee]; } function payeeReleased( GasTokens storage gasTokens , address payee ) internal view returns (uint256) { return gasTokens.released[payee]; } function payeeIndex( GasTokens storage gasTokens , address payee ) internal view returns (uint256) { (bool found, uint256 index) = findIndex(gasTokens.payees, payee); if (found) { return index; } else { revert MaxSplaining({ reason: "PS:6" }); } } function allPayees( GasTokens storage gasTokens ) internal view returns (address[] memory) { return gasTokens.payees; } function addPayee( GasTokens storage gasTokens , address payee , uint256 _shares ) internal { if (payee == address(0)) { revert MaxSplaining({ reason: "PS:3" }); } else if (_shares == 0) { revert MaxSplaining({ reason: "PS:4" }); } else if (gasTokens.shares[payee] > 0) { revert MaxSplaining({ reason: "PS:5" }); } gasTokens.payees.push(payee); gasTokens.shares[payee] = _shares; gasTokens.totalShares += _shares; emit PayeeAdded(payee, _shares); } function getPayees( GasTokens storage gasTokens ) internal view returns (address[] memory) { return gasTokens.payees; } function removePayee( GasTokens storage gasTokens , address payee ) internal { if (payee == address(0)) { revert MaxSplaining({ reason: "PS:3" }); } uint256 whacked = payeeIndex(gasTokens, payee); address last = gasTokens.payees[gasTokens.payees.length -1]; gasTokens.payees[whacked] = last; gasTokens.payees.pop(); uint256 whackedShares = gasTokens.shares[payee]; delete gasTokens.shares[payee]; gasTokens.totalShares -= whackedShares; emit PayeeRemoved(payee, whackedShares); } function clearPayees( GasTokens storage gasTokens ) internal { uint256 len = gasTokens.payees.length; for (uint x = 0; x < len;) { address whacked = gasTokens.payees[x]; delete gasTokens.shares[whacked]; unchecked { ++x; } } delete gasTokens.totalShares; delete gasTokens.payees; emit PayeesReset(); } function processPayment( GasTokens storage gasTokens , address payee , uint256 payment ) internal { gasTokens.totalReleased += payment; gasTokens.released[payee] += payment; emit PaymentReleased(payee, payment); } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Access lists * @author: @MaxFlowO2 on bird app/GitHub * @notice: Formerly whitelists, now allowlist, or whatever it's called. * @custom:change-log removed end variable/functions (un-needed) * @custom:change-log variables renamed from lib whitelist * @custom:change-log internal -> internal * @custom:error-code A:1 "(user) is already whitelisted." * @custom:error-code A:2 "(user) is not whitelisted." * @custom:error-code A:3 "Whitelist already enabled." * @custom:error-code A:4 "Whitelist already disabled." * @custom:change-log added custom error codes * @custom:change-log removed import "./Strings.sol"; (un-needed) * * Include with 'using Lists for Lists.Access;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "./CountersV2.sol"; library Lists { using CountersV2 for CountersV2.Counter; event ListChanged(bool _old, bool _new, address _address); event ListStatus(bool _old, bool _new); error MaxSplaining(string reason); struct Access { bool _status; CountersV2.Counter added; CountersV2.Counter removed; mapping(address => bool) allowed; } function add( Access storage list , address user ) internal { if (list.allowed[user]) { revert MaxSplaining({ reason : "A:1" }); } // since now all previous values are false no need for another variable // and add them to the list! list.allowed[user] = true; // increment counter list.added.increment(); // emit event emit ListChanged(false, list.allowed[user], user); } function remove( Access storage list , address user ) internal { if (!list.allowed[user]) { revert MaxSplaining({ reason : "A:2" }); } // since now all previous values are true no need for another variable // and remove them from the list! list.allowed[user] = false; // increment counter list.removed.increment(); // emit event emit ListChanged(true, list.allowed[user], user); } function enable( Access storage list ) internal { if (list._status) { revert MaxSplaining({ reason : "A:3" }); } list._status = true; emit ListStatus(false, list._status); } function disable( Access storage list ) internal { if (!list._status) { revert MaxSplaining({ reason : "A:4" }); } list._status = false; emit ListStatus(true, list._status); } function status( Access storage list ) internal view returns (bool) { return list._status; } function totalAdded( Access storage list ) internal view returns (uint) { return list.added.current(); } function totalRemoved( Access storage list ) internal view returns (uint) { return list.removed.current(); } function onList( Access storage list , address user ) internal view returns (bool) { return list.allowed[user]; } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: CountersV2.sol * @author Matt Condon (@shrugs) * @notice 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. * @custom:change-log MIT -> Apache-2.0 * @custom:change-log Edited for more NFT functionality added .set(uint) * @custom:change-log added event CounterNumberChangedTo(uint _number). * @custom:change-log added error MaxSplaining(string reason). * @custom:change-log internal -> internal functions * @custom:error-code C2:1 "No negatives in uints" - overflow protection * * Include with `using CountersV2 for CountersV2.Counter;` */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library CountersV2 { struct Counter { uint256 value; } event CounterNumberChangedTo(uint _number); error MaxSplaining(string reason); 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 { if (counter.value == 0) { revert MaxSplaining({ reason : "C2:1" }); } 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); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @notice : Collection of functions related to the address type */ library Address { /** * @notice : 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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @notice : Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.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"); } /** * @notice : Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @notice : 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); } /** * @notice : 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"); } /** * @notice : Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @notice : 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"); } /** * @notice : Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @notice : 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"); } /** * @notice : Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @notice : Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @notice : Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Library 721 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Library for EIP 721 * @custom:error-code L:1 "non-existent tokenId" * @custom:error-code L:2 "approval to current owner" * @custom:error-code L:3 "approve caller is not token owner nor approved for all" * @custom:error-code L:4 "approve to caller" * @custom:error-code L:5 "caller is not token owner nor approved" * @custom:error-code L:6 "transfer from incorrect owner" * @custom:error-code L:7 "transfer to the zero address" * @custom:error-code L:8 "mint to the zero address" * @custom:error-code L:9 "token already minted" * @custom:change-log Custom errors added above * * Include with 'using Lib721 for Lib721.Token;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "./Strings.sol"; import "./CountersV2.sol"; library Lib721 { using Strings for uint256; using CountersV2 for CountersV2.Counter; struct Token { mapping(uint256 => address) owners; mapping(address => uint256) balances; mapping(uint256 => address) tokenApprovals; mapping(address => mapping(address => bool)) operatorApprovals; string name; string symbol; string baseURI; CountersV2.Counter supply; } event NameSet(string name); event SymbolSet(string symbol); event NewBaseURI(string baseURI); error MaxSplaining(string reason); function getBalanceOf( Token storage token , address owner ) internal view returns (uint256) { return token.balances[owner]; } function getOwnerOf( Token storage token , uint256 tokenId ) internal view returns (address) { return token.owners[tokenId]; } function setName( Token storage token , string memory newName ) internal { token.name = newName; emit NameSet(newName); } function getName( Token storage token ) internal view returns (string memory) { return token.name; } function setSymbol( Token storage token , string memory newSymbol ) internal { token.symbol = newSymbol; emit SymbolSet(newSymbol); } function getSymbol( Token storage token ) internal view returns (string memory) { return token.symbol; } function getSupply( Token storage token ) internal view returns (uint256) { return token.supply.current(); } function setBaseURI( Token storage token , string memory newURI ) internal { token.baseURI = newURI; emit NewBaseURI(newURI); } function getTokenURI( Token storage token , uint256 tokenId ) internal view returns (string memory) { if (getOwnerOf(token, tokenId) == address(0)) { revert MaxSplaining({ reason: "L:1" }); } return bytes(token.baseURI).length > 0 ? string(abi.encodePacked(token.baseURI, tokenId.toString())) : ""; } function setApprove( Token storage token , address to , address by , uint256 tokenId ) internal { address owner = getOwnerOf(token, tokenId); if (to == owner) { revert MaxSplaining({ reason: "L:2" }); } else if (!isApprovedOrOwner(token, by, tokenId)) { revert MaxSplaining({ reason: "L:3" }); } token.tokenApprovals[tokenId] = to; } function getApproved( Token storage token , uint256 tokenId ) internal view returns (address) { if (getOwnerOf(token, tokenId) == address(0)) { revert MaxSplaining({ reason: "L:1" }); } return token.tokenApprovals[tokenId]; } function setApprovalForAll( Token storage token , address operator , address from , bool approved ) internal { if (from == operator) { revert MaxSplaining({ reason: "L:4" }); } token.operatorApprovals[from][operator] = approved; } function isApprovedForAll( Token storage token , address owner , address operator ) internal view returns (bool) { return token.operatorApprovals[owner][operator]; } function isApprovedOrOwner( Token storage token , address spender , uint256 tokenId ) internal view returns (bool) { address owner = getOwnerOf(token, tokenId); return ( spender == owner || isApprovedForAll(token, owner, spender) || getApproved(token, tokenId) == spender ); } function doTransferFrom( Token storage token , address from , address to , address by , uint256 tokenId ) internal { if (!isApprovedOrOwner(token, by, tokenId)) { revert MaxSplaining({ reason: "L:5" }); } address owner = getOwnerOf(token, tokenId); if (owner != from) { revert MaxSplaining({ reason: "L:6" }); } else if (to == address(0)) { revert MaxSplaining({ reason: "L:7" }); } // Clear approvals from the previous owner setApprove(token, address(0), by, tokenId); // Change balances token.balances[from] -= 1; token.balances[to] += 1; // Move tokenId token.owners[tokenId] = to; } function mint( Token storage token , address to , uint256 tokenId ) internal { if (to == address(0)) { revert MaxSplaining({ reason: "L:8" }); } else if (getOwnerOf(token, tokenId) != address(0)) { revert MaxSplaining({ reason: "L:9" }); } token.balances[to] += 1; token.owners[tokenId] = to; token.supply.increment(); } function burn( Token storage token , address by , uint256 tokenId ) internal { address owner = getOwnerOf(token, tokenId); // Clear approvals setApprove(token, address(0), by, tokenId); // Change balances token.balances[owner] -= 1; delete token.owners[tokenId]; token.supply.decrement(); } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Library 2981 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice: Library for EIP 2981 * @custom:error-code R:1 Permille out of bounds * @custom:change-log Custom errors added above * * Include with 'using Lib2981 for Lib2981.Royalties;' -- unique per collection * Include with 'using Lib2981 for Lib2981.MappedRoyalties;' -- unique per token */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Lib2981c { struct Royalties { address receiver; uint16 permille; } event RoyaltiesSet(uint256 token, address recipient, uint16 value); event RoyaltiesSet(address recipient, uint16 value); error MaxSplaining(string reason); function setRoyalties( Royalties storage royalties , address receiver , uint16 permille ) internal { if (permille >= 1000 || permille == 0) { revert MaxSplaining({ reason: "R:1" }); } royalties.receiver = receiver; royalties.permille = permille; emit RoyaltiesSet( royalties.receiver , royalties.permille ); } function revokeRoyalties( Royalties storage royalties ) internal { delete royalties.receiver; delete royalties.permille; emit RoyaltiesSet( royalties.receiver , royalties.permille ); } function royaltyInfo( Royalties storage royalties , uint256 tokenId , uint256 salePrice ) internal view returns ( address receiver , uint256 royaltyAmount ) { receiver = royalties.receiver; royaltyAmount = salePrice * royalties.permille / 1000; } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ERC-721 Non-Fungible Token Standard, required wallet interface * @author: William Entriken, Dieter Shirley, Jacob Evans, Nastassia Sachs * @notice: the ERC-165 identifier for this interface is 0x150b7a02. * @custom:source https://eips.ethereum.org/EIPS/eip-721 * @custom:change-log interface ERC721TokenReceiver -> interface IERC721TokenReceiver * @custom:change-log readability enhanced * @custom:change-log MIT -> Apache-2.0 * @custom:change-log TypeError: Data location must be "memory" or "calldata" for parameter (line 60) * */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC721TokenReceiver is IERC165 { /// @notice Handle the receipt of an NFT /// @notice The ERC721 smart contract calls this function on the recipient /// after a `transfer`. This function MAY throw to revert and reject the /// transfer. Return of other than the magic value MUST result in the /// transaction being reverted. /// Note: the contract address is always the message sender. /// @param _operator The address which called `safeTransferFrom` function /// @param _from The address which previously owned the token /// @param _tokenId The NFT identifier which is being transferred /// @param _data Additional data with no specified format /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` /// unless throwing function onERC721Received( address _operator , address _from , uint256 _tokenId , bytes calldata _data ) external returns(bytes4); }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ERC-721 Non-Fungible Token Standard, optional metadata extension * @author: William Entriken, Dieter Shirley, Jacob Evans, Nastassia Sachs * @notice: the ERC-165 identifier for this interface is 0x5b5e139f. * @custom:source https://eips.ethereum.org/EIPS/eip-721 * @custom:change-log interface ERC721Metadata * is ERC721 * -> interface IERC721Metadata * @custom:change-log readability enhanced * @custom:change-log MIT -> Apache-2.0 * @custom:change-log Data location must be "memory" or "calldata" for return parameter (lines 48, 54, 64) * */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "./IERC721.sol"; interface IERC721Metadata is IERC721 { /// @notice A descriptive name for a collection of NFTs in this contract function name() external view returns (string memory _name); /// @notice An abbreviated name for NFTs in this contract function symbol() external view returns (string memory _symbol); /// @notice A distinct Uniform Resource Identifier (URI) for a given asset. /// @notice Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC /// 3986. The URI may point to a JSON file that conforms to the "ERC721 /// Metadata JSON Schema". function tokenURI( uint256 _tokenId ) external view returns (string memory); }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ERC-721 Non-Fungible Token Standard * @author: William Entriken, Dieter Shirley, Jacob Evans, Nastassia Sachs * @notice: the ERC-165 identifier for this interface is 0x80ac58cd. * @custom:source https://eips.ethereum.org/EIPS/eip-721 * @custom:change-log interface ERC721 * is ERC165 * -> interface IERC721 * @custom:change-log removed payable from IERC721 * @custom:change-log removed events from IERC721 (handled in Lib721) * @custom:change-log readability enhanced * @custom:change-log MIT -> Apache-2.0 * @custom:change-log TypeError: Data location must be "memory" or "calldata" for parameter (line 84) * */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC721 is IERC165 { /// @dev This emits when ownership of any NFT changes by any mechanism. /// This event emits when NFTs are created (`from` == 0) and destroyed /// (`to` == 0). Exception: during contract creation, any number of NFTs /// may be created and assigned without emitting Transfer. At the time of /// any transfer, the approved address for that NFT (if any) is reset to none. event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); /// @dev This emits when the approved address for an NFT is changed or /// reaffirmed. The zero address indicates there is no approved address. /// When a Transfer event emits, this also indicates that the approved /// address for that NFT (if any) is reset to none. event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); /// @dev This emits when an operator is enabled or disabled for an owner. /// The operator can manage all NFTs of the owner. event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); /// @notice Count all NFTs assigned to an owner /// @notice NFTs assigned to the zero address are considered invalid, and this /// function throws for queries about the zero address. /// @param _owner An address for whom to query the balance /// @return The number of NFTs owned by `_owner`, possibly zero function balanceOf( address _owner ) external view returns (uint256); /// @notice Find the owner of an NFT /// @notice NFTs assigned to zero address are considered invalid, and queries /// about them do throw. /// @param _tokenId The identifier for an NFT /// @return The address of the owner of the NFT function ownerOf( uint256 _tokenId ) external view returns (address); /// @notice Transfers the ownership of an NFT from one address to another address /// @notice Throws unless `msg.sender` is the current owner, an authorized /// operator, or the approved address for this NFT. Throws if `_from` is /// not the current owner. Throws if `_to` is the zero address. Throws if /// `_tokenId` is not a valid NFT. When transfer is complete, this function /// checks if `_to` is a smart contract (code size > 0). If so, it calls /// `onERC721Received` on `_to` and throws if the return value is not /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer /// @param data Additional data with no specified format, sent in call to `_to` function safeTransferFrom( address _from , address _to , uint256 _tokenId , bytes calldata data ) external; /// @notice Transfers the ownership of an NFT from one address to another address /// @notice This works identically to the other function with an extra data parameter, /// except this function just sets data to "". /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer function safeTransferFrom( address _from , address _to , uint256 _tokenId ) external; /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE /// THEY MAY BE PERMANENTLY LOST /// @notice Throws unless `msg.sender` is the current owner, an authorized /// operator, or the approved address for this NFT. Throws if `_from` is /// not the current owner. Throws if `_to` is the zero address. Throws if /// `_tokenId` is not a valid NFT. /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer function transferFrom( address _from , address _to , uint256 _tokenId ) external; /// @notice Change or reaffirm the approved address for an NFT /// @notice The zero address indicates there is no approved address. /// Throws unless `msg.sender` is the current NFT owner, or an authorized /// operator of the current owner. /// @param _approved The new approved NFT controller /// @param _tokenId The NFT to approve function approve( address _approved , uint256 _tokenId ) external; /// @notice Enable or disable approval for a third party ("operator") to manage /// all of `msg.sender`'s assets /// @notice Emits the ApprovalForAll event. The contract MUST allow /// multiple operators per owner. /// @param _operator Address to add to the set of authorized operators /// @param _approved True if the operator is approved, false to revoke approval function setApprovalForAll( address _operator , bool _approved ) external; /// @notice Get the approved address for a single NFT /// @notice Throws if `_tokenId` is not a valid NFT. /// @param _tokenId The NFT to find the approved address for /// @return The approved address for this NFT, or the zero address if there is none function getApproved( uint256 _tokenId ) external view returns (address); /// @notice Query if an address is an authorized operator for another address /// @param _owner The address that owns the NFTs /// @param _operator The address that acts on behalf of the owner /// @return True if `_operator` is an approved operator for `_owner`, false otherwise function isApprovedForAll( address _owner , address _operator ) external view returns (bool); }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-2981: NFT Royalty Standard * @author: Zach Burks, James Morgan, Blaine Malone, James Seibel * @notice: the ERC-165 identifier for this interface is 0x2a55205a. * @custom:source https://eips.ethereum.org/EIPS/eip-2981 * @custom:change-log MIT -> Apache-2.0 * */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC2981 is IERC165 { /// ERC165 bytes to add to interface array - set in parent contract /// implementing this standard /// bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a /// bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a; /// _registerInterface(_INTERFACE_ID_ERC2981); /// @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: EIP-173: Contract Ownership Standard * @author: Nick Mudge, Dan Finlay * @notice: This specification defines standard functions for owning or controlling a contract. * the ERC-165 identifier for this interface is 0x7f5828d0 * @custom:URI https://eips.ethereum.org/EIPS/eip-173 * @custom:change-log MIT -> Apache-2.0 * @custom:change-log readability modification */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IERC173 is IERC165 { /// @dev This emits when ownership of a contract changes. event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address); /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-165: Standard Interface Detection * @author: Christian Reitwießner, Nick Johnson, Fabian Vogelsteller, Jordi Baylina, Konrad Feldmeier, William Entriken * @notice: Creates a standard method to publish and detect what interfaces a smart contract implements. * @custom:source https://eips.ethereum.org/EIPS/eip-165 * @custom:change-log interface ERC165 -> interface IERC165 * @custom:change-log readability enhanced * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface IERC165 { /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view returns (bool); }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [EIP721] Max-721 Implementation, using EIP 1822 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice ERC721 Implementation with: * Enhanced EIP173 - Ownership via roles * EIP2981 - NFT Royalties * PsuedoRandom Engine - Expansion of BAYC engine * TimeCop + Lists - For presales * PaymentSplitter v2 - For "ETH" payments */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.17 <0.9.0; import "./eip/721/IERC721TokenReceiver.sol";// import "./eip/721/IERC721Metadata.sol";// import "./eip/721/IERC721.sol";// import "./modules/2981/IERC2981Admin.sol";// import "./modules/access/MaxAccess.sol";// import "./modules/splitter/ISplitter.sol";// import "./lib/Address.sol";// import "./lib/721.sol";// import "./lib/Roles.sol";// import "./lib/2981c.sol";// import "./lib/Payments.sol";// abstract contract Max721 is MaxAccess , IERC721 , IERC721Metadata , IERC721TokenReceiver , IERC2981Admin , ISplitter { using Lib721 for Lib721.Token; using Roles for Roles.Role; using Lib2981c for Lib2981c.Royalties; using Payments for Payments.GasTokens; using Address for address; // The Structs... Lib721.Token internal token721; Roles.Role internal contractRoles; Lib2981c.Royalties internal royalties; Payments.GasTokens internal splitter; // The rest (got to have a few) bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal PENDING_DEVS = 0xca4b208a; // DEVS - 1 bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal PENDING_OWNERS = 0x8da5cb5a; // OWNERS - 1 bytes4 constant internal ADMIN = 0xf851a440; uint256 startTime; // Set to opening (can +48h for secondary) uint256 period; // Set to the period uint256 maxCap; // Cpacity of minter bytes32 internal admin; mapping(uint256 => uint256) internal claimedAdmin; bytes32 internal homies; mapping(uint256 => uint256) internal claimedHomies; bytes32 internal normies; mapping(uint256 => uint256) internal claimedNormies; string internal contractURL; string internal image; string internal description; string internal animationURI; uint256 public normiesCost = 0.069 ether; uint256 public publicCost = 0.1 ether; event PaymentReceived(address indexed _payee, uint256 _amount); /// @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 ); /////////////////////// /// MAX-721: Modifiers /////////////////////// modifier onlyRole(bytes4 role) { if (contractRoles.has(role, msg.sender) || contractRoles.has(ADMIN, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyOwner() { if (contractRoles.has(OWNERS, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyDev() { if (contractRoles.has(DEVS, msg.sender)) { _; } else { revert Unauthorized(); } } /////////////////////// /// MAX-721: Internals /////////////////////// function __Max721_init( string memory _name , string memory _symbol , address _admin , address _dev , address _owner ) internal { token721.setName(_name); token721.setSymbol(_symbol); contractRoles.add(ADMIN, _admin); contractRoles.setAdmin(_admin); contractRoles.add(DEVS, _dev); contractRoles.setDeveloper(_dev); contractRoles.add(OWNERS, _owner); contractRoles.setOwner(_owner); } function safeHook( address from, address to, uint256 tokenId, bytes memory data ) internal returns (bool) { if (to.isContract()) { try IERC721TokenReceiver(to).onERC721Received(msg.sender, from, tokenId, data) returns (bytes4 retval) { return retval == IERC721TokenReceiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert Unauthorized(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } ///////////////////////////////////////// /// EIP-173: Contract Ownership Standard ///////////////////////////////////////// /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address) { return contractRoles.getOwner(); } /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external onlyRole(OWNERS) { contractRoles.add(OWNERS, _newOwner); contractRoles.setOwner(_newOwner); contractRoles.remove(OWNERS, msg.sender); } //////////////////////////////////////////////////////////////// /// EIP-173: Contract Ownership Standard, MaxFlowO2's extension //////////////////////////////////////////////////////////////// /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external onlyRole(OWNERS) { contractRoles.setOwner(address(0)); contractRoles.remove(OWNERS, msg.sender); } /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.add(OWNERS, msg.sender); contractRoles.setOwner(msg.sender); contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external onlyRole(OWNERS) { contractRoles.add(PENDING_OWNERS, newOwner); } ////////////////////////////////////////////// /// [Not an EIP]: Contract Developer Standard ////////////////////////////////////////////// /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address) { return contractRoles.getDeveloper(); } /// @dev This renounces your role as onlyDev() function renounceDeveloper() external onlyRole(DEVS) { contractRoles.setDeveloper(address(0)); contractRoles.remove(DEVS, msg.sender); } /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(DEVS, newDeveloper); contractRoles.setDeveloper(newDeveloper); contractRoles.remove(DEVS, msg.sender); } /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.add(DEVS, msg.sender); contractRoles.setDeveloper(msg.sender); contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(PENDING_DEVS, newDeveloper); } ////////////////////////////////////////// /// [Not an EIP]: Contract Roles Standard ////////////////////////////////////////// /// @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) { return contractRoles.has(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 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 onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { revert Unauthorized(); } else { contractRoles.add(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 onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { if (account == msg.sender) { contractRoles.remove(role, account); } else { revert Unauthorized(); } } else { contractRoles.remove(role, account); } } /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external onlyRole(role) { contractRoles.remove(role, msg.sender); } //////////////////////////////////////////////////////////////////////// /// ERC-721 Non-Fungible Token Standard, optional enumeration extension /// @dev may be added, but not fully supported see ERC-165 below //////////////////////////////////////////////////////////////////////// /// @notice Count NFTs tracked by this contract /// @return A count of valid NFTs tracked by this contract, where each one of /// them has an assigned and queryable owner not equal to the zero address function totalSupply() external view virtual returns (uint256) { return token721.getSupply(); } ///////////////////////////////////////////////// /// ERC721 Metadata, optional metadata extension ///////////////////////////////////////////////// /// @notice A descriptive name for a collection of NFTs in this contract function name() external view virtual override returns (string memory _name) { return token721.getName(); } /// @notice An abbreviated name for NFTs in this contract function symbol() external view virtual override returns (string memory _symbol) { return token721.getSymbol(); } /// @notice A distinct Uniform Resource Identifier (URI) for a given asset. /// @notice Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC /// 3986. The URI may point to a JSON file that conforms to the "ERC721 /// Metadata JSON Schema". function tokenURI( uint256 _tokenId ) external view virtual override returns (string memory) { return token721.getTokenURI(_tokenId); } //////////////////////////////////////// /// ERC-721 Non-Fungible Token Standard //////////////////////////////////////// /// @notice Count all NFTs assigned to an owner /// @notice NFTs assigned to the zero address are considered invalid, and this /// function throws for queries about the zero address. /// @param _owner An address for whom to query the balance /// @return The number of NFTs owned by `_owner`, possibly zero function balanceOf( address _owner ) external view virtual override returns (uint256) { return token721.getBalanceOf(_owner); } /// @notice Find the owner of an NFT /// @notice NFTs assigned to zero address are considered invalid, and queries /// about them do throw. /// @param _tokenId The identifier for an NFT /// @return The address of the owner of the NFT function ownerOf( uint256 _tokenId ) external view virtual override returns (address) { return token721.getOwnerOf(_tokenId); } /// @notice Transfers the ownership of an NFT from one address to another address /// @notice Throws unless `msg.sender` is the current owner, an authorized /// operator, or the approved address for this NFT. Throws if `_from` is /// not the current owner. Throws if `_to` is the zero address. Throws if /// `_tokenId` is not a valid NFT. When transfer is complete, this function /// checks if `_to` is a smart contract (code size > 0). If so, it calls /// `onERC721Received` on `_to` and throws if the return value is not /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer /// @param data Additional data with no specified format, sent in call to `_to` function safeTransferFrom( address _from , address _to , uint256 _tokenId , bytes calldata data ) external virtual override { token721.doTransferFrom(_from, _to, msg.sender, _tokenId); safeHook(_from, _to, _tokenId, data); emit Transfer(_from, _to, _tokenId); } /// @notice Transfers the ownership of an NFT from one address to another address /// @notice This works identically to the other function with an extra data parameter, /// except this function just sets data to "". /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer function safeTransferFrom( address _from , address _to , uint256 _tokenId ) external virtual override { this.safeTransferFrom(_from, _to, _tokenId, ""); } /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE /// THEY MAY BE PERMANENTLY LOST /// @notice Throws unless `msg.sender` is the current owner, an authorized /// operator, or the approved address for this NFT. Throws if `_from` is /// not the current owner. Throws if `_to` is the zero address. Throws if /// `_tokenId` is not a valid NFT. /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer function transferFrom( address _from , address _to , uint256 _tokenId ) external virtual override { token721.doTransferFrom(_from, _to, msg.sender, _tokenId); emit Transfer(_from, _to, _tokenId); } /// @notice Change or reaffirm the approved address for an NFT /// @notice The zero address indicates there is no approved address. /// Throws unless `msg.sender` is the current NFT owner, or an authorized /// operator of the current owner. /// @param _approved The new approved NFT controller /// @param _tokenId The NFT to approve function approve( address _approved , uint256 _tokenId ) external virtual override { token721.setApprove(_approved, msg.sender, _tokenId); emit Approval(msg.sender, _approved, _tokenId); } /// @notice Enable or disable approval for a third party ("operator") to manage /// all of `msg.sender`'s assets /// @notice Emits the ApprovalForAll event. The contract MUST allow /// multiple operators per owner. /// @param _operator Address to add to the set of authorized operators /// @param _approved True if the operator is approved, false to revoke approval function setApprovalForAll( address _operator , bool _approved ) external virtual override { token721.setApprovalForAll(_operator, msg.sender, _approved); emit ApprovalForAll(msg.sender, _operator, _approved); } /// @notice Get the approved address for a single NFT /// @notice Throws if `_tokenId` is not a valid NFT. /// @param _tokenId The NFT to find the approved address for /// @return The approved address for this NFT, or the zero address if there is none function getApproved( uint256 _tokenId ) external view virtual override returns (address) { return token721.getApproved(_tokenId); } /// @notice Query if an address is an authorized operator for another address /// @param _owner The address that owns the NFTs /// @param _operator The address that acts on behalf of the owner /// @return True if `_operator` is an approved operator for `_owner`, false otherwise function isApprovedForAll( address _owner , address _operator ) external view virtual override returns (bool) { return token721.isApprovedForAll(_owner, _operator); } /////////////////////////////////////////////////////////////////// /// ERC-721 Non-Fungible Token Standard, required wallet interface /// @dev This is to disable all safe transfers to this contract /////////////////////////////////////////////////////////////////// /// @notice Handle the receipt of an NFT /// @notice The ERC721 smart contract calls this function on the recipient /// after a `transfer`. This function MAY throw to revert and reject the /// transfer. Return of other than the magic value MUST result in the /// transaction being reverted. /// Note: the contract address is always the message sender. /// @param _operator The address which called `safeTransferFrom` function /// @param _from The address which previously owned the token /// @param _tokenId The NFT identifier which is being transferred /// @param _data Additional data with no specified format /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` /// unless throwing function onERC721Received( address _operator , address _from , uint256 _tokenId , bytes calldata _data ) external virtual override returns(bytes4) { revert Unauthorized(); } /////////////////////////////////// /// EIP-2981: NFT Royalty Standard /////////////////////////////////// /// @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 virtual override returns ( address receiver, uint256 royaltyAmount ) { (receiver, royaltyAmount) = royalties.royaltyInfo(_tokenId,_salePrice); } //////////////////////////////////////////////////// /// EIP-2981: NFT Royalty Standard, admin extension /// @dev Using the collection standard //////////////////////////////////////////////////// /// @dev function (state storage) sets the royalty data for a token /// @param tokenId uint256 for the token /// @param receiver address for the royalty reciever for token /// @param permille uint16 for the permille of royalties 20 -> 2.0% function setRoyalties( uint256 tokenId , address receiver , uint16 permille ) external virtual override { revert Unauthorized(); } /// @dev function (state storage) revokes the royalty data for a token /// @param tokenId uint256 for the token function revokeRoyalties( uint256 tokenId ) external virtual override { revert Unauthorized(); } /// @dev function (state storage) sets the royalty data for a collection /// @param receiver address for the royalty reciever for token /// @param permille uint16 for the permille of royalties 20 -> 2.0% function setRoyalties( address receiver , uint16 permille ) external virtual onlyOwner() override { royalties.setRoyalties(receiver, permille); } /// @dev function (state storage) revokes the royalty data for a collection function revokeRoyalties() external virtual onlyOwner() override { royalties.revokeRoyalties(); } //////////////////////////////////////////////////////////////// /// [Not an EIP] Payment Splitter, interface for ether payments //////////////////////////////////////////////////////////////// /// @dev returns total shares /// @return uint256 of all shares on contract function totalShares() external view virtual override returns (uint256) { return splitter.getTotalShares(); } /// @dev returns shares of an address /// @param payee address of payee to return /// @return mapping(address => uint) of _shares function shares( address payee ) external view virtual override returns (uint256) { return splitter.payeeShares(payee); } /// @dev returns total releases in "eth" /// @return uint256 of all "eth" released in wei function totalReleased() external view virtual override returns (uint256) { return splitter.getTotalReleased(); } /// @dev returns released "eth" of an payee /// @param payee address of payee to look up /// @return mapping(address => uint) of _released function released( address payee ) external view virtual override returns (uint256) { return splitter.payeeReleased(payee); } /// @dev returns amount of "eth" that can be released to payee /// @param payee address of payee to look up /// @return uint in wei of "eth" to release function releasable( address payee ) external view virtual override returns (uint256) { uint totalReceived = address(this).balance + this.totalReleased(); return totalReceived * this.shares(payee) / this.totalShares() - this.released(payee); } /// @dev returns index number of payee /// @param payee number of index /// @return address at _payees[index] function payeeIndex( address payee ) external view virtual override returns (uint256) { return splitter.payeeIndex(payee); } /// @dev this returns the array of payees[] /// @return address[] payees function payees() external view virtual override returns (address[] memory) { return splitter.getPayees(); } /// @dev this claims all "eth" on contract for msg.sender function claim() external virtual override { if (this.shares(msg.sender) == 0) { revert Unauthorized(); } uint256 payment = this.releasable(msg.sender); if (payment == 0) { revert Unauthorized(); } splitter.processPayment(msg.sender, payment); Address.sendValue(payable(msg.sender), payment); } /// @dev This pays all payees function payClaims() external virtual override { address[] memory toPay = splitter.getPayees(); uint256 len = toPay.length; for (uint x = 0 ; x < len ;) { uint256 payment = this.releasable(toPay[x]); splitter.processPayment(toPay[x], payment); Address.sendValue(payable(toPay[x]), payment); unchecked { ++x; } } } /// @dev This adds a payee /// @param payee Address of payee /// @param _shares Shares to send user function addPayee( address payee , uint256 _shares ) external virtual onlyDev() override { splitter.addPayee(payee, _shares); } /// @dev This removes a payee /// @param payee Address of payee to remove /// @notice use payPayees() prior to use if anything is on the contract function removePayee( address payee ) external virtual onlyDev() override { splitter.removePayee(payee); } /// @dev This removes all payees /// @notice use payPayees() prior to use if anything is on the contract function clearPayees() external virtual onlyDev() override { splitter.clearPayees(); } ////////////////////////////////////////// /// EIP-165: Standard Interface Detection ////////////////////////////////////////// /// @dev Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view virtual override returns (bool) { return ( interfaceID == type(IERC173).interfaceId || interfaceID == type(IERC721).interfaceId || interfaceID == type(IERC2981).interfaceId || interfaceID == type(IERC721Metadata).interfaceId ); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates merkle trees that are safe * against this attack out of the box. */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify( bytes32[] memory proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} * * _Available since v4.7._ */ function verifyCalldata( bytes32[] calldata proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} * * _Available since v4.7._ */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). * * _Available since v4.7._ */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol) pragma solidity ^0.8.0; /** * @dev Provides a set of functions to operate with Base64 strings. * * _Available since v4.5._ */ library Base64 { /** * @dev Base64 Encoding/Decoding Table */ string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** * @dev Converts a `bytes` to its Bytes64 `string` representation. */ function encode(bytes memory data) internal pure returns (string memory) { /** * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol */ if (data.length == 0) return ""; // Loads the table into memory string memory table = _TABLE; // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter // and split into 4 numbers of 6 bits. // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up // - `data.length + 2` -> Round up // - `/ 3` -> Number of 3-bytes chunks // - `4 *` -> 4 characters for each chunk string memory result = new string(4 * ((data.length + 2) / 3)); /// @solidity memory-safe-assembly assembly { // Prepare the lookup table (skip the first "length" byte) let tablePtr := add(table, 1) // Prepare result pointer, jump over length let resultPtr := add(result, 32) // Run over the input, 3 bytes at a time for { let dataPtr := data let endPtr := add(data, mload(data)) } lt(dataPtr, endPtr) { } { // Advance 3 bytes dataPtr := add(dataPtr, 3) let input := mload(dataPtr) // To write each character, shift the 3 bytes (18 bits) chunk // 4 times in blocks of 6 bits for each character (18, 12, 6, 0) // and apply logical AND with 0x3F which is the number of // the previous character in the ASCII table prior to the Base64 Table // The result is then added to the table to get the character to write, // and finally write it in the result pointer but with a left shift // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F)))) resultPtr := add(resultPtr, 1) // Advance } // When data `bytes` is not exactly 3 bytes long // it is padded with `=` characters at the end switch mod(mload(data), 3) case 1 { mstore8(sub(resultPtr, 1), 0x3d) mstore8(sub(resultPtr, 2), 0x3d) } case 2 { mstore8(sub(resultPtr, 1), 0x3d) } } return result; } }
{ "remappings": [], "optimizer": { "enabled": true, "runs": 1000 }, "evmVersion": "london", "libraries": {}, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_dev","type":"address"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_start","type":"uint256"}],"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":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"what","type":"string"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_payee","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"PaymentReceived","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"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"acceptDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"payee","type":"address"},{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"addPayee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"adminMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_approved","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":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"clearPayees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"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":[{"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":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"homiesMint","outputs":[],"stateMutability":"nonpayable","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":"uint256","name":"index","type":"uint256"}],"name":"isClaimedAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"isClaimedHomies","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"isClaimedNormies","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"_name","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"normiesCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"normiesMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"payClaims","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"payee","type":"address"}],"name":"payeeIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"payees","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quant","type":"uint256"}],"name":"publicMint","outputs":[],"stateMutability":"payable","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":"payee","type":"address"}],"name":"releasable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"payee","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"payee","type":"address"}],"name":"removePayee","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":"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"}],"name":"revokeRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revokeRoyalties","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":"uint256","name":"_amount","type":"uint256"}],"name":"setCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newURI","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_normies","type":"uint256"},{"internalType":"uint256","name":"_public","type":"uint256"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_description","type":"string"},{"internalType":"string","name":"_image","type":"string"},{"internalType":"string","name":"_animation","type":"string"}],"name":"setJSON","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_admin","type":"bytes32"},{"internalType":"bytes32","name":"_homies","type":"bytes32"},{"internalType":"bytes32","name":"_normies","type":"bytes32"}],"name":"setMerks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint16","name":"permille","type":"uint16"}],"name":"setRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint16","name":"permille","type":"uint16"}],"name":"setRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_period","type":"uint256"}],"name":"setTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"payee","type":"address"}],"name":"shares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"showTimes","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"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":"_symbol","type":"string"}],"stateMutability":"view","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"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405266f5232269808000601f5567016345785d8a00006020553480156200002857600080fd5b5060405162005171380380620051718339810160408190526200004b9162000612565b6200005a868686868662000081565b620000758160216200017260201b620026031790919060201c565b5050505050506200084c565b6200009c856000620001ad60201b6200263e1790919060201c565b620000b7846000620001ef60201b6200267c1790919060201c565b620000d860086303e1469160e61b8562000231602090811b620026ba17901c565b620000f38360086200030160201b6200278a1790919060201c565b62000114600863ca4b208b60e01b8462000231602090811b620026ba17901c565b6200012f826008620003ec60201b620028591790919060201c565b620001506008638da5cb5b60e01b8362000231602090811b620026ba17901c565b6200016b8160086200045b60201b620028c51790919060201c565b5050505050565b8082556040518181527f83b179bd5cb3a111f82ac98510d3c66f48f77679e657302f4f253d4c32d6d672906020015b60405180910390a15050565b60048201620001bd82826200074b565b507f13c98778b0c1a086bb98d7f1986e15788b5d3a1ad4c492e1d78f1c4cc51c20cf81604051620001a1919062000817565b60058201620001ff82826200074b565b507f3e46ff90086ee29856e77591e82c82ff8ed513379b0fd82e84fc5290dd633c9981604051620001a1919062000817565b6001600160a01b03811662000258576040516282b42960e81b815260040160405180910390fd5b62000265838383620004ca565b1562000283576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0381166000818152602085815260408083206001600160e01b03198716808552908352928190208054600160ff1990911681179091558151938452918301939093528183015290517fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f79181900360600190a1505050565b62000315826303e1469160e61b83620004ca565b1562000370576003820180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a3505050565b6001600160a01b038116620003d4576003820180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a3505050565b6040516282b42960e81b815260040160405180910390fd5b620004008263ca4b208b60e01b83620004ca565b1562000370576002820180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f2cfca82ac51c2fc6b6db547820d28d526a505e12d230afb8bf112a5aeefa9a4c90600090a3505050565b6200046f82638da5cb5b60e01b83620004ca565b1562000370576001820180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60006001600160a01b038216620004f3576040516282b42960e81b815260040160405180910390fd5b506001600160a01b03166000908152602092835260408082206001600160e01b03199390931682529190925290205460ff1690565b634e487b7160e01b600052604160045260246000fd5b60005b838110156200055b57818101518382015260200162000541565b50506000910152565b600082601f8301126200057657600080fd5b81516001600160401b038082111562000593576200059362000528565b604051601f8301601f19908116603f01168101908282118183101715620005be57620005be62000528565b81604052838152866020858801011115620005d857600080fd5b620005eb8460208301602089016200053e565b9695505050505050565b80516001600160a01b03811681146200060d57600080fd5b919050565b60008060008060008060c087890312156200062c57600080fd5b86516001600160401b03808211156200064457600080fd5b620006528a838b0162000564565b975060208901519150808211156200066957600080fd5b506200067889828a0162000564565b9550506200068960408801620005f5565b93506200069960608801620005f5565b9250620006a960808801620005f5565b915060a087015190509295509295509295565b600181811c90821680620006d157607f821691505b602082108103620006f257634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200074657600081815260208120601f850160051c81016020861015620007215750805b601f850160051c820191505b8181101562000742578281556001016200072d565b5050505b505050565b81516001600160401b0381111562000767576200076762000528565b6200077f81620007788454620006bc565b84620006f8565b602080601f831160018114620007b757600084156200079e5750858301515b600019600386901b1c1916600185901b17855562000742565b600085815260208120601f198616915b82811015620007e857888601518255948401946001909101908401620007c7565b5085821015620008075787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020815260008251806020840152620008388160408501602087016200053e565b601f01601f19169190910160400192915050565b614915806200085c6000396000f3fe6080604052600436106104185760003560e01c806376d7fc0711610228578063b88d4fde11610128578063dcd4ab77116100bb578063e8a3d4851161008a578063ec1ffdd81161006f578063ec1ffdd814610c1a578063f2fde38b14610c44578063f950233314610c6457610455565b8063e8a3d48514610be5578063e985e9c514610bfa57610455565b8063dcd4ab7714610b7b578063de02cde714610b90578063e33b7de314610bb0578063e7b7544014610bc557610455565b8063ca4b208b116100f7578063ca4b208b14610b0a578063ce7c2ac214610b28578063d39ce77c14610b48578063d601f1dc14610b6857610455565b8063b88d4fde14610a8a578063bb5027f714610aaa578063c3b8e34514610aca578063c87b56dd14610aea57610455565b806396d32915116101bb578063a22cb4651161018a578063a6b6cb371161016f578063a6b6cb3714610a4a578063a86ff96014610a60578063ad6d9c1714610a7557610455565b8063a22cb46514610a0a578063a3f8eace14610a2a57610455565b806396d329151461098f5780639852595c146109af5780639bce3944146109cf578063a0355eca146109ea57610455565b80638bb2b65a116101f75780638bb2b65a1461091c5780638da5cb5b1461093c578063938e3d7b1461095a57806395d89b411461097a57610455565b806376d7fc07146108bc57806379ba5097146108d15780638159324c146108e65780638693da201461090657610455565b80632db11544116103335780634e8086aa116102c65780636352211e1161029557806366278a6c1161027a57806366278a6c1461086757806370a0823114610887578063715018a6146108a757610455565b80636352211e1461082757806364cb4edb1461084757610455565b80634e8086aa1461079e57806350d604e3146107c05780635ba5e9f0146107e05780636149d8711461080757610455565b806342842e0e1161030257806342842e0e1461072957806344faded01461074957806347786d37146107695780634e71d92d1461078957610455565b80632db11544146106cc57806331e26cfd146106df5780633a98ef39146106f45780633ed358551461070957610455565b8063150b7a02116103ab57806323b872dd1161037a57806323b872dd14610643578063266dcbf6146106635780632a55205a146106785780632bfcf0f2146106b757610455565b8063150b7a02146105b557806318160ddd146105ee57806318f9b023146106035780631fcb02f31461062357610455565b80630b78f9c0116103e75780630b78f9c0146105385780630c222ee51461055857806310ab94321461057857806312065fe01461059857610455565b806301ffc9a71461048757806306fdde03146104bc578063081812fc146104de578063095ea7b31461051657610455565b366104555760405134815233907f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be770906020015b60405180910390a2005b60405134815233907f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be7709060200161044b565b34801561049357600080fd5b506104a76104a2366004613df4565b610c84565b60405190151581526020015b60405180910390f35b3480156104c857600080fd5b506104d1610d55565b6040516104b39190613e61565b3480156104ea57600080fd5b506104fe6104f9366004613e74565b610d66565b6040516001600160a01b0390911681526020016104b3565b34801561052257600080fd5b50610536610531366004613ea9565b610d72565b005b34801561054457600080fd5b50610536610553366004613ed3565b610dbb565b34801561056457600080fd5b50610536610573366004613f07565b610df6565b34801561058457600080fd5b506104a7610593366004613f3a565b610e1e565b3480156105a457600080fd5b50475b6040519081526020016104b3565b3480156105c157600080fd5b506105d56105d0366004613f66565b610e33565b6040516001600160e01b031990911681526020016104b3565b3480156105fa57600080fd5b506105a7610e4d565b34801561060f57600080fd5b5061053661061e366004613ea9565b610e59565b34801561062f57600080fd5b5061053661063e366004614001565b610dde565b34801561064f57600080fd5b5061053661065e36600461403d565b610e7d565b34801561066f57600080fd5b50610536610ed1565b34801561068457600080fd5b50610698610693366004613ed3565b610fe6565b604080516001600160a01b0390931683526020830191909152016104b3565b3480156106c357600080fd5b50610536611000565b6105366106da366004613e74565b611066565b3480156106eb57600080fd5b506105366111be565b34801561070057600080fd5b506105a7611203565b34801561071557600080fd5b50610536610724366004614079565b61120e565b34801561073557600080fd5b5061053661074436600461403d565b611231565b34801561075557600080fd5b50610536610764366004613f3a565b6112c5565b34801561077557600080fd5b50610536610784366004613e74565b61134c565b34801561079557600080fd5b50610536611369565b3480156107aa57600080fd5b506107b361149a565b6040516104b39190614094565b3480156107cc57600080fd5b506104a76107db366004613e74565b6114a6565b3480156107ec57600080fd5b506105d56107fb366004613df4565b506303e1469160e61b90565b34801561081357600080fd5b50610536610822366004614079565b6114e7565b34801561083357600080fd5b506104fe610842366004613e74565b61152c565b34801561085357600080fd5b50610536610862366004614079565b611549565b34801561087357600080fd5b50610536610882366004613df4565b6115ac565b34801561089357600080fd5b506105a76108a2366004614079565b6115e3565b3480156108b357600080fd5b50610536611601565b3480156108c857600080fd5b50610536611652565b3480156108dd57600080fd5b50610536611676565b3480156108f257600080fd5b5061053661090136600461412d565b6116d9565b34801561091257600080fd5b506105a760205481565b34801561092857600080fd5b50610536610937366004614238565b61195f565b34801561094857600080fd5b506009546001600160a01b03166104fe565b34801561096657600080fd5b506105366109753660046142c0565b6119a3565b34801561098657600080fd5b506104d16119c7565b34801561099b57600080fd5b506104a76109aa366004613e74565b6119d3565b3480156109bb57600080fd5b506105a76109ca366004614079565b611a14565b3480156109db57600080fd5b5061053661063e366004613e74565b3480156109f657600080fd5b50610536610a05366004613ed3565b611a32565b348015610a1657600080fd5b50610536610a253660046142f5565b611a55565b348015610a3657600080fd5b506105a7610a45366004614079565b611aa8565b348015610a5657600080fd5b506105a7601f5481565b348015610a6c57600080fd5b50610536611c83565b348015610a8157600080fd5b50610536611cc8565b348015610a9657600080fd5b50610536610aa5366004613f66565b611d19565b348015610ab657600080fd5b50610536610ac5366004614331565b611db2565b348015610ad657600080fd5b506104a7610ae5366004613e74565b612024565b348015610af657600080fd5b506104d1610b05366004613e74565b612065565b348015610b1657600080fd5b50600a546001600160a01b03166104fe565b348015610b3457600080fd5b506105a7610b43366004614079565b6120cc565b348015610b5457600080fd5b50610536610b63366004614079565b6120ea565b610536610b76366004614331565b61212f565b348015610b8757600080fd5b506105366123e8565b348015610b9c57600080fd5b50610536610bab366004613f3a565b61240a565b348015610bbc57600080fd5b50600e546105a7565b348015610bd157600080fd5b506105a7610be0366004614079565b61248d565b348015610bf157600080fd5b506104d161249a565b348015610c0657600080fd5b506104a7610c1536600461438b565b61252c565b348015610c2657600080fd5b50610c2f61255c565b604080519283526020830191909152016104b3565b348015610c5057600080fd5b50610536610c5f366004614079565b61257a565b348015610c7057600080fd5b50610536610c7f3660046143a7565b6125dd565b60006001600160e01b031982167f7f5828d0000000000000000000000000000000000000000000000000000000001480610ce757506001600160e01b031982167f80ac58cd00000000000000000000000000000000000000000000000000000000145b80610d1b57506001600160e01b031982167f2a55205a00000000000000000000000000000000000000000000000000000000145b80610d4f57506001600160e01b031982167f5b5e139f00000000000000000000000000000000000000000000000000000000145b92915050565b6060610d616000612931565b905090565b6000610d4f81836129c7565b610d7f6000833384612a4c565b60405181906001600160a01b0384169033907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590600090a45050565b610dce600863ca4b208b60e01b33612b45565b15610dde57601f91909155602055565b6040516282b42960e81b815260040160405180910390fd5b610e096008638da5cb5b60e01b33612b45565b15610dde57610e1a600c8383612ba2565b5050565b6000610e2c60088484612b45565b9392505050565b60006040516282b42960e81b815260040160405180910390fd5b6000610d616000612c83565b610e6c600863ca4b208b60e01b33612b45565b15610dde57610e1a600d8383612c90565b610e8b600084843385612e27565b80826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000610edd600d612fe4565b805190915060005b81811015610fe1576000306001600160a01b031663a3f8eace858481518110610f1057610f106143d3565b60200260200101516040518263ffffffff1660e01b8152600401610f4391906001600160a01b0391909116815260200190565b602060405180830381865afa158015610f60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8491906143e9565b9050610fb5848381518110610f9b57610f9b6143d3565b602002602001015182600d6130499092919063ffffffff16565b610fd8848381518110610fca57610fca6143d3565b6020026020010151826130d0565b50600101610ee5565b505050565b600080610ff5600c85856131e9565b909590945092505050565b636525904560e11b61101460088233612b45565b8061102d575061102d60086303e1469160e61b33612b45565b15610dde57611045600863ca4b208b60e01b336126ba565b611050600833612859565b6110636008636525904560e11b33613226565b50565b6013546012546110769190614418565b4210610dde57600581111561109d576040516282b42960e81b815260040160405180910390fd5b6012546000036110bf576040516282b42960e81b815260040160405180910390fd5b806020546110cd919061442b565b341461112157604051630330dbc960e11b815260206004820152601160248201527f6d73672e76616c756520746f6f206c6f7700000000000000000000000000000060448201526064015b60405180910390fd5b6014548161112f6000612c83565b6111399190614418565b1115611157576040516282b42960e81b815260040160405180910390fd5b60005b81811015610e1a576111783361116f60215490565b600091906132e2565b60215460405133906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46111b6602180546001019055565b60010161115a565b636525904560e11b6111d260088233612b45565b806111eb57506111eb60086303e1469160e61b33612b45565b15610dde576110636008636525904560e11b33613226565b6000610d61600d5490565b611221600863ca4b208b60e01b33612b45565b15610dde57611063600d82613407565b6040517fb88d4fde0000000000000000000000000000000000000000000000000000000081526001600160a01b03808516600483015283166024820152604481018290526080606482015260006084820152309063b88d4fde9060a401600060405180830381600087803b1580156112a857600080fd5b505af11580156112bc573d6000803e3d6000fd5b50505050505050565b816112d260088233612b45565b806112eb57506112eb60086303e1469160e61b33612b45565b15610dde576001600160e01b03198316636525904560e11b148061131f57506001600160e01b031983166346d2e5ad60e11b145b1561134057336001600160a01b03831603610dde57610fe160088484613226565b610fe160088484613226565b61135f600863ca4b208b60e01b33612b45565b15610dde57601455565b60405163673e156160e11b8152336004820152309063ce7c2ac290602401602060405180830381865afa1580156113a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c891906143e9565b6000036113e7576040516282b42960e81b815260040160405180910390fd5b6040517fa3f8eace000000000000000000000000000000000000000000000000000000008152336004820152600090309063a3f8eace90602401602060405180830381865afa15801561143e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061146291906143e9565b905080600003611484576040516282b42960e81b815260040160405180910390fd5b611490600d3383613049565b61106333826130d0565b6060610d61600d612fe4565b6000806114b561010084614458565b905060006114c56101008561446c565b60009283526016602052604090922054600190921b9182169091149392505050565b63ca4b208b60e01b6114fb60088233612b45565b80611514575061151460086303e1469160e61b33612b45565b15610dde57610e1a6008636525904560e11b846126ba565b6000818152602081905260408120546001600160a01b0316610d4f565b63ca4b208b60e01b61155d60088233612b45565b80611576575061157660086303e1469160e61b33612b45565b15610dde5761158e600863ca4b208b60e01b846126ba565b611599600883612859565b610e1a600863ca4b208b60e01b33613226565b806115b960088233612b45565b806115d257506115d260086303e1469160e61b33612b45565b15610dde57610e1a60088333613226565b6001600160a01b038116600090815260016020526040812054610d4f565b638da5cb5b60e01b61161560088233612b45565b8061162e575061162e60086303e1469160e61b33612b45565b15610dde5761163f600860006128c5565b6110636008638da5cb5b60e01b33613226565b611665600863ca4b208b60e01b33612b45565b15610dde57611674600d613587565b565b6346d2e5ad60e11b61168a60088233612b45565b806116a357506116a360086303e1469160e61b33612b45565b15610dde576116bb6008638da5cb5b60e01b336126ba565b6116c66008336128c5565b61106360086346d2e5ad60e11b33613226565b6013546012546116e99190614418565b421080156116f957506012544210155b15610dde57601254600003611720576040516282b42960e81b815260040160405180910390fd5b611729856114a6565b1561176957604051630330dbc960e11b815260206004820152600f60248201526e105b1c9958591e4810db185a5b5959608a1b6044820152606401611118565b60408051602081018790526bffffffffffffffffffffffff19606087901b1691810191909152605481018490526000906074016040516020818303038152906040528051906020012090506117f583838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050601554915084905061361c565b61183257604051630330dbc960e11b815260206004820152600d60248201526c24b73b30b634b210283937b7b360991b6044820152606401611118565b61183b86613632565b601454846118496000612c83565b6118539190614418565b1115611871576040516282b42960e81b815260040160405180910390fd5b60005b848110156118d8576118898661116f60215490565b6021546040516001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46118d0602180546001019055565b600101611874565b50604080518781526001600160a01b03871660208201529081018590526080606082018190526005908201527f41646d696e00000000000000000000000000000000000000000000000000000060a08201527fee563d8e532abc293fca2fdeb41c25180305bddcf9206c167dab3e155aaf17139060c00160405180910390a1505050505050565b611972600863ca4b208b60e01b33612b45565b15610dde57601d6119838482614508565b50601c6119908382614508565b50601e61199d8282614508565b50505050565b6119b6600863ca4b208b60e01b33612b45565b15610dde57601b610e1a8282614508565b6060610d616000613670565b6000806119e261010084614458565b905060006119f26101008561446c565b6000928352601a602052604090922054600190921b9182169091149392505050565b6001600160a01b038116600090815260106020526040812054610d4f565b611a45600863ca4b208b60e01b33612b45565b15610dde57601291909155601355565b611a626000833384613681565b60405181151581526001600160a01b0383169033907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319060200160405180910390a35050565b600080306001600160a01b031663e33b7de36040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ae9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b0d91906143e9565b611b179047614418565b6040517f9852595c0000000000000000000000000000000000000000000000000000000081526001600160a01b03851660048201529091503090639852595c90602401602060405180830381865afa158015611b77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b9b91906143e9565b306001600160a01b0316633a98ef396040518163ffffffff1660e01b8152600401602060405180830381865afa158015611bd9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bfd91906143e9565b60405163673e156160e11b81526001600160a01b0386166004820152309063ce7c2ac290602401602060405180830381865afa158015611c41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c6591906143e9565b611c6f908461442b565b611c799190614458565b610e2c91906145c8565b6346d2e5ad60e11b611c9760088233612b45565b80611cb05750611cb060086303e1469160e61b33612b45565b15610dde5761106360086346d2e5ad60e11b33613226565b63ca4b208b60e01b611cdc60088233612b45565b80611cf55750611cf560086303e1469160e61b33612b45565b15610dde57611d0660086000612859565b611063600863ca4b208b60e01b33613226565b611d27600086863387612e27565b611d6985858585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061372192505050565b5082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050505050565b601354601254611dc29190614418565b42108015611dd257506012544210155b15610dde57601254600003611df9576040516282b42960e81b815260040160405180910390fd5b611e0284612024565b15611e4257604051630330dbc960e11b815260206004820152600f60248201526e105b1c9958591e4810db185a5b5959608a1b6044820152606401611118565b60008484604051602001611e7292919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b604051602081830303815290604052805190602001209050611ecb83838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050601754915084905061361c565b611f0857604051630330dbc960e11b815260206004820152600d60248201526c24b73b30b634b210283937b7b360991b6044820152606401611118565b611f1185613823565b601454611f1e6000612c83565b611f29906001614418565b1115611f47576040516282b42960e81b815260040160405180910390fd5b611f548461116f60215490565b6021546040516001600160a01b038616906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4611f9b602180546001019055565b604080518681526001600160a01b03861660208201526001918101919091526080606082018190526006908201527f486f6d696573000000000000000000000000000000000000000000000000000060a08201527fee563d8e532abc293fca2fdeb41c25180305bddcf9206c167dab3e155aaf17139060c0015b60405180910390a15050505050565b60008061203361010084614458565b905060006120436101008561446c565b60009283526018602052604090922054600190921b9182169091149392505050565b6060600061207283613861565b601d601c601e60405160200161208b949392919061464e565b60405160208183030381529060405290506120a581613996565b6040516020016120b591906147d2565b604051602081830303815290604052915050919050565b6001600160a01b0381166000908152600f6020526040812054610d4f565b638da5cb5b60e01b6120fe60088233612b45565b80612117575061211760086303e1469160e61b33612b45565b15610dde57610e1a60086346d2e5ad60e11b846126ba565b60135460125461213f9190614418565b4210801561214f57506012544210155b15610dde57601254600003612176576040516282b42960e81b815260040160405180910390fd5b601f5434146121c857604051630330dbc960e11b815260206004820152601160248201527f6d73672e76616c756520746f6f206c6f770000000000000000000000000000006044820152606401611118565b6121d1846119d3565b1561221157604051630330dbc960e11b815260206004820152600f60248201526e105b1c9958591e4810db185a5b5959608a1b6044820152606401611118565b6000848460405160200161224192919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b60405160208183030381529060405280519060200120905061229a83838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050601954915084905061361c565b6122d757604051630330dbc960e11b815260206004820152600d60248201526c24b73b30b634b210283937b7b360991b6044820152606401611118565b6122e085613ae9565b6014546122ed6000612c83565b6122f8906001614418565b1115612316576040516282b42960e81b815260040160405180910390fd5b6123238461116f60215490565b6021546040516001600160a01b038616906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a461236a602180546001019055565b604080518681526001600160a01b03861660208201526001918101919091526080606082018190526007908201527f4e6f726d6965730000000000000000000000000000000000000000000000000060a08201527fee563d8e532abc293fca2fdeb41c25180305bddcf9206c167dab3e155aaf17139060c001612015565b6123fb6008638da5cb5b60e01b33612b45565b15610dde57611674600c613b27565b8161241760088233612b45565b80612430575061243060086303e1469160e61b33612b45565b15610dde576001600160e01b03198316636525904560e11b148061246457506001600160e01b031983166346d2e5ad60e11b145b15612481576040516282b42960e81b815260040160405180910390fd5b610fe1600884846126ba565b6000610d4f600d83613b8c565b6060601b80546124a990614480565b80601f01602080910402602001604051908101604052809291908181526020018280546124d590614480565b80156125225780601f106124f757610100808354040283529160200191612522565b820191906000526020600020905b81548152906001019060200180831161250557829003601f168201915b5050505050905090565b6001600160a01b03808316600090815260036020908152604080832093851683529290529081205460ff16610e2c565b6000806012546013546012546125729190614418565b915091509091565b638da5cb5b60e01b61258e60088233612b45565b806125a757506125a760086303e1469160e61b33612b45565b15610dde576125bf6008638da5cb5b60e01b846126ba565b6125ca6008836128c5565b610e1a6008638da5cb5b60e01b33613226565b6125f0600863ca4b208b60e01b33612b45565b15610dde57601592909255601755601955565b8082556040518181527f83b179bd5cb3a111f82ac98510d3c66f48f77679e657302f4f253d4c32d6d672906020015b60405180910390a15050565b6004820161264c8282614508565b507f13c98778b0c1a086bb98d7f1986e15788b5d3a1ad4c492e1d78f1c4cc51c20cf816040516126329190613e61565b6005820161268a8282614508565b507f3e46ff90086ee29856e77591e82c82ff8ed513379b0fd82e84fc5290dd633c99816040516126329190613e61565b6001600160a01b0381166126e0576040516282b42960e81b815260040160405180910390fd5b6126eb838383612b45565b15612708576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0381166000818152602085815260408083206001600160e01b0319871680855290835292819020805460ff19166001908117909155815193845291830193909352918101919091527fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f7906060015b60405180910390a1505050565b61279c826303e1469160e61b83612b45565b156127f6576003820180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a3505050565b6001600160a01b038116610dde576003820180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a3505050565b61286b8263ca4b208b60e01b83612b45565b156127f6576002820180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f2cfca82ac51c2fc6b6db547820d28d526a505e12d230afb8bf112a5aeefa9a4c90600090a3505050565b6128d782638da5cb5b60e01b83612b45565b156127f6576001820180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b606081600401805461294290614480565b80601f016020809104026020016040519081016040528092919081815260200182805461296e90614480565b80156129bb5780601f10612990576101008083540402835291602001916129bb565b820191906000526020600020905b81548152906001019060200180831161299e57829003601f168201915b50505050509050919050565b6000818152602083905260408120546001600160a01b0316612a2c57604051630330dbc960e11b815260206004820152600360248201527f4c3a3100000000000000000000000000000000000000000000000000000000006044820152606401611118565b50600090815260029190910160205260409020546001600160a01b031690565b6000818152602085905260409020546001600160a01b03908116908416819003612ab957604051630330dbc960e11b815260206004820152600360248201527f4c3a3200000000000000000000000000000000000000000000000000000000006044820152606401611118565b612ac4858484613c55565b612b1157604051630330dbc960e11b815260206004820152600360248201527f4c3a3300000000000000000000000000000000000000000000000000000000006044820152606401611118565b50600090815260029390930160205250604090912080546001600160a01b0319166001600160a01b03909216919091179055565b60006001600160a01b038216612b6d576040516282b42960e81b815260040160405180910390fd5b506001600160a01b03166000908152602092835260408082206001600160e01b03199390931682529190925290205460ff1690565b6103e88161ffff16101580612bb9575061ffff8116155b15612c0757604051630330dbc960e11b815260206004820152600360248201527f523a3100000000000000000000000000000000000000000000000000000000006044820152606401611118565b82546001600160a01b0383811675ffffffffffffffffffffffffffffffffffffffffffff1990921691909117600160a01b61ffff84811682029290921780875560408051948216855291900490911660208301527f712ca2ffb17da9e3b90d98d54938dee8be84b528cbdec691d680c1df8b78538a910161277d565b6000610d4f826007015490565b6001600160a01b038216612cd057604051630330dbc960e11b81526004016111189060208082526004908201526350533a3360e01b604082015260600190565b80600003612d2357604051630330dbc960e11b81526004016111189060208082526004908201527f50533a3400000000000000000000000000000000000000000000000000000000604082015260600190565b6001600160a01b038216600090815260028401602052604090205415612d8e57604051630330dbc960e11b81526004016111189060208082526004908201527f50533a3500000000000000000000000000000000000000000000000000000000604082015260600190565b6004830180546001810182556000918252602080832090910180546001600160a01b0319166001600160a01b038616908117909155825260028501905260408120829055835482918591612de3908490614418565b9091555050604080516001600160a01b0384168152602081018390527f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac910161277d565b612e32858383613c55565b612e7f57604051630330dbc960e11b815260206004820152600360248201527f4c3a3500000000000000000000000000000000000000000000000000000000006044820152606401611118565b6000818152602086905260409020546001600160a01b039081169085168114612eeb57604051630330dbc960e11b815260206004820152600360248201527f4c3a3600000000000000000000000000000000000000000000000000000000006044820152606401611118565b6001600160a01b038416612f4257604051630330dbc960e11b815260206004820152600360248201527f4c3a3700000000000000000000000000000000000000000000000000000000006044820152606401611118565b612f4f8660008585612a4c565b6001600160a01b0385166000908152600187810160205260408220805491929091612f7b9084906145c8565b90915550506001600160a01b0384166000908152600187810160205260408220805491929091612fac908490614418565b909155505050600090815260209490945250604090922080546001600160a01b0319166001600160a01b039093169290921790915550565b6060816004018054806020026020016040519081016040528092919081815260200182805480156129bb57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116130205750505050509050919050565b8083600101600082825461305d9190614418565b90915550506001600160a01b03821660009081526003840160205260408120805483929061308c908490614418565b9091555050604080516001600160a01b0384168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910161277d565b804710156131205760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401611118565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461316d576040519150601f19603f3d011682016040523d82523d6000602084013e613172565b606091505b5050905080610fe15760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401611118565b82546001600160a01b038116906000906103e89061321290600160a01b900461ffff168561442b565b61321c9190614458565b9050935093915050565b6001600160a01b03811661324c576040516282b42960e81b815260040160405180910390fd5b613257838383612b45565b613273576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0381166000818152602085815260408083206001600160e01b03198716808552908352818420805460ff19169055815190815291820193909352918201527fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f79060600161277d565b6001600160a01b03821661333957604051630330dbc960e11b815260206004820152600360248201527f4c3a3800000000000000000000000000000000000000000000000000000000006044820152606401611118565b6000818152602084905260409020546001600160a01b03161561339f57604051630330dbc960e11b815260206004820152600360248201527f4c3a3900000000000000000000000000000000000000000000000000000000006044820152606401611118565b6001600160a01b03821660009081526001848101602052604082208054919290916133cb908490614418565b9091555050600081815260208490526040902080546001600160a01b0319166001600160a01b0384161790556007830180546001019055505050565b6001600160a01b03811661344757604051630330dbc960e11b81526004016111189060208082526004908201526350533a3360e01b604082015260600190565b60006134538383613b8c565b60048401805491925060009161346b906001906145c8565b8154811061347b5761347b6143d3565b6000918252602090912001546004850180546001600160a01b0390921692508291849081106134ac576134ac6143d3565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550836004018054806134ed576134ed614817565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0385168252600286019052604081208054908290558554909182918791906135439084906145c8565b9091555050604080516001600160a01b0386168152602081018390527f104b8837ec12e86f303ac7ce5e3bf20c6790f843fabd7451943f3390fc8376cb9101612015565b600481015460005b818110156135db5760008360040182815481106135ae576135ae6143d3565b60009182526020808320909101546001600160a01b0316825260028601905260408120555060010161358f565b5060008083556135ef906004840190613dac565b6040517f3407fd525bf6581e0ae8e3a3636bd90d02112bea34d66802743c28ced73f910e90600090a15050565b6000826136298584613cd4565b14949350505050565b600061364061010083614458565b905060006136506101008461446c565b6000928352601660205260409092208054600190931b9092179091555050565b606081600501805461294290614480565b826001600160a01b0316826001600160a01b0316036136e357604051630330dbc960e11b815260206004820152600360248201527f4c3a3400000000000000000000000000000000000000000000000000000000006044820152606401611118565b6001600160a01b0391821660009081526003949094016020908152604080862094909316855292909252909120805460ff1916911515919091179055565b60006001600160a01b0384163b1561381757604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061376590339089908890889060040161482d565b6020604051808303816000875af19250505080156137a0575060408051601f3d908101601f1916820190925261379d91810190614869565b60015b6137fd573d8080156137ce576040519150601f19603f3d011682016040523d82523d6000602084013e6137d3565b606091505b5080516000036137f5576040516282b42960e81b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061381b565b5060015b949350505050565b600061383161010083614458565b905060006138416101008461446c565b6000928352601860205260409092208054600190931b9092179091555050565b6060816000036138a457505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156138ce57806138b881614886565b91506138c79050600a83614458565b91506138a8565b60008167ffffffffffffffff8111156138e9576138e9614195565b6040519080825280601f01601f191660200182016040528015613913576020820181803683370190505b5090505b841561381b576139286001836145c8565b9150613935600a8661446c565b613940906030614418565b60f81b818381518110613955576139556143d3565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061398f600a86614458565b9450613917565b606081516000036139b557505060408051602081019091526000815290565b60006040518060600160405280604081526020016148a060409139905060006003845160026139e49190614418565b6139ee9190614458565b6139f990600461442b565b67ffffffffffffffff811115613a1157613a11614195565b6040519080825280601f01601f191660200182016040528015613a3b576020820181803683370190505b509050600182016020820185865187015b80821015613aa7576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250613a4c565b5050600386510660018114613ac35760028114613ad657613ade565b603d6001830353603d6002830353613ade565b603d60018303535b509195945050505050565b6000613af761010083614458565b90506000613b076101008461446c565b6000928352601a60205260409092208054600190931b9092179091555050565b805475ffffffffffffffffffffffffffffffffffffffffffff19168082556040805160008152600160a01b90920461ffff1660208301527f712ca2ffb17da9e3b90d98d54938dee8be84b528cbdec691d680c1df8b78538a910160405180910390a150565b6000806000613bf785600401805480602002602001604051908101604052809291908181526020018280548015613bec57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613bce575b505050505085613d21565b915091508115613c0a579150610d4f9050565b604051630330dbc960e11b81526004016111189060208082526004908201527f50533a3600000000000000000000000000000000000000000000000000000000604082015260600190565b6000818152602084905260408120546001600160a01b03908116908416811480613ca657506001600160a01b03808216600090815260038701602090815260408083209388168352929052205460ff165b80613ccb5750836001600160a01b0316613cc086856129c7565b6001600160a01b0316145b95945050505050565b600081815b8451811015613d1957613d0582868381518110613cf857613cf86143d3565b6020026020010151613d7d565b915080613d1181614886565b915050613cd9565b509392505050565b81516000908190815b81811015613d7457846001600160a01b0316868281518110613d4e57613d4e6143d3565b60200260200101516001600160a01b031603613d6c57600193508092505b600101613d2a565b50509250929050565b6000818310613d99576000828152602084905260409020610e2c565b6000838152602083905260409020610e2c565b508054600082559060005260206000209081019061106391905b80821115613dda5760008155600101613dc6565b5090565b6001600160e01b03198116811461106357600080fd5b600060208284031215613e0657600080fd5b8135610e2c81613dde565b60005b83811015613e2c578181015183820152602001613e14565b50506000910152565b60008151808452613e4d816020860160208601613e11565b601f01601f19169290920160200192915050565b602081526000610e2c6020830184613e35565b600060208284031215613e8657600080fd5b5035919050565b80356001600160a01b0381168114613ea457600080fd5b919050565b60008060408385031215613ebc57600080fd5b613ec583613e8d565b946020939093013593505050565b60008060408385031215613ee657600080fd5b50508035926020909101359150565b803561ffff81168114613ea457600080fd5b60008060408385031215613f1a57600080fd5b613f2383613e8d565b9150613f3160208401613ef5565b90509250929050565b60008060408385031215613f4d57600080fd5b8235613f5881613dde565b9150613f3160208401613e8d565b600080600080600060808688031215613f7e57600080fd5b613f8786613e8d565b9450613f9560208701613e8d565b935060408601359250606086013567ffffffffffffffff80821115613fb957600080fd5b818801915088601f830112613fcd57600080fd5b813581811115613fdc57600080fd5b896020828501011115613fee57600080fd5b9699959850939650602001949392505050565b60008060006060848603121561401657600080fd5b8335925061402660208501613e8d565b915061403460408501613ef5565b90509250925092565b60008060006060848603121561405257600080fd5b61405b84613e8d565b925061406960208501613e8d565b9150604084013590509250925092565b60006020828403121561408b57600080fd5b610e2c82613e8d565b6020808252825182820181905260009190848201906040850190845b818110156140d55783516001600160a01b0316835292840192918401916001016140b0565b50909695505050505050565b60008083601f8401126140f357600080fd5b50813567ffffffffffffffff81111561410b57600080fd5b6020830191508360208260051b850101111561412657600080fd5b9250929050565b60008060008060006080868803121561414557600080fd5b8535945061415560208701613e8d565b935060408601359250606086013567ffffffffffffffff81111561417857600080fd5b614184888289016140e1565b969995985093965092949392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126141bc57600080fd5b813567ffffffffffffffff808211156141d7576141d7614195565b604051601f8301601f19908116603f011681019082821181831017156141ff576141ff614195565b8160405283815286602085880101111561421857600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561424d57600080fd5b833567ffffffffffffffff8082111561426557600080fd5b614271878388016141ab565b9450602086013591508082111561428757600080fd5b614293878388016141ab565b935060408601359150808211156142a957600080fd5b506142b6868287016141ab565b9150509250925092565b6000602082840312156142d257600080fd5b813567ffffffffffffffff8111156142e957600080fd5b61381b848285016141ab565b6000806040838503121561430857600080fd5b61431183613e8d565b91506020830135801515811461432657600080fd5b809150509250929050565b6000806000806060858703121561434757600080fd5b8435935061435760208601613e8d565b9250604085013567ffffffffffffffff81111561437357600080fd5b61437f878288016140e1565b95989497509550505050565b6000806040838503121561439e57600080fd5b613f5883613e8d565b6000806000606084860312156143bc57600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156143fb57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610d4f57610d4f614402565b8082028115828204841417610d4f57610d4f614402565b634e487b7160e01b600052601260045260246000fd5b60008261446757614467614442565b500490565b60008261447b5761447b614442565b500690565b600181811c9082168061449457607f821691505b6020821081036144b457634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610fe157600081815260208120601f850160051c810160208610156144e15750805b601f850160051c820191505b81811015614500578281556001016144ed565b505050505050565b815167ffffffffffffffff81111561452257614522614195565b614536816145308454614480565b846144ba565b602080601f83116001811461456b57600084156145535750858301515b600019600386901b1c1916600185901b178555614500565b600085815260208120601f198616915b8281101561459a5788860151825594840194600190910190840161457b565b50858210156145b85787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b81810381811115610d4f57610d4f614402565b600081546145e881614480565b60018281168015614600576001811461461557614644565b60ff1984168752821515830287019450614644565b8560005260208060002060005b8581101561463b5781548a820152908401908201614622565b50505082870194505b5050505092915050565b7f7b0000000000000000000000000000000000000000000000000000000000000081527f226e616d65223a2022486f6d6965732047656e657369732023000000000000006001820152600085516146ac81601a850160208a01613e11565b80830190507f222c00000000000000000000000000000000000000000000000000000000000080601a8301527f226465736372697074696f6e223a202200000000000000000000000000000000601c83015261470b602c8301886145db565b91508082527f22696d616765223a2022000000000000000000000000000000000000000000006002830152614743600c8301876145db565b9081527f22616e696d6174696f6e5f75726c223a202200000000000000000000000000006002820152905061477b60148201856145db565b7f220000000000000000000000000000000000000000000000000000000000000081527f7d000000000000000000000000000000000000000000000000000000000000006001820152600201979650505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161480a81601d850160208701613e11565b91909101601d0192915050565b634e487b7160e01b600052603160045260246000fd5b60006001600160a01b0380871683528086166020840152508360408301526080606083015261485f6080830184613e35565b9695505050505050565b60006020828403121561487b57600080fd5b8151610e2c81613dde565b60006001820161489857614898614402565b506001019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220ed328c08ff18b159f7e3d70e6781cd2a14eded050466f4014276ca6751db6b2c64736f6c6343000811003300000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000004ce69fd760ad0c07490178f9a47863dc0358cccd0000000000000000000000004ce69fd760ad0c07490178f9a47863dc0358cccd000000000000000000000000e318cde62513f8c21e91e5211ff33a7eedf78a2f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000e486f6d696573206f6620576562330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004486f573300000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106104185760003560e01c806376d7fc0711610228578063b88d4fde11610128578063dcd4ab77116100bb578063e8a3d4851161008a578063ec1ffdd81161006f578063ec1ffdd814610c1a578063f2fde38b14610c44578063f950233314610c6457610455565b8063e8a3d48514610be5578063e985e9c514610bfa57610455565b8063dcd4ab7714610b7b578063de02cde714610b90578063e33b7de314610bb0578063e7b7544014610bc557610455565b8063ca4b208b116100f7578063ca4b208b14610b0a578063ce7c2ac214610b28578063d39ce77c14610b48578063d601f1dc14610b6857610455565b8063b88d4fde14610a8a578063bb5027f714610aaa578063c3b8e34514610aca578063c87b56dd14610aea57610455565b806396d32915116101bb578063a22cb4651161018a578063a6b6cb371161016f578063a6b6cb3714610a4a578063a86ff96014610a60578063ad6d9c1714610a7557610455565b8063a22cb46514610a0a578063a3f8eace14610a2a57610455565b806396d329151461098f5780639852595c146109af5780639bce3944146109cf578063a0355eca146109ea57610455565b80638bb2b65a116101f75780638bb2b65a1461091c5780638da5cb5b1461093c578063938e3d7b1461095a57806395d89b411461097a57610455565b806376d7fc07146108bc57806379ba5097146108d15780638159324c146108e65780638693da201461090657610455565b80632db11544116103335780634e8086aa116102c65780636352211e1161029557806366278a6c1161027a57806366278a6c1461086757806370a0823114610887578063715018a6146108a757610455565b80636352211e1461082757806364cb4edb1461084757610455565b80634e8086aa1461079e57806350d604e3146107c05780635ba5e9f0146107e05780636149d8711461080757610455565b806342842e0e1161030257806342842e0e1461072957806344faded01461074957806347786d37146107695780634e71d92d1461078957610455565b80632db11544146106cc57806331e26cfd146106df5780633a98ef39146106f45780633ed358551461070957610455565b8063150b7a02116103ab57806323b872dd1161037a57806323b872dd14610643578063266dcbf6146106635780632a55205a146106785780632bfcf0f2146106b757610455565b8063150b7a02146105b557806318160ddd146105ee57806318f9b023146106035780631fcb02f31461062357610455565b80630b78f9c0116103e75780630b78f9c0146105385780630c222ee51461055857806310ab94321461057857806312065fe01461059857610455565b806301ffc9a71461048757806306fdde03146104bc578063081812fc146104de578063095ea7b31461051657610455565b366104555760405134815233907f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be770906020015b60405180910390a2005b60405134815233907f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be7709060200161044b565b34801561049357600080fd5b506104a76104a2366004613df4565b610c84565b60405190151581526020015b60405180910390f35b3480156104c857600080fd5b506104d1610d55565b6040516104b39190613e61565b3480156104ea57600080fd5b506104fe6104f9366004613e74565b610d66565b6040516001600160a01b0390911681526020016104b3565b34801561052257600080fd5b50610536610531366004613ea9565b610d72565b005b34801561054457600080fd5b50610536610553366004613ed3565b610dbb565b34801561056457600080fd5b50610536610573366004613f07565b610df6565b34801561058457600080fd5b506104a7610593366004613f3a565b610e1e565b3480156105a457600080fd5b50475b6040519081526020016104b3565b3480156105c157600080fd5b506105d56105d0366004613f66565b610e33565b6040516001600160e01b031990911681526020016104b3565b3480156105fa57600080fd5b506105a7610e4d565b34801561060f57600080fd5b5061053661061e366004613ea9565b610e59565b34801561062f57600080fd5b5061053661063e366004614001565b610dde565b34801561064f57600080fd5b5061053661065e36600461403d565b610e7d565b34801561066f57600080fd5b50610536610ed1565b34801561068457600080fd5b50610698610693366004613ed3565b610fe6565b604080516001600160a01b0390931683526020830191909152016104b3565b3480156106c357600080fd5b50610536611000565b6105366106da366004613e74565b611066565b3480156106eb57600080fd5b506105366111be565b34801561070057600080fd5b506105a7611203565b34801561071557600080fd5b50610536610724366004614079565b61120e565b34801561073557600080fd5b5061053661074436600461403d565b611231565b34801561075557600080fd5b50610536610764366004613f3a565b6112c5565b34801561077557600080fd5b50610536610784366004613e74565b61134c565b34801561079557600080fd5b50610536611369565b3480156107aa57600080fd5b506107b361149a565b6040516104b39190614094565b3480156107cc57600080fd5b506104a76107db366004613e74565b6114a6565b3480156107ec57600080fd5b506105d56107fb366004613df4565b506303e1469160e61b90565b34801561081357600080fd5b50610536610822366004614079565b6114e7565b34801561083357600080fd5b506104fe610842366004613e74565b61152c565b34801561085357600080fd5b50610536610862366004614079565b611549565b34801561087357600080fd5b50610536610882366004613df4565b6115ac565b34801561089357600080fd5b506105a76108a2366004614079565b6115e3565b3480156108b357600080fd5b50610536611601565b3480156108c857600080fd5b50610536611652565b3480156108dd57600080fd5b50610536611676565b3480156108f257600080fd5b5061053661090136600461412d565b6116d9565b34801561091257600080fd5b506105a760205481565b34801561092857600080fd5b50610536610937366004614238565b61195f565b34801561094857600080fd5b506009546001600160a01b03166104fe565b34801561096657600080fd5b506105366109753660046142c0565b6119a3565b34801561098657600080fd5b506104d16119c7565b34801561099b57600080fd5b506104a76109aa366004613e74565b6119d3565b3480156109bb57600080fd5b506105a76109ca366004614079565b611a14565b3480156109db57600080fd5b5061053661063e366004613e74565b3480156109f657600080fd5b50610536610a05366004613ed3565b611a32565b348015610a1657600080fd5b50610536610a253660046142f5565b611a55565b348015610a3657600080fd5b506105a7610a45366004614079565b611aa8565b348015610a5657600080fd5b506105a7601f5481565b348015610a6c57600080fd5b50610536611c83565b348015610a8157600080fd5b50610536611cc8565b348015610a9657600080fd5b50610536610aa5366004613f66565b611d19565b348015610ab657600080fd5b50610536610ac5366004614331565b611db2565b348015610ad657600080fd5b506104a7610ae5366004613e74565b612024565b348015610af657600080fd5b506104d1610b05366004613e74565b612065565b348015610b1657600080fd5b50600a546001600160a01b03166104fe565b348015610b3457600080fd5b506105a7610b43366004614079565b6120cc565b348015610b5457600080fd5b50610536610b63366004614079565b6120ea565b610536610b76366004614331565b61212f565b348015610b8757600080fd5b506105366123e8565b348015610b9c57600080fd5b50610536610bab366004613f3a565b61240a565b348015610bbc57600080fd5b50600e546105a7565b348015610bd157600080fd5b506105a7610be0366004614079565b61248d565b348015610bf157600080fd5b506104d161249a565b348015610c0657600080fd5b506104a7610c1536600461438b565b61252c565b348015610c2657600080fd5b50610c2f61255c565b604080519283526020830191909152016104b3565b348015610c5057600080fd5b50610536610c5f366004614079565b61257a565b348015610c7057600080fd5b50610536610c7f3660046143a7565b6125dd565b60006001600160e01b031982167f7f5828d0000000000000000000000000000000000000000000000000000000001480610ce757506001600160e01b031982167f80ac58cd00000000000000000000000000000000000000000000000000000000145b80610d1b57506001600160e01b031982167f2a55205a00000000000000000000000000000000000000000000000000000000145b80610d4f57506001600160e01b031982167f5b5e139f00000000000000000000000000000000000000000000000000000000145b92915050565b6060610d616000612931565b905090565b6000610d4f81836129c7565b610d7f6000833384612a4c565b60405181906001600160a01b0384169033907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590600090a45050565b610dce600863ca4b208b60e01b33612b45565b15610dde57601f91909155602055565b6040516282b42960e81b815260040160405180910390fd5b610e096008638da5cb5b60e01b33612b45565b15610dde57610e1a600c8383612ba2565b5050565b6000610e2c60088484612b45565b9392505050565b60006040516282b42960e81b815260040160405180910390fd5b6000610d616000612c83565b610e6c600863ca4b208b60e01b33612b45565b15610dde57610e1a600d8383612c90565b610e8b600084843385612e27565b80826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000610edd600d612fe4565b805190915060005b81811015610fe1576000306001600160a01b031663a3f8eace858481518110610f1057610f106143d3565b60200260200101516040518263ffffffff1660e01b8152600401610f4391906001600160a01b0391909116815260200190565b602060405180830381865afa158015610f60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8491906143e9565b9050610fb5848381518110610f9b57610f9b6143d3565b602002602001015182600d6130499092919063ffffffff16565b610fd8848381518110610fca57610fca6143d3565b6020026020010151826130d0565b50600101610ee5565b505050565b600080610ff5600c85856131e9565b909590945092505050565b636525904560e11b61101460088233612b45565b8061102d575061102d60086303e1469160e61b33612b45565b15610dde57611045600863ca4b208b60e01b336126ba565b611050600833612859565b6110636008636525904560e11b33613226565b50565b6013546012546110769190614418565b4210610dde57600581111561109d576040516282b42960e81b815260040160405180910390fd5b6012546000036110bf576040516282b42960e81b815260040160405180910390fd5b806020546110cd919061442b565b341461112157604051630330dbc960e11b815260206004820152601160248201527f6d73672e76616c756520746f6f206c6f7700000000000000000000000000000060448201526064015b60405180910390fd5b6014548161112f6000612c83565b6111399190614418565b1115611157576040516282b42960e81b815260040160405180910390fd5b60005b81811015610e1a576111783361116f60215490565b600091906132e2565b60215460405133906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46111b6602180546001019055565b60010161115a565b636525904560e11b6111d260088233612b45565b806111eb57506111eb60086303e1469160e61b33612b45565b15610dde576110636008636525904560e11b33613226565b6000610d61600d5490565b611221600863ca4b208b60e01b33612b45565b15610dde57611063600d82613407565b6040517fb88d4fde0000000000000000000000000000000000000000000000000000000081526001600160a01b03808516600483015283166024820152604481018290526080606482015260006084820152309063b88d4fde9060a401600060405180830381600087803b1580156112a857600080fd5b505af11580156112bc573d6000803e3d6000fd5b50505050505050565b816112d260088233612b45565b806112eb57506112eb60086303e1469160e61b33612b45565b15610dde576001600160e01b03198316636525904560e11b148061131f57506001600160e01b031983166346d2e5ad60e11b145b1561134057336001600160a01b03831603610dde57610fe160088484613226565b610fe160088484613226565b61135f600863ca4b208b60e01b33612b45565b15610dde57601455565b60405163673e156160e11b8152336004820152309063ce7c2ac290602401602060405180830381865afa1580156113a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c891906143e9565b6000036113e7576040516282b42960e81b815260040160405180910390fd5b6040517fa3f8eace000000000000000000000000000000000000000000000000000000008152336004820152600090309063a3f8eace90602401602060405180830381865afa15801561143e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061146291906143e9565b905080600003611484576040516282b42960e81b815260040160405180910390fd5b611490600d3383613049565b61106333826130d0565b6060610d61600d612fe4565b6000806114b561010084614458565b905060006114c56101008561446c565b60009283526016602052604090922054600190921b9182169091149392505050565b63ca4b208b60e01b6114fb60088233612b45565b80611514575061151460086303e1469160e61b33612b45565b15610dde57610e1a6008636525904560e11b846126ba565b6000818152602081905260408120546001600160a01b0316610d4f565b63ca4b208b60e01b61155d60088233612b45565b80611576575061157660086303e1469160e61b33612b45565b15610dde5761158e600863ca4b208b60e01b846126ba565b611599600883612859565b610e1a600863ca4b208b60e01b33613226565b806115b960088233612b45565b806115d257506115d260086303e1469160e61b33612b45565b15610dde57610e1a60088333613226565b6001600160a01b038116600090815260016020526040812054610d4f565b638da5cb5b60e01b61161560088233612b45565b8061162e575061162e60086303e1469160e61b33612b45565b15610dde5761163f600860006128c5565b6110636008638da5cb5b60e01b33613226565b611665600863ca4b208b60e01b33612b45565b15610dde57611674600d613587565b565b6346d2e5ad60e11b61168a60088233612b45565b806116a357506116a360086303e1469160e61b33612b45565b15610dde576116bb6008638da5cb5b60e01b336126ba565b6116c66008336128c5565b61106360086346d2e5ad60e11b33613226565b6013546012546116e99190614418565b421080156116f957506012544210155b15610dde57601254600003611720576040516282b42960e81b815260040160405180910390fd5b611729856114a6565b1561176957604051630330dbc960e11b815260206004820152600f60248201526e105b1c9958591e4810db185a5b5959608a1b6044820152606401611118565b60408051602081018790526bffffffffffffffffffffffff19606087901b1691810191909152605481018490526000906074016040516020818303038152906040528051906020012090506117f583838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050601554915084905061361c565b61183257604051630330dbc960e11b815260206004820152600d60248201526c24b73b30b634b210283937b7b360991b6044820152606401611118565b61183b86613632565b601454846118496000612c83565b6118539190614418565b1115611871576040516282b42960e81b815260040160405180910390fd5b60005b848110156118d8576118898661116f60215490565b6021546040516001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46118d0602180546001019055565b600101611874565b50604080518781526001600160a01b03871660208201529081018590526080606082018190526005908201527f41646d696e00000000000000000000000000000000000000000000000000000060a08201527fee563d8e532abc293fca2fdeb41c25180305bddcf9206c167dab3e155aaf17139060c00160405180910390a1505050505050565b611972600863ca4b208b60e01b33612b45565b15610dde57601d6119838482614508565b50601c6119908382614508565b50601e61199d8282614508565b50505050565b6119b6600863ca4b208b60e01b33612b45565b15610dde57601b610e1a8282614508565b6060610d616000613670565b6000806119e261010084614458565b905060006119f26101008561446c565b6000928352601a602052604090922054600190921b9182169091149392505050565b6001600160a01b038116600090815260106020526040812054610d4f565b611a45600863ca4b208b60e01b33612b45565b15610dde57601291909155601355565b611a626000833384613681565b60405181151581526001600160a01b0383169033907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319060200160405180910390a35050565b600080306001600160a01b031663e33b7de36040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ae9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b0d91906143e9565b611b179047614418565b6040517f9852595c0000000000000000000000000000000000000000000000000000000081526001600160a01b03851660048201529091503090639852595c90602401602060405180830381865afa158015611b77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b9b91906143e9565b306001600160a01b0316633a98ef396040518163ffffffff1660e01b8152600401602060405180830381865afa158015611bd9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bfd91906143e9565b60405163673e156160e11b81526001600160a01b0386166004820152309063ce7c2ac290602401602060405180830381865afa158015611c41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c6591906143e9565b611c6f908461442b565b611c799190614458565b610e2c91906145c8565b6346d2e5ad60e11b611c9760088233612b45565b80611cb05750611cb060086303e1469160e61b33612b45565b15610dde5761106360086346d2e5ad60e11b33613226565b63ca4b208b60e01b611cdc60088233612b45565b80611cf55750611cf560086303e1469160e61b33612b45565b15610dde57611d0660086000612859565b611063600863ca4b208b60e01b33613226565b611d27600086863387612e27565b611d6985858585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061372192505050565b5082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050505050565b601354601254611dc29190614418565b42108015611dd257506012544210155b15610dde57601254600003611df9576040516282b42960e81b815260040160405180910390fd5b611e0284612024565b15611e4257604051630330dbc960e11b815260206004820152600f60248201526e105b1c9958591e4810db185a5b5959608a1b6044820152606401611118565b60008484604051602001611e7292919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b604051602081830303815290604052805190602001209050611ecb83838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050601754915084905061361c565b611f0857604051630330dbc960e11b815260206004820152600d60248201526c24b73b30b634b210283937b7b360991b6044820152606401611118565b611f1185613823565b601454611f1e6000612c83565b611f29906001614418565b1115611f47576040516282b42960e81b815260040160405180910390fd5b611f548461116f60215490565b6021546040516001600160a01b038616906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4611f9b602180546001019055565b604080518681526001600160a01b03861660208201526001918101919091526080606082018190526006908201527f486f6d696573000000000000000000000000000000000000000000000000000060a08201527fee563d8e532abc293fca2fdeb41c25180305bddcf9206c167dab3e155aaf17139060c0015b60405180910390a15050505050565b60008061203361010084614458565b905060006120436101008561446c565b60009283526018602052604090922054600190921b9182169091149392505050565b6060600061207283613861565b601d601c601e60405160200161208b949392919061464e565b60405160208183030381529060405290506120a581613996565b6040516020016120b591906147d2565b604051602081830303815290604052915050919050565b6001600160a01b0381166000908152600f6020526040812054610d4f565b638da5cb5b60e01b6120fe60088233612b45565b80612117575061211760086303e1469160e61b33612b45565b15610dde57610e1a60086346d2e5ad60e11b846126ba565b60135460125461213f9190614418565b4210801561214f57506012544210155b15610dde57601254600003612176576040516282b42960e81b815260040160405180910390fd5b601f5434146121c857604051630330dbc960e11b815260206004820152601160248201527f6d73672e76616c756520746f6f206c6f770000000000000000000000000000006044820152606401611118565b6121d1846119d3565b1561221157604051630330dbc960e11b815260206004820152600f60248201526e105b1c9958591e4810db185a5b5959608a1b6044820152606401611118565b6000848460405160200161224192919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b60405160208183030381529060405280519060200120905061229a83838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050601954915084905061361c565b6122d757604051630330dbc960e11b815260206004820152600d60248201526c24b73b30b634b210283937b7b360991b6044820152606401611118565b6122e085613ae9565b6014546122ed6000612c83565b6122f8906001614418565b1115612316576040516282b42960e81b815260040160405180910390fd5b6123238461116f60215490565b6021546040516001600160a01b038616906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a461236a602180546001019055565b604080518681526001600160a01b03861660208201526001918101919091526080606082018190526007908201527f4e6f726d6965730000000000000000000000000000000000000000000000000060a08201527fee563d8e532abc293fca2fdeb41c25180305bddcf9206c167dab3e155aaf17139060c001612015565b6123fb6008638da5cb5b60e01b33612b45565b15610dde57611674600c613b27565b8161241760088233612b45565b80612430575061243060086303e1469160e61b33612b45565b15610dde576001600160e01b03198316636525904560e11b148061246457506001600160e01b031983166346d2e5ad60e11b145b15612481576040516282b42960e81b815260040160405180910390fd5b610fe1600884846126ba565b6000610d4f600d83613b8c565b6060601b80546124a990614480565b80601f01602080910402602001604051908101604052809291908181526020018280546124d590614480565b80156125225780601f106124f757610100808354040283529160200191612522565b820191906000526020600020905b81548152906001019060200180831161250557829003601f168201915b5050505050905090565b6001600160a01b03808316600090815260036020908152604080832093851683529290529081205460ff16610e2c565b6000806012546013546012546125729190614418565b915091509091565b638da5cb5b60e01b61258e60088233612b45565b806125a757506125a760086303e1469160e61b33612b45565b15610dde576125bf6008638da5cb5b60e01b846126ba565b6125ca6008836128c5565b610e1a6008638da5cb5b60e01b33613226565b6125f0600863ca4b208b60e01b33612b45565b15610dde57601592909255601755601955565b8082556040518181527f83b179bd5cb3a111f82ac98510d3c66f48f77679e657302f4f253d4c32d6d672906020015b60405180910390a15050565b6004820161264c8282614508565b507f13c98778b0c1a086bb98d7f1986e15788b5d3a1ad4c492e1d78f1c4cc51c20cf816040516126329190613e61565b6005820161268a8282614508565b507f3e46ff90086ee29856e77591e82c82ff8ed513379b0fd82e84fc5290dd633c99816040516126329190613e61565b6001600160a01b0381166126e0576040516282b42960e81b815260040160405180910390fd5b6126eb838383612b45565b15612708576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0381166000818152602085815260408083206001600160e01b0319871680855290835292819020805460ff19166001908117909155815193845291830193909352918101919091527fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f7906060015b60405180910390a1505050565b61279c826303e1469160e61b83612b45565b156127f6576003820180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a3505050565b6001600160a01b038116610dde576003820180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a3505050565b61286b8263ca4b208b60e01b83612b45565b156127f6576002820180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f2cfca82ac51c2fc6b6db547820d28d526a505e12d230afb8bf112a5aeefa9a4c90600090a3505050565b6128d782638da5cb5b60e01b83612b45565b156127f6576001820180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b606081600401805461294290614480565b80601f016020809104026020016040519081016040528092919081815260200182805461296e90614480565b80156129bb5780601f10612990576101008083540402835291602001916129bb565b820191906000526020600020905b81548152906001019060200180831161299e57829003601f168201915b50505050509050919050565b6000818152602083905260408120546001600160a01b0316612a2c57604051630330dbc960e11b815260206004820152600360248201527f4c3a3100000000000000000000000000000000000000000000000000000000006044820152606401611118565b50600090815260029190910160205260409020546001600160a01b031690565b6000818152602085905260409020546001600160a01b03908116908416819003612ab957604051630330dbc960e11b815260206004820152600360248201527f4c3a3200000000000000000000000000000000000000000000000000000000006044820152606401611118565b612ac4858484613c55565b612b1157604051630330dbc960e11b815260206004820152600360248201527f4c3a3300000000000000000000000000000000000000000000000000000000006044820152606401611118565b50600090815260029390930160205250604090912080546001600160a01b0319166001600160a01b03909216919091179055565b60006001600160a01b038216612b6d576040516282b42960e81b815260040160405180910390fd5b506001600160a01b03166000908152602092835260408082206001600160e01b03199390931682529190925290205460ff1690565b6103e88161ffff16101580612bb9575061ffff8116155b15612c0757604051630330dbc960e11b815260206004820152600360248201527f523a3100000000000000000000000000000000000000000000000000000000006044820152606401611118565b82546001600160a01b0383811675ffffffffffffffffffffffffffffffffffffffffffff1990921691909117600160a01b61ffff84811682029290921780875560408051948216855291900490911660208301527f712ca2ffb17da9e3b90d98d54938dee8be84b528cbdec691d680c1df8b78538a910161277d565b6000610d4f826007015490565b6001600160a01b038216612cd057604051630330dbc960e11b81526004016111189060208082526004908201526350533a3360e01b604082015260600190565b80600003612d2357604051630330dbc960e11b81526004016111189060208082526004908201527f50533a3400000000000000000000000000000000000000000000000000000000604082015260600190565b6001600160a01b038216600090815260028401602052604090205415612d8e57604051630330dbc960e11b81526004016111189060208082526004908201527f50533a3500000000000000000000000000000000000000000000000000000000604082015260600190565b6004830180546001810182556000918252602080832090910180546001600160a01b0319166001600160a01b038616908117909155825260028501905260408120829055835482918591612de3908490614418565b9091555050604080516001600160a01b0384168152602081018390527f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac910161277d565b612e32858383613c55565b612e7f57604051630330dbc960e11b815260206004820152600360248201527f4c3a3500000000000000000000000000000000000000000000000000000000006044820152606401611118565b6000818152602086905260409020546001600160a01b039081169085168114612eeb57604051630330dbc960e11b815260206004820152600360248201527f4c3a3600000000000000000000000000000000000000000000000000000000006044820152606401611118565b6001600160a01b038416612f4257604051630330dbc960e11b815260206004820152600360248201527f4c3a3700000000000000000000000000000000000000000000000000000000006044820152606401611118565b612f4f8660008585612a4c565b6001600160a01b0385166000908152600187810160205260408220805491929091612f7b9084906145c8565b90915550506001600160a01b0384166000908152600187810160205260408220805491929091612fac908490614418565b909155505050600090815260209490945250604090922080546001600160a01b0319166001600160a01b039093169290921790915550565b6060816004018054806020026020016040519081016040528092919081815260200182805480156129bb57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116130205750505050509050919050565b8083600101600082825461305d9190614418565b90915550506001600160a01b03821660009081526003840160205260408120805483929061308c908490614418565b9091555050604080516001600160a01b0384168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910161277d565b804710156131205760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401611118565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461316d576040519150601f19603f3d011682016040523d82523d6000602084013e613172565b606091505b5050905080610fe15760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401611118565b82546001600160a01b038116906000906103e89061321290600160a01b900461ffff168561442b565b61321c9190614458565b9050935093915050565b6001600160a01b03811661324c576040516282b42960e81b815260040160405180910390fd5b613257838383612b45565b613273576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0381166000818152602085815260408083206001600160e01b03198716808552908352818420805460ff19169055815190815291820193909352918201527fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f79060600161277d565b6001600160a01b03821661333957604051630330dbc960e11b815260206004820152600360248201527f4c3a3800000000000000000000000000000000000000000000000000000000006044820152606401611118565b6000818152602084905260409020546001600160a01b03161561339f57604051630330dbc960e11b815260206004820152600360248201527f4c3a3900000000000000000000000000000000000000000000000000000000006044820152606401611118565b6001600160a01b03821660009081526001848101602052604082208054919290916133cb908490614418565b9091555050600081815260208490526040902080546001600160a01b0319166001600160a01b0384161790556007830180546001019055505050565b6001600160a01b03811661344757604051630330dbc960e11b81526004016111189060208082526004908201526350533a3360e01b604082015260600190565b60006134538383613b8c565b60048401805491925060009161346b906001906145c8565b8154811061347b5761347b6143d3565b6000918252602090912001546004850180546001600160a01b0390921692508291849081106134ac576134ac6143d3565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550836004018054806134ed576134ed614817565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0385168252600286019052604081208054908290558554909182918791906135439084906145c8565b9091555050604080516001600160a01b0386168152602081018390527f104b8837ec12e86f303ac7ce5e3bf20c6790f843fabd7451943f3390fc8376cb9101612015565b600481015460005b818110156135db5760008360040182815481106135ae576135ae6143d3565b60009182526020808320909101546001600160a01b0316825260028601905260408120555060010161358f565b5060008083556135ef906004840190613dac565b6040517f3407fd525bf6581e0ae8e3a3636bd90d02112bea34d66802743c28ced73f910e90600090a15050565b6000826136298584613cd4565b14949350505050565b600061364061010083614458565b905060006136506101008461446c565b6000928352601660205260409092208054600190931b9092179091555050565b606081600501805461294290614480565b826001600160a01b0316826001600160a01b0316036136e357604051630330dbc960e11b815260206004820152600360248201527f4c3a3400000000000000000000000000000000000000000000000000000000006044820152606401611118565b6001600160a01b0391821660009081526003949094016020908152604080862094909316855292909252909120805460ff1916911515919091179055565b60006001600160a01b0384163b1561381757604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061376590339089908890889060040161482d565b6020604051808303816000875af19250505080156137a0575060408051601f3d908101601f1916820190925261379d91810190614869565b60015b6137fd573d8080156137ce576040519150601f19603f3d011682016040523d82523d6000602084013e6137d3565b606091505b5080516000036137f5576040516282b42960e81b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061381b565b5060015b949350505050565b600061383161010083614458565b905060006138416101008461446c565b6000928352601860205260409092208054600190931b9092179091555050565b6060816000036138a457505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156138ce57806138b881614886565b91506138c79050600a83614458565b91506138a8565b60008167ffffffffffffffff8111156138e9576138e9614195565b6040519080825280601f01601f191660200182016040528015613913576020820181803683370190505b5090505b841561381b576139286001836145c8565b9150613935600a8661446c565b613940906030614418565b60f81b818381518110613955576139556143d3565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061398f600a86614458565b9450613917565b606081516000036139b557505060408051602081019091526000815290565b60006040518060600160405280604081526020016148a060409139905060006003845160026139e49190614418565b6139ee9190614458565b6139f990600461442b565b67ffffffffffffffff811115613a1157613a11614195565b6040519080825280601f01601f191660200182016040528015613a3b576020820181803683370190505b509050600182016020820185865187015b80821015613aa7576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250613a4c565b5050600386510660018114613ac35760028114613ad657613ade565b603d6001830353603d6002830353613ade565b603d60018303535b509195945050505050565b6000613af761010083614458565b90506000613b076101008461446c565b6000928352601a60205260409092208054600190931b9092179091555050565b805475ffffffffffffffffffffffffffffffffffffffffffff19168082556040805160008152600160a01b90920461ffff1660208301527f712ca2ffb17da9e3b90d98d54938dee8be84b528cbdec691d680c1df8b78538a910160405180910390a150565b6000806000613bf785600401805480602002602001604051908101604052809291908181526020018280548015613bec57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613bce575b505050505085613d21565b915091508115613c0a579150610d4f9050565b604051630330dbc960e11b81526004016111189060208082526004908201527f50533a3600000000000000000000000000000000000000000000000000000000604082015260600190565b6000818152602084905260408120546001600160a01b03908116908416811480613ca657506001600160a01b03808216600090815260038701602090815260408083209388168352929052205460ff165b80613ccb5750836001600160a01b0316613cc086856129c7565b6001600160a01b0316145b95945050505050565b600081815b8451811015613d1957613d0582868381518110613cf857613cf86143d3565b6020026020010151613d7d565b915080613d1181614886565b915050613cd9565b509392505050565b81516000908190815b81811015613d7457846001600160a01b0316868281518110613d4e57613d4e6143d3565b60200260200101516001600160a01b031603613d6c57600193508092505b600101613d2a565b50509250929050565b6000818310613d99576000828152602084905260409020610e2c565b6000838152602083905260409020610e2c565b508054600082559060005260206000209081019061106391905b80821115613dda5760008155600101613dc6565b5090565b6001600160e01b03198116811461106357600080fd5b600060208284031215613e0657600080fd5b8135610e2c81613dde565b60005b83811015613e2c578181015183820152602001613e14565b50506000910152565b60008151808452613e4d816020860160208601613e11565b601f01601f19169290920160200192915050565b602081526000610e2c6020830184613e35565b600060208284031215613e8657600080fd5b5035919050565b80356001600160a01b0381168114613ea457600080fd5b919050565b60008060408385031215613ebc57600080fd5b613ec583613e8d565b946020939093013593505050565b60008060408385031215613ee657600080fd5b50508035926020909101359150565b803561ffff81168114613ea457600080fd5b60008060408385031215613f1a57600080fd5b613f2383613e8d565b9150613f3160208401613ef5565b90509250929050565b60008060408385031215613f4d57600080fd5b8235613f5881613dde565b9150613f3160208401613e8d565b600080600080600060808688031215613f7e57600080fd5b613f8786613e8d565b9450613f9560208701613e8d565b935060408601359250606086013567ffffffffffffffff80821115613fb957600080fd5b818801915088601f830112613fcd57600080fd5b813581811115613fdc57600080fd5b896020828501011115613fee57600080fd5b9699959850939650602001949392505050565b60008060006060848603121561401657600080fd5b8335925061402660208501613e8d565b915061403460408501613ef5565b90509250925092565b60008060006060848603121561405257600080fd5b61405b84613e8d565b925061406960208501613e8d565b9150604084013590509250925092565b60006020828403121561408b57600080fd5b610e2c82613e8d565b6020808252825182820181905260009190848201906040850190845b818110156140d55783516001600160a01b0316835292840192918401916001016140b0565b50909695505050505050565b60008083601f8401126140f357600080fd5b50813567ffffffffffffffff81111561410b57600080fd5b6020830191508360208260051b850101111561412657600080fd5b9250929050565b60008060008060006080868803121561414557600080fd5b8535945061415560208701613e8d565b935060408601359250606086013567ffffffffffffffff81111561417857600080fd5b614184888289016140e1565b969995985093965092949392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126141bc57600080fd5b813567ffffffffffffffff808211156141d7576141d7614195565b604051601f8301601f19908116603f011681019082821181831017156141ff576141ff614195565b8160405283815286602085880101111561421857600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561424d57600080fd5b833567ffffffffffffffff8082111561426557600080fd5b614271878388016141ab565b9450602086013591508082111561428757600080fd5b614293878388016141ab565b935060408601359150808211156142a957600080fd5b506142b6868287016141ab565b9150509250925092565b6000602082840312156142d257600080fd5b813567ffffffffffffffff8111156142e957600080fd5b61381b848285016141ab565b6000806040838503121561430857600080fd5b61431183613e8d565b91506020830135801515811461432657600080fd5b809150509250929050565b6000806000806060858703121561434757600080fd5b8435935061435760208601613e8d565b9250604085013567ffffffffffffffff81111561437357600080fd5b61437f878288016140e1565b95989497509550505050565b6000806040838503121561439e57600080fd5b613f5883613e8d565b6000806000606084860312156143bc57600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156143fb57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610d4f57610d4f614402565b8082028115828204841417610d4f57610d4f614402565b634e487b7160e01b600052601260045260246000fd5b60008261446757614467614442565b500490565b60008261447b5761447b614442565b500690565b600181811c9082168061449457607f821691505b6020821081036144b457634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610fe157600081815260208120601f850160051c810160208610156144e15750805b601f850160051c820191505b81811015614500578281556001016144ed565b505050505050565b815167ffffffffffffffff81111561452257614522614195565b614536816145308454614480565b846144ba565b602080601f83116001811461456b57600084156145535750858301515b600019600386901b1c1916600185901b178555614500565b600085815260208120601f198616915b8281101561459a5788860151825594840194600190910190840161457b565b50858210156145b85787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b81810381811115610d4f57610d4f614402565b600081546145e881614480565b60018281168015614600576001811461461557614644565b60ff1984168752821515830287019450614644565b8560005260208060002060005b8581101561463b5781548a820152908401908201614622565b50505082870194505b5050505092915050565b7f7b0000000000000000000000000000000000000000000000000000000000000081527f226e616d65223a2022486f6d6965732047656e657369732023000000000000006001820152600085516146ac81601a850160208a01613e11565b80830190507f222c00000000000000000000000000000000000000000000000000000000000080601a8301527f226465736372697074696f6e223a202200000000000000000000000000000000601c83015261470b602c8301886145db565b91508082527f22696d616765223a2022000000000000000000000000000000000000000000006002830152614743600c8301876145db565b9081527f22616e696d6174696f6e5f75726c223a202200000000000000000000000000006002820152905061477b60148201856145db565b7f220000000000000000000000000000000000000000000000000000000000000081527f7d000000000000000000000000000000000000000000000000000000000000006001820152600201979650505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161480a81601d850160208701613e11565b91909101601d0192915050565b634e487b7160e01b600052603160045260246000fd5b60006001600160a01b0380871683528086166020840152508360408301526080606083015261485f6080830184613e35565b9695505050505050565b60006020828403121561487b57600080fd5b8151610e2c81613dde565b60006001820161489857614898614402565b506001019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220ed328c08ff18b159f7e3d70e6781cd2a14eded050466f4014276ca6751db6b2c64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000004ce69fd760ad0c07490178f9a47863dc0358cccd0000000000000000000000004ce69fd760ad0c07490178f9a47863dc0358cccd000000000000000000000000e318cde62513f8c21e91e5211ff33a7eedf78a2f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000e486f6d696573206f6620576562330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004486f573300000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _name (string): Homies of Web3
Arg [1] : _symbol (string): HoW3
Arg [2] : _admin (address): 0x4CE69fd760AD0c07490178f9a47863Dc0358cCCD
Arg [3] : _dev (address): 0x4CE69fd760AD0c07490178f9a47863Dc0358cCCD
Arg [4] : _owner (address): 0xE318Cde62513F8C21e91E5211ff33A7eedF78A2F
Arg [5] : _start (uint256): 1
-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [2] : 0000000000000000000000004ce69fd760ad0c07490178f9a47863dc0358cccd
Arg [3] : 0000000000000000000000004ce69fd760ad0c07490178f9a47863dc0358cccd
Arg [4] : 000000000000000000000000e318cde62513f8c21e91e5211ff33a7eedf78a2f
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [6] : 000000000000000000000000000000000000000000000000000000000000000e
Arg [7] : 486f6d696573206f662057656233000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [9] : 486f573300000000000000000000000000000000000000000000000000000000
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.