编译器
0.8.10+commit.fc410830
文件 1 的 15:BBCLUB.sol
pragma solidity 0.8.10;
import '../EthereumContracts/contracts/NFT/NFTBaseC.sol';
import '../EthereumContracts/contracts/utils/IWhitelistable_ECDSA.sol';
contract BBCLUB is NFTBaseC, IWhitelistable_ECDSA {
uint8 public constant PRIVATE_SALE = 2;
uint8 public constant PRE_SALE = 3;
uint8 public constant CLAIM = 4;
constructor(
uint256 reserve_,
uint256 maxBatch_,
uint256 maxSupply_
) {
_initNFTBaseC(
reserve_,
maxBatch_,
maxSupply_,
30000000000000000,
500,
"Bush Baby Club",
"BUSH",
"https://api.bushbabyclub.io/metadata?tokenId="
);
}
modifier isPrivateOrPreSale {
uint8 _currentState_ = getPauseState();
if ( _currentState_ != PRIVATE_SALE && _currentState_ != PRE_SALE ) {
revert IPausable_INCORRECT_STATE( _currentState_ );
}
_;
}
modifier isPreSale {
uint8 _currentState_ = getPauseState();
if ( _currentState_ != PRE_SALE ) {
revert IPausable_INCORRECT_STATE( _currentState_ );
}
_;
}
function claim( uint256 alloted_, Proof memory proof_, uint256 qty_ ) public validateAmount( qty_ ) isNotClosed isWhitelisted( _msgSender(), CLAIM, alloted_, proof_, qty_ ) {
address _account_ = _msgSender();
if ( _reserve < qty_ ) {
revert NFT_MAX_RESERVE( qty_, _reserve );
}
unchecked {
_reserve -= qty_;
}
_consumeWhitelist( _account_, CLAIM, qty_ );
_mint( _account_, qty_ );
}
function mintPreSale( uint256 alloted_, Proof memory proof_, uint256 qty_ ) public payable validateAmount( qty_ ) isPreSale isWhitelisted( _msgSender(), PRE_SALE, alloted_, proof_, qty_ ) {
uint256 _remainingSupply_ = MAX_SUPPLY - _reserve - supplyMinted();
if ( qty_ > _remainingSupply_ ) {
revert NFT_MAX_SUPPLY( qty_, _remainingSupply_ );
}
uint256 _expected_ = qty_ * SALE_PRICE;
if ( _expected_ != msg.value ) {
revert NFT_INCORRECT_PRICE( msg.value, _expected_ );
}
address _account_ = _msgSender();
_consumeWhitelist( _account_, PRE_SALE, qty_ );
_mint( _account_, qty_ );
}
function mintPrivateSale( uint256 alloted_, Proof memory proof_, uint256 qty_ ) public payable validateAmount( qty_ ) isPrivateOrPreSale isWhitelisted( _msgSender(), PRIVATE_SALE, alloted_, proof_, qty_ ) {
uint256 _remainingSupply_ = MAX_SUPPLY - _reserve - supplyMinted();
if ( qty_ > _remainingSupply_ ) {
revert NFT_MAX_SUPPLY( qty_, _remainingSupply_ );
}
uint256 _expected_ = qty_ * SALE_PRICE;
if ( _expected_ != msg.value ) {
revert NFT_INCORRECT_PRICE( msg.value, _expected_ );
}
address _account_ = _msgSender();
_consumeWhitelist( _account_, PRIVATE_SALE, qty_ );
_mint( _account_, qty_ );
}
function setWhitelist( address adminSigner_ ) public onlyOwner {
_setWhitelist( adminSigner_ );
}
}
文件 2 的 15:Consec_ERC721Batch.sol
pragma solidity 0.8.10;
import "../../interfaces/IERC721Enumerable.sol";
import "../../interfaces/IERC721Metadata.sol";
import "../../interfaces/IERC721Receiver.sol";
import "@openzeppelin/contracts/utils/Context.sol";
abstract contract Consec_ERC721Batch is Context, IERC721Metadata, IERC721Enumerable {
event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed fromAddress, address indexed toAddress);
error IERC721_CALLER_NOT_APPROVED( address tokenOwner, address operator, uint256 tokenId );
error IERC721_NONEXISTANT_TOKEN( uint256 tokenId );
error IERC721_NON_ERC721_RECEIVER( address receiver );
error IERC721_INVALID_APPROVAL( address operator );
error IERC721_INVALID_TRANSFER( address recipient );
error IERC721Enumerable_INDEX_OUT_OF_BOUNDS( uint256 index );
error IERC721Enumerable_OWNER_INDEX_OUT_OF_BOUNDS( address tokenOwner, uint256 index );
uint256 private _nextId = 1;
string public name;
string public symbol;
mapping( uint256 => address ) public getApproved;
mapping( address => mapping( address => bool ) ) private _operatorApprovals;
mapping( uint256 => address ) private _owners;
string private _baseURI;
modifier exists( uint256 tokenId_ ) {
if ( ! _exists( tokenId_ ) ) {
revert IERC721_NONEXISTANT_TOKEN( tokenId_ );
}
_;
}
function _balanceOf( address tokenOwner_ ) internal view virtual returns ( uint256 ) {
if ( tokenOwner_ == address( 0 ) ) {
return 0;
}
uint256 _count_ = 0;
address _currentTokenOwner_;
for ( uint256 i = 1; i < _nextId; ++ i ) {
if ( _exists( i ) ) {
if ( _owners[ i ] != address( 0 ) ) {
_currentTokenOwner_ = _owners[ i ];
}
if ( tokenOwner_ == _currentTokenOwner_ ) {
_count_++;
}
}
}
return _count_;
}
function _checkOnERC721Received( address from_, address to_, uint256 tokenId_, bytes memory data_ ) internal virtual returns ( bool ) {
uint256 _size_;
assembly {
_size_ := extcodesize( to_ )
}
if ( _size_ > 0 ) {
try IERC721Receiver( to_ ).onERC721Received( _msgSender(), from_, tokenId_, data_ ) returns ( bytes4 retval ) {
return retval == IERC721Receiver.onERC721Received.selector;
}
catch ( bytes memory reason ) {
if ( reason.length == 0 ) {
revert IERC721_NON_ERC721_RECEIVER( to_ );
}
else {
assembly {
revert( add( 32, reason ), mload( reason ) )
}
}
}
}
else {
return true;
}
}
function _exists( uint256 tokenId_ ) internal view virtual returns ( bool ) {
if ( tokenId_ == 0 ) {
return false;
}
return tokenId_ < _nextId;
}
function _initERC721Metadata( string memory name_, string memory symbol_, string memory baseURI_ ) internal {
name = name_;
symbol = symbol_;
_baseURI = baseURI_;
}
function _isApprovedForAll( address tokenOwner_, address operator_ ) internal view virtual returns ( bool ) {
return _operatorApprovals[ tokenOwner_ ][ operator_ ];
}
function _isApprovedOrOwner( address tokenOwner_, address operator_, uint256 tokenId_ ) internal view virtual returns ( bool ) {
bool _isApproved_ = operator_ == tokenOwner_ ||
operator_ == getApproved[ tokenId_ ] ||
_isApprovedForAll( tokenOwner_, operator_ );
return _isApproved_;
}
function _mint( address to_, uint256 qty_ ) internal virtual {
uint256 _firstToken_ = _nextId;
uint256 _nextStart_ = _firstToken_ + qty_;
uint256 _lastToken_ = _nextStart_ - 1;
_owners[ _firstToken_ ] = to_;
if ( _lastToken_ > _firstToken_ ) {
_owners[ _lastToken_ ] = to_;
}
_nextId = _nextStart_;
if ( ! _checkOnERC721Received( address( 0 ), to_, _firstToken_, "" ) ) {
revert IERC721_NON_ERC721_RECEIVER( to_ );
}
emit ConsecutiveTransfer( _firstToken_, _lastToken_, address( 0 ), to_ );
}
function _ownerOf( uint256 tokenId_ ) internal view virtual returns ( address ) {
uint256 _tokenId_ = tokenId_;
address _tokenOwner_ = _owners[ _tokenId_ ];
while ( _tokenOwner_ == address( 0 ) ) {
_tokenId_ --;
_tokenOwner_ = _owners[ _tokenId_ ];
}
return _tokenOwner_;
}
function _setBaseURI( string memory baseURI_ ) internal virtual {
_baseURI = baseURI_;
}
function _totalSupply() internal view virtual returns ( uint256 ) {
return supplyMinted();
}
function _toString( uint256 value ) internal pure returns ( string memory ) {
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 _transfer( address from_, address to_, uint256 tokenId_ ) internal virtual {
getApproved[ tokenId_ ] = address( 0 );
uint256 _previousId_ = tokenId_ > 1 ? tokenId_ - 1 : 1;
uint256 _nextId_ = tokenId_ + 1;
bool _previousShouldUpdate_ = _previousId_ < tokenId_ &&
_exists( _previousId_ ) &&
_owners[ _previousId_ ] == address( 0 );
bool _nextShouldUpdate_ = _exists( _nextId_ ) &&
_owners[ _nextId_ ] == address( 0 );
if ( _previousShouldUpdate_ ) {
_owners[ _previousId_ ] = from_;
}
if ( _nextShouldUpdate_ ) {
_owners[ _nextId_ ] = from_;
}
_owners[ tokenId_ ] = to_;
emit Transfer( from_, to_, tokenId_ );
}
function approve( address to_, uint256 tokenId_ ) public virtual exists( tokenId_ ) {
address _operator_ = _msgSender();
address _tokenOwner_ = _ownerOf( tokenId_ );
bool _isApproved_ = _isApprovedOrOwner( _tokenOwner_, _operator_, tokenId_ );
if ( ! _isApproved_ ) {
revert IERC721_CALLER_NOT_APPROVED( _tokenOwner_, _operator_, tokenId_ );
}
if ( to_ == _tokenOwner_ ) {
revert IERC721_INVALID_APPROVAL( to_ );
}
getApproved[ tokenId_ ] = to_;
emit Approval( _tokenOwner_, to_, tokenId_ );
}
function safeTransferFrom( address, address to_, uint256 tokenId_ ) public virtual exists( tokenId_ ) {
address _operator_ = _msgSender();
address _tokenOwner_ = _ownerOf( tokenId_ );
bool _isApproved_ = _isApprovedOrOwner( _tokenOwner_, _operator_, tokenId_ );
if ( ! _isApproved_ ) {
revert IERC721_CALLER_NOT_APPROVED( _tokenOwner_, _operator_, tokenId_ );
}
if ( to_ == address( 0 ) ) {
revert IERC721_INVALID_TRANSFER( to_ );
}
_transfer( _tokenOwner_, to_, tokenId_ );
if ( ! _checkOnERC721Received( _tokenOwner_, to_, tokenId_, "" ) ) {
revert IERC721_NON_ERC721_RECEIVER( to_ );
}
}
function safeTransferFrom( address, address to_, uint256 tokenId_, bytes calldata data_ ) public virtual exists( tokenId_ ) {
address _operator_ = _msgSender();
address _tokenOwner_ = _ownerOf( tokenId_ );
bool _isApproved_ = _isApprovedOrOwner( _tokenOwner_, _operator_, tokenId_ );
if ( ! _isApproved_ ) {
revert IERC721_CALLER_NOT_APPROVED( _tokenOwner_, _operator_, tokenId_ );
}
if ( to_ == address( 0 ) ) {
revert IERC721_INVALID_TRANSFER( to_ );
}
_transfer( _tokenOwner_, to_, tokenId_ );
if ( ! _checkOnERC721Received( _tokenOwner_, to_, tokenId_, data_ ) ) {
revert IERC721_NON_ERC721_RECEIVER( to_ );
}
}
function setApprovalForAll( address operator_, bool approved_ ) public virtual override {
address _account_ = _msgSender();
if ( operator_ == _account_ ) {
revert IERC721_INVALID_APPROVAL( operator_ );
}
_operatorApprovals[ _account_ ][ operator_ ] = approved_;
emit ApprovalForAll( _account_, operator_, approved_ );
}
function transferFrom( address, address to_, uint256 tokenId_ ) public virtual exists( tokenId_ ) {
address _operator_ = _msgSender();
address _tokenOwner_ = _ownerOf( tokenId_ );
bool _isApproved_ = _isApprovedOrOwner( _tokenOwner_, _operator_, tokenId_ );
if ( ! _isApproved_ ) {
revert IERC721_CALLER_NOT_APPROVED( _tokenOwner_, _operator_, tokenId_ );
}
if ( to_ == address( 0 ) ) {
revert IERC721_INVALID_TRANSFER( to_ );
}
_transfer( _tokenOwner_, to_, tokenId_ );
}
function balanceOf( address tokenOwner_ ) public view virtual returns ( uint256 ) {
return _balanceOf( tokenOwner_ );
}
function isApprovedForAll( address tokenOwner_, address operator_ ) public view virtual returns ( bool ) {
return _isApprovedForAll( tokenOwner_, operator_ );
}
function ownerOf( uint256 tokenId_ ) public view virtual exists( tokenId_ ) returns ( address ) {
return _ownerOf( tokenId_ );
}
function supplyMinted() public view virtual returns ( uint256 ) {
return _nextId - 1;
}
function supportsInterface( bytes4 interfaceId_ ) public view virtual override returns ( bool ) {
return
interfaceId_ == type( IERC721Enumerable ).interfaceId ||
interfaceId_ == type( IERC721Metadata ).interfaceId ||
interfaceId_ == type( IERC721 ).interfaceId ||
interfaceId_ == type( IERC165 ).interfaceId;
}
function tokenByIndex( uint256 index_ ) public view virtual override returns ( uint256 ) {
if ( index_ >= supplyMinted() ) {
revert IERC721Enumerable_INDEX_OUT_OF_BOUNDS( index_ );
}
return index_;
}
function tokenOfOwnerByIndex( address tokenOwner_, uint256 index_ ) public view virtual override returns ( uint256 tokenId ) {
if ( index_ >= _balanceOf( tokenOwner_ ) ) {
revert IERC721Enumerable_OWNER_INDEX_OUT_OF_BOUNDS( tokenOwner_, index_ );
}
uint256 _count_ = 0;
for ( uint256 i = 1; i < _nextId; i++ ) {
if ( _exists( i ) && tokenOwner_ == _ownerOf( i ) ) {
if ( index_ == _count_ ) {
return i;
}
_count_++;
}
}
}
function tokenURI( uint256 tokenId_ ) public view virtual override exists( tokenId_ ) returns ( string memory ) {
return bytes( _baseURI ).length > 0 ? string( abi.encodePacked( _baseURI, _toString( tokenId_ ) ) ) : _toString( tokenId_ );
}
function totalSupply() public view virtual override returns ( uint256 ) {
return _totalSupply();
}
}
文件 3 的 15:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 4 的 15:ERC2981Base.sol
pragma solidity 0.8.10;
import "../interfaces/IERC2981.sol";
import "../interfaces/IERC165.sol";
abstract contract ERC2981Base is IERC165, IERC2981 {
error IERC2981_INVALID_ROYALTIES( uint256 royaltyRate, uint256 royaltyBase );
uint private constant ROYALTY_BASE = 10000;
uint256 private _royaltyRate;
address private _royaltyRecipient;
function _initERC2981Base( address royaltyRecipient_, uint256 royaltyRate_ ) internal {
_setRoyaltyInfo( royaltyRecipient_, royaltyRate_ );
}
function royaltyInfo( uint256, uint256 salePrice_ ) public view virtual override returns ( address, uint256 ) {
if ( salePrice_ == 0 || _royaltyRate == 0 ) {
return ( _royaltyRecipient, 0 );
}
uint256 _royaltyAmount_ = _royaltyRate * salePrice_ / ROYALTY_BASE;
return ( _royaltyRecipient, _royaltyAmount_ );
}
function _setRoyaltyInfo( address royaltyRecipient_, uint256 royaltyRate_ ) internal virtual {
if ( royaltyRate_ > ROYALTY_BASE ) {
revert IERC2981_INVALID_ROYALTIES( royaltyRate_, ROYALTY_BASE );
}
_royaltyRate = royaltyRate_;
_royaltyRecipient = royaltyRecipient_;
}
function supportsInterface( bytes4 interfaceId_ ) public view virtual override returns ( bool ) {
return
interfaceId_ == type( IERC2981 ).interfaceId ||
interfaceId_ == type( IERC165 ).interfaceId;
}
}
文件 5 的 15:IERC165.sol
pragma solidity 0.8.10;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 6 的 15:IERC2981.sol
pragma solidity 0.8.10;
interface IERC2981 {
function royaltyInfo(uint256 _tokenId, uint256 _salePrice) external view returns (address receiver, uint256 royaltyAmount);
}
文件 7 的 15:IERC721.sol
pragma solidity 0.8.10;
import "./IERC165.sol";
interface IERC721 is IERC165 {
event Transfer( address indexed from_, address indexed to_, uint256 indexed tokenId_ );
event Approval( address indexed owner_, address indexed approved_, uint256 indexed tokenId_ );
event ApprovalForAll( address indexed owner_ , address indexed operator_ , bool approved_ );
function approve( address to_, uint256 tokenId_ ) external;
function safeTransferFrom( address from_, address to_, uint256 tokenI_d ) external;
function safeTransferFrom( address from_, address to_, uint256 tokenId_, bytes calldata data_ ) external;
function setApprovalForAll( address operator_, bool approved_ ) external;
function transferFrom( address from_, address to_, uint256 tokenId_ ) external;
function balanceOf( address tokenOwner_ ) external view returns ( uint256 balance );
function getApproved( uint256 tokenId_ ) external view returns ( address operator );
function isApprovedForAll( address tokenOwner_, address operator_ ) external view returns ( bool );
function ownerOf( uint256 tokenId_ ) external view returns ( address owner );
}
文件 8 的 15:IERC721Enumerable.sol
pragma solidity 0.8.10;
import "./IERC721.sol";
interface IERC721Enumerable is IERC721 {
function totalSupply() external view returns ( uint256 );
function tokenOfOwnerByIndex( address owner_, uint256 index_ ) external view returns ( uint256 tokenId );
function tokenByIndex( uint256 index_ ) external view returns ( uint256 );
}
文件 9 的 15:IERC721Metadata.sol
pragma solidity 0.8.10;
import "./IERC721.sol";
interface IERC721Metadata is IERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
文件 10 的 15:IERC721Receiver.sol
pragma solidity 0.8.10;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 11 的 15:IOwnable.sol
pragma solidity 0.8.10;
import "@openzeppelin/contracts/utils/Context.sol";
abstract contract IOwnable is Context {
error IOwnable_NOT_OWNER( address operator );
address private _owner;
event OwnershipTransferred( address indexed previousOwner, address indexed newOwner );
function _initIOwnable( address owner_ ) internal {
_owner = owner_;
}
function owner() public view virtual returns ( address ) {
return _owner;
}
modifier onlyOwner() {
address _sender_ = _msgSender();
if ( owner() != _sender_ ) {
revert IOwnable_NOT_OWNER( _sender_ );
}
_;
}
function transferOwnership( address newOwner_ ) public virtual onlyOwner {
address _oldOwner_ = _owner;
_owner = newOwner_;
emit OwnershipTransferred( _oldOwner_, newOwner_ );
}
}
文件 12 的 15:IPausable.sol
pragma solidity 0.8.10;
abstract contract IPausable {
uint8 constant CLOSED = 0;
uint8 constant OPEN = 1;
error IPausable_INCORRECT_STATE( uint8 currentState );
error IPausable_INVALID_STATE( uint8 newState );
uint8 private _contractState;
event ContractStateChanged( uint8 indexed previousState, uint8 indexed newState );
function _setPauseState( uint8 newState_ ) internal virtual {
uint8 _previousState_ = _contractState;
_contractState = newState_;
emit ContractStateChanged( _previousState_, newState_ );
}
function getPauseState() public virtual view returns ( uint8 ) {
return _contractState;
}
modifier isClosed {
if ( _contractState != CLOSED ) {
revert IPausable_INCORRECT_STATE( _contractState );
}
_;
}
modifier isNotClosed {
if ( _contractState == CLOSED ) {
revert IPausable_INCORRECT_STATE( _contractState );
}
_;
}
modifier isOpen {
if ( _contractState != OPEN ) {
revert IPausable_INCORRECT_STATE( _contractState );
}
_;
}
modifier isNotOpen {
if ( _contractState == OPEN ) {
revert IPausable_INCORRECT_STATE( _contractState );
}
_;
}
}
文件 13 的 15:ITradable.sol
pragma solidity 0.8.10;
contract OwnableDelegateProxy {}
contract ProxyRegistry {
mapping( address => OwnableDelegateProxy ) public proxies;
}
abstract contract ITradable {
address[] internal _proxyRegistries;
function _addProxyRegistry( address proxyRegistryAddress_ ) internal {
uint256 _index_ = _proxyRegistries.length;
while ( _index_ > 0 ) {
unchecked {
_index_ --;
}
if ( _proxyRegistries[ _index_ ] == proxyRegistryAddress_ ) {
return;
}
}
_proxyRegistries.push( proxyRegistryAddress_ );
}
function _removeProxyRegistry( address proxyRegistryAddress_ ) internal {
uint256 _len_ = _proxyRegistries.length;
uint256 _index_ = _len_;
while ( _index_ > 0 ) {
unchecked {
_index_ --;
}
if ( _proxyRegistries[ _index_ ] == proxyRegistryAddress_ ) {
if ( _index_ + 1 != _len_ ) {
_proxyRegistries[ _index_ ] = _proxyRegistries[ _len_ - 1 ];
}
_proxyRegistries.pop();
}
return;
}
}
function _isRegisteredProxy( address tokenOwner_, address operator_ ) internal view returns ( bool ) {
uint256 _index_ = _proxyRegistries.length;
while ( _index_ > 0 ) {
unchecked {
_index_ --;
}
ProxyRegistry _proxyRegistry_ = ProxyRegistry( _proxyRegistries[ _index_ ] );
if ( address( _proxyRegistry_.proxies( tokenOwner_ ) ) == operator_ ) {
return true;
}
}
return false;
}
}
文件 14 的 15:IWhitelistable_ECDSA.sol
pragma solidity 0.8.10;
abstract contract IWhitelistable_ECDSA {
uint8 public constant DEFAULT_WHITELIST = 1;
error IWhitelistable_NOT_SET();
error IWhitelistable_CONSUMED( address account );
error IWhitelistable_FORBIDDEN( address account );
struct Proof {
bytes32 r;
bytes32 s;
uint8 v;
}
address private _adminSigner;
mapping( uint8 => mapping ( address => uint256 ) ) private _consumed;
modifier isWhitelisted( address account_, uint8 whitelistType_, uint256 alloted_, Proof memory proof_, uint256 qty_ ) {
uint256 _allowed_ = checkWhitelistAllowance( account_, whitelistType_, alloted_, proof_ );
if ( _allowed_ < qty_ ) {
revert IWhitelistable_FORBIDDEN( account_ );
}
_;
}
function _setWhitelist( address adminSigner_ ) internal virtual {
_adminSigner = adminSigner_;
}
function checkWhitelistAllowance( address account_, uint8 whitelistType_, uint256 alloted_, Proof memory proof_ ) public view returns ( uint256 ) {
if ( _adminSigner == address( 0 ) ) {
revert IWhitelistable_NOT_SET();
}
if ( _consumed[ whitelistType_ ][ account_ ] >= alloted_ ) {
revert IWhitelistable_CONSUMED( account_ );
}
bytes32 _digest_ = keccak256( abi.encode( whitelistType_, alloted_, account_ ) );
if ( ! _validateProof( _digest_, proof_ ) ) {
revert IWhitelistable_FORBIDDEN( account_ );
}
return alloted_ - _consumed[ whitelistType_ ][ account_ ];
}
function _validateProof( bytes32 digest_, Proof memory proof_ ) private view returns ( bool ) {
address _signer_ = ecrecover( digest_, proof_.v, proof_.r, proof_.s );
return _signer_ == _adminSigner;
}
function _consumeWhitelist( address account_, uint8 whitelistType_, uint256 qty_ ) internal {
unchecked {
_consumed[ whitelistType_ ][ account_ ] += qty_;
}
}
}
文件 15 的 15:NFTBaseC.sol
pragma solidity 0.8.10;
import '../tokens/ERC721/Consec_ERC721Batch.sol';
import '../utils/IOwnable.sol';
import '../utils/IPausable.sol';
import '../utils/ITradable.sol';
import '../utils/ERC2981Base.sol';
abstract contract NFTBaseC is Consec_ERC721Batch, IOwnable, IPausable, ITradable, ERC2981Base {
error NFT_ARRAY_LENGTH_MISMATCH( uint256 len1, uint256 len2 );
error NFT_INCORRECT_PRICE( uint256 amountReceived, uint256 amountExpected );
error NFT_INVALID_QTY();
error NFT_INVALID_SHARE();
error NFT_INVALID_TEAM_MEMBER( address account );
error NFT_MAX_BATCH( uint256 qtyRequested, uint256 maxBatch );
error NFT_MAX_RESERVE( uint256 qtyRequested, uint256 reserveLeft );
error NFT_MAX_SUPPLY( uint256 qtyRequested, uint256 remainingSupply );
error NFT_MISSING_SHARES( uint256 missingShares );
error NFT_NO_ETHER_BALANCE();
error NFT_ETHER_TRANSFER_FAIL( address to, uint256 amount );
event PaymentReleased( address to, uint256 amount );
uint256 private constant SHARE_BASE = 10000;
uint256 public MAX_SUPPLY;
uint256 public MAX_BATCH;
uint256 public SALE_PRICE;
uint256 internal _reserve;
uint256[] private _teamShares;
address[] private _teamAddresses;
modifier validateAmount( uint256 qty_ ) {
if ( qty_ == 0 ) {
revert NFT_INVALID_QTY();
}
_;
}
function _initNFTBaseC (
uint256 reserve_,
uint256 maxBatch_,
uint256 maxSupply_,
uint256 salePrice_,
uint256 royaltyRate_,
string memory name_,
string memory symbol_,
string memory baseURI_
) internal {
_initERC721Metadata( name_, symbol_, baseURI_ );
_initIOwnable( _msgSender() );
_initERC2981Base( _msgSender(), royaltyRate_ );
MAX_SUPPLY = maxSupply_;
MAX_BATCH = maxBatch_;
SALE_PRICE = salePrice_;
_reserve = reserve_;
}
function _isApprovedForAll( address tokenOwner_, address operator_ ) internal view virtual override(Consec_ERC721Batch) returns ( bool ) {
return _isRegisteredProxy( tokenOwner_, operator_ ) ||
super._isApprovedForAll( tokenOwner_, operator_ );
}
function _isContract( address addr_ ) internal view returns ( bool ) {
uint size;
assembly {
size := extcodesize( addr_ )
}
return size > 0;
}
function mintPublic( uint256 qty_ ) public payable validateAmount( qty_ ) isOpen {
if ( qty_ > MAX_BATCH ) {
revert NFT_MAX_BATCH( qty_, MAX_BATCH );
}
uint256 _remainingSupply_ = MAX_SUPPLY - _reserve - supplyMinted();
if ( qty_ > _remainingSupply_ ) {
revert NFT_MAX_SUPPLY( qty_, _remainingSupply_ );
}
uint256 _expected_ = qty_ * SALE_PRICE;
if ( _expected_ != msg.value ) {
revert NFT_INCORRECT_PRICE( msg.value, _expected_ );
}
_mint( _msgSender(), qty_ );
}
function addProxyRegistry( address proxyRegistryAddress_ ) external onlyOwner {
_addProxyRegistry( proxyRegistryAddress_ );
}
function removeProxyRegistry( address proxyRegistryAddress_ ) external onlyOwner {
_removeProxyRegistry( proxyRegistryAddress_ );
}
function airdrop( address[] memory accounts_, uint256[] memory amounts_ ) public onlyOwner {
uint256 _accountsLen_ = accounts_.length;
uint256 _amountsLen_ = amounts_.length;
if ( _accountsLen_ != _amountsLen_ ) {
revert NFT_ARRAY_LENGTH_MISMATCH( _accountsLen_, _amountsLen_ );
}
uint256 _totalQty_;
for ( uint256 i = _amountsLen_; i > 0; i -- ) {
_totalQty_ += amounts_[ i - 1 ];
}
if ( _totalQty_ > _reserve ) {
revert NFT_MAX_RESERVE( _totalQty_, _reserve );
}
unchecked {
_reserve -= _totalQty_;
}
for ( uint256 i; i < _accountsLen_; i ++ ) {
_mint( accounts_[ i ], amounts_[ i ] );
}
}
function setBaseURI( string memory baseURI_ ) public onlyOwner {
_setBaseURI( baseURI_ );
}
function setRoyaltyInfo( address royaltyRecipient_, uint256 royaltyRate_ ) external onlyOwner {
_setRoyaltyInfo( royaltyRecipient_, royaltyRate_ );
}
function setPauseState( uint8 newState_ ) external onlyOwner {
_setPauseState( newState_ );
}
function withdraw() public onlyOwner {
uint256 _balance_ = address( this ).balance;
if ( _balance_ == 0 ) {
revert NFT_NO_ETHER_BALANCE();
}
address _recipient_ = payable( _msgSender() );
( bool _success_, ) = _recipient_.call{ value: _balance_ }( "" );
if ( ! _success_ ) {
revert NFT_ETHER_TRANSFER_FAIL( _recipient_, _balance_ );
}
emit PaymentReleased( _recipient_, _balance_ );
}
function supportsInterface( bytes4 interfaceId_ ) public view virtual override(Consec_ERC721Batch, ERC2981Base) returns ( bool ) {
return ERC2981Base.supportsInterface( interfaceId_ ) ||
Consec_ERC721Batch.supportsInterface( interfaceId_ );
}
}
{
"compilationTarget": {
"contracts/BBCLUB/BBCLUB.sol": "BBCLUB"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 10000
},
"remappings": []
}
[{"inputs":[{"internalType":"uint256","name":"reserve_","type":"uint256"},{"internalType":"uint256","name":"maxBatch_","type":"uint256"},{"internalType":"uint256","name":"maxSupply_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"royaltyRate","type":"uint256"},{"internalType":"uint256","name":"royaltyBase","type":"uint256"}],"name":"IERC2981_INVALID_ROYALTIES","type":"error"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"IERC721Enumerable_INDEX_OUT_OF_BOUNDS","type":"error"},{"inputs":[{"internalType":"address","name":"tokenOwner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"IERC721Enumerable_OWNER_INDEX_OUT_OF_BOUNDS","type":"error"},{"inputs":[{"internalType":"address","name":"tokenOwner","type":"address"},{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"IERC721_CALLER_NOT_APPROVED","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"IERC721_INVALID_APPROVAL","type":"error"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"IERC721_INVALID_TRANSFER","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"IERC721_NONEXISTANT_TOKEN","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"IERC721_NON_ERC721_RECEIVER","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"IOwnable_NOT_OWNER","type":"error"},{"inputs":[{"internalType":"uint8","name":"currentState","type":"uint8"}],"name":"IPausable_INCORRECT_STATE","type":"error"},{"inputs":[{"internalType":"uint8","name":"newState","type":"uint8"}],"name":"IPausable_INVALID_STATE","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"IWhitelistable_CONSUMED","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"IWhitelistable_FORBIDDEN","type":"error"},{"inputs":[],"name":"IWhitelistable_NOT_SET","type":"error"},{"inputs":[{"internalType":"uint256","name":"len1","type":"uint256"},{"internalType":"uint256","name":"len2","type":"uint256"}],"name":"NFT_ARRAY_LENGTH_MISMATCH","type":"error"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NFT_ETHER_TRANSFER_FAIL","type":"error"},{"inputs":[{"internalType":"uint256","name":"amountReceived","type":"uint256"},{"internalType":"uint256","name":"amountExpected","type":"uint256"}],"name":"NFT_INCORRECT_PRICE","type":"error"},{"inputs":[],"name":"NFT_INVALID_QTY","type":"error"},{"inputs":[],"name":"NFT_INVALID_SHARE","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"NFT_INVALID_TEAM_MEMBER","type":"error"},{"inputs":[{"internalType":"uint256","name":"qtyRequested","type":"uint256"},{"internalType":"uint256","name":"maxBatch","type":"uint256"}],"name":"NFT_MAX_BATCH","type":"error"},{"inputs":[{"internalType":"uint256","name":"qtyRequested","type":"uint256"},{"internalType":"uint256","name":"reserveLeft","type":"uint256"}],"name":"NFT_MAX_RESERVE","type":"error"},{"inputs":[{"internalType":"uint256","name":"qtyRequested","type":"uint256"},{"internalType":"uint256","name":"remainingSupply","type":"uint256"}],"name":"NFT_MAX_SUPPLY","type":"error"},{"inputs":[{"internalType":"uint256","name":"missingShares","type":"uint256"}],"name":"NFT_MISSING_SHARES","type":"error"},{"inputs":[],"name":"NFT_NO_ETHER_BALANCE","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":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"fromAddress","type":"address"},{"indexed":true,"internalType":"address","name":"toAddress","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint8","name":"previousState","type":"uint8"},{"indexed":true,"internalType":"uint8","name":"newState","type":"uint8"}],"name":"ContractStateChanged","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":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReleased","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"},{"inputs":[],"name":"CLAIM","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_WHITELIST","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_BATCH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRE_SALE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRIVATE_SALE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SALE_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"proxyRegistryAddress_","type":"address"}],"name":"addProxyRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts_","type":"address[]"},{"internalType":"uint256[]","name":"amounts_","type":"uint256[]"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOwner_","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"},{"internalType":"uint8","name":"whitelistType_","type":"uint8"},{"internalType":"uint256","name":"alloted_","type":"uint256"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"}],"internalType":"struct IWhitelistable_ECDSA.Proof","name":"proof_","type":"tuple"}],"name":"checkWhitelistAllowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"alloted_","type":"uint256"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"}],"internalType":"struct IWhitelistable_ECDSA.Proof","name":"proof_","type":"tuple"},{"internalType":"uint256","name":"qty_","type":"uint256"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPauseState","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOwner_","type":"address"},{"internalType":"address","name":"operator_","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"alloted_","type":"uint256"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"}],"internalType":"struct IWhitelistable_ECDSA.Proof","name":"proof_","type":"tuple"},{"internalType":"uint256","name":"qty_","type":"uint256"}],"name":"mintPreSale","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"alloted_","type":"uint256"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"}],"internalType":"struct IWhitelistable_ECDSA.Proof","name":"proof_","type":"tuple"},{"internalType":"uint256","name":"qty_","type":"uint256"}],"name":"mintPrivateSale","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"qty_","type":"uint256"}],"name":"mintPublic","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"proxyRegistryAddress_","type":"address"}],"name":"removeProxyRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"salePrice_","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","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":"","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"},{"internalType":"bytes","name":"data_","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator_","type":"address"},{"internalType":"bool","name":"approved_","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI_","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"newState_","type":"uint8"}],"name":"setPauseState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"royaltyRecipient_","type":"address"},{"internalType":"uint256","name":"royaltyRate_","type":"uint256"}],"name":"setRoyaltyInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"adminSigner_","type":"address"}],"name":"setWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"supplyMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId_","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index_","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOwner_","type":"address"},{"internalType":"uint256","name":"index_","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"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":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner_","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]