编译器
0.8.23+commit.f704f362
文件 1 的 12:Context.sol
pragma solidity ^0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 2 的 12:ERC165.sol
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 3 的 12:ERC2981.sol
pragma solidity ^0.8.20;
import {IERC2981} from "../../interfaces/IERC2981.sol";
import {IERC165, ERC165} from "../../utils/introspection/ERC165.sol";
abstract contract ERC2981 is IERC2981, ERC165 {
struct RoyaltyInfo {
address receiver;
uint96 royaltyFraction;
}
RoyaltyInfo private _defaultRoyaltyInfo;
mapping(uint256 tokenId => RoyaltyInfo) private _tokenRoyaltyInfo;
error ERC2981InvalidDefaultRoyalty(uint256 numerator, uint256 denominator);
error ERC2981InvalidDefaultRoyaltyReceiver(address receiver);
error ERC2981InvalidTokenRoyalty(uint256 tokenId, uint256 numerator, uint256 denominator);
error ERC2981InvalidTokenRoyaltyReceiver(uint256 tokenId, address receiver);
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
}
function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual returns (address, uint256) {
RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId];
if (royalty.receiver == address(0)) {
royalty = _defaultRoyaltyInfo;
}
uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator();
return (royalty.receiver, royaltyAmount);
}
function _feeDenominator() internal pure virtual returns (uint96) {
return 10000;
}
function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
uint256 denominator = _feeDenominator();
if (feeNumerator > denominator) {
revert ERC2981InvalidDefaultRoyalty(feeNumerator, denominator);
}
if (receiver == address(0)) {
revert ERC2981InvalidDefaultRoyaltyReceiver(address(0));
}
_defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
}
function _deleteDefaultRoyalty() internal virtual {
delete _defaultRoyaltyInfo;
}
function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {
uint256 denominator = _feeDenominator();
if (feeNumerator > denominator) {
revert ERC2981InvalidTokenRoyalty(tokenId, feeNumerator, denominator);
}
if (receiver == address(0)) {
revert ERC2981InvalidTokenRoyaltyReceiver(tokenId, address(0));
}
_tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
}
function _resetTokenRoyalty(uint256 tokenId) internal virtual {
delete _tokenRoyaltyInfo[tokenId];
}
}
文件 4 的 12:ERC721.sol
pragma solidity >=0.8.0;
abstract contract ERC721 {
event Transfer(address indexed from, address indexed to, uint256 indexed id);
event Approval(address indexed owner, address indexed spender, uint256 indexed id);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
string public name;
string public symbol;
function tokenURI(uint256 id) public view virtual returns (string memory);
mapping(uint256 => address) internal _ownerOf;
mapping(address => uint256) internal _balanceOf;
function ownerOf(uint256 id) public view virtual returns (address owner) {
require((owner = _ownerOf[id]) != address(0), "NOT_MINTED");
}
function balanceOf(address owner) public view virtual returns (uint256) {
require(owner != address(0), "ZERO_ADDRESS");
return _balanceOf[owner];
}
mapping(uint256 => address) public getApproved;
mapping(address => mapping(address => bool)) public isApprovedForAll;
constructor(string memory _name, string memory _symbol) {
name = _name;
symbol = _symbol;
}
function approve(address spender, uint256 id) public virtual {
address owner = _ownerOf[id];
require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED");
getApproved[id] = spender;
emit Approval(owner, spender, id);
}
function setApprovalForAll(address operator, bool approved) public virtual {
isApprovedForAll[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
function transferFrom(
address from,
address to,
uint256 id
) public virtual {
require(from == _ownerOf[id], "WRONG_FROM");
require(to != address(0), "INVALID_RECIPIENT");
require(
msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],
"NOT_AUTHORIZED"
);
unchecked {
_balanceOf[from]--;
_balanceOf[to]++;
}
_ownerOf[id] = to;
delete getApproved[id];
emit Transfer(from, to, id);
}
function safeTransferFrom(
address from,
address to,
uint256 id
) public virtual {
transferFrom(from, to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
function safeTransferFrom(
address from,
address to,
uint256 id,
bytes calldata data
) public virtual {
transferFrom(from, to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return
interfaceId == 0x01ffc9a7 ||
interfaceId == 0x80ac58cd ||
interfaceId == 0x5b5e139f;
}
function _mint(address to, uint256 id) internal virtual {
require(to != address(0), "INVALID_RECIPIENT");
require(_ownerOf[id] == address(0), "ALREADY_MINTED");
unchecked {
_balanceOf[to]++;
}
_ownerOf[id] = to;
emit Transfer(address(0), to, id);
}
function _burn(uint256 id) internal virtual {
address owner = _ownerOf[id];
require(owner != address(0), "NOT_MINTED");
unchecked {
_balanceOf[owner]--;
}
delete _ownerOf[id];
delete getApproved[id];
emit Transfer(owner, address(0), id);
}
function _safeMint(address to, uint256 id) internal virtual {
_mint(to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
function _safeMint(
address to,
uint256 id,
bytes memory data
) internal virtual {
_mint(to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
}
abstract contract ERC721TokenReceiver {
function onERC721Received(
address,
address,
uint256,
bytes calldata
) external virtual returns (bytes4) {
return ERC721TokenReceiver.onERC721Received.selector;
}
}
文件 5 的 12:IERC165.sol
pragma solidity ^0.8.20;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 6 的 12:IERC20.sol
pragma solidity ^0.8.20;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
文件 7 的 12:IERC2981.sol
pragma solidity ^0.8.20;
import {IERC165} from "../utils/introspection/IERC165.sol";
interface IERC2981 is IERC165 {
function royaltyInfo(
uint256 tokenId,
uint256 salePrice
) external view returns (address receiver, uint256 royaltyAmount);
}
文件 8 的 12:LibString.sol
pragma solidity >=0.8.0;
library LibString {
function toString(int256 value) internal pure returns (string memory str) {
if (value >= 0) return toString(uint256(value));
unchecked {
str = toString(uint256(-value));
assembly {
let length := mload(str)
mstore(str, 45)
str := sub(str, 1)
mstore(str, add(length, 1))
}
}
}
function toString(uint256 value) internal pure returns (string memory str) {
assembly {
let newFreeMemoryPointer := add(mload(0x40), 160)
mstore(0x40, newFreeMemoryPointer)
str := sub(newFreeMemoryPointer, 32)
mstore(str, 0)
let end := str
for { let temp := value } 1 {} {
str := sub(str, 1)
mstore8(str, add(48, mod(temp, 10)))
temp := div(temp, 10)
if iszero(temp) { break }
}
let length := sub(end, str)
str := sub(str, 32)
mstore(str, length)
}
}
}
文件 9 的 12:MerkleProofLib.sol
pragma solidity >=0.8.0;
library MerkleProofLib {
function verify(
bytes32[] calldata proof,
bytes32 root,
bytes32 leaf
) internal pure returns (bool isValid) {
assembly {
if proof.length {
let end := add(proof.offset, shl(5, proof.length))
let offset := proof.offset
for {} 1 {} {
let leafSlot := shl(5, gt(leaf, calldataload(offset)))
mstore(leafSlot, leaf)
mstore(xor(leafSlot, 32), calldataload(offset))
leaf := keccak256(0, 64)
offset := add(offset, 32)
if iszero(lt(offset, end)) { break }
}
}
isValid := eq(leaf, root)
}
}
}
文件 10 的 12:Ownable.sol
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
error OwnableUnauthorizedAccount(address account);
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 11 的 12:ReentrancyGuard.sol
pragma solidity >=0.8.0;
abstract contract ReentrancyGuard {
uint256 private locked = 1;
modifier nonReentrant() virtual {
require(locked == 1, "REENTRANCY");
locked = 2;
_;
locked = 1;
}
}
文件 12 的 12:Workstation95.sol
pragma solidity ^0.8.23;
import {ERC721} from "solmate/tokens/ERC721.sol";
import {LibString} from "solmate/utils/LibString.sol";
import {MerkleProofLib} from "solmate/utils/MerkleProofLib.sol";
import {ReentrancyGuard} from "solmate/utils/ReentrancyGuard.sol";
import {Ownable} from "openzeppelin-contracts/contracts/access/Ownable.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {ERC2981} from "@openzeppelin/contracts/token/common/ERC2981.sol";
contract Workstation95 is ERC721, ERC2981, Ownable, ReentrancyGuard {
uint256 public maxSupply;
uint256 public totalSupply;
uint256 public stdPrice;
uint256 public discountPrice;
uint256 public discountsPerCollection;
uint256 public lastBulkMintedId = 1;
string public baseURI;
bool public isSaleActive = false;
mapping(uint256 => uint256) public mintedBitmap;
mapping(uint256 => uint256) public frameOnlyIdsBitmap;
mapping(address => uint256) public discountedCredits;
mapping(address => uint256) public stdCredits;
mapping(address => uint256) public depositedEth;
mapping(address => uint256) public claimedDiscounted;
mapping(address => uint256) public claimedStd;
mapping(address => uint256) public directPaidDiscounted;
mapping(address => uint256) public directPaidStd;
uint256 public totalDepositedUnspentETH;
uint256 public totalClaimedCount;
uint256 public ethTowardsMints;
uint256 frameOnlyCount;
bytes32 private merkleRoot;
address public paymentsRecipient;
error MaxMintableLimitReached();
error TokenIdOutOfRange();
error TokenAlreadyMinted();
error NoBalanceToWithdraw();
error TransferFailed();
error InsufficientBalance();
error IncorrectEth(uint256 expected, uint256 received);
error ShouldBeGreaterThanZero();
error NotEnoughTokensAvailableToMint();
error SaleNotActive();
error Nope();
error ExceedsAllowedDiscounts(uint256 allowed, uint256 requested);
modifier saleActive() {
if (!isSaleActive) {
revert SaleNotActive();
}
_;
}
constructor(
address initialOwner,
address _paymentsRecipient,
string memory _baseURI,
uint256 _stdPrice,
uint256 _discountPrice,
uint256 _maxSupply,
bytes32 _merkleRoot,
uint256 _discountsPerCollection
) ERC721("Workstation95", "WS95") Ownable(initialOwner) {
baseURI = _baseURI;
stdPrice = _stdPrice;
discountPrice = _discountPrice;
maxSupply = _maxSupply;
merkleRoot = _merkleRoot;
discountsPerCollection = _discountsPerCollection;
paymentsRecipient = _paymentsRecipient;
_setDefaultRoyalty(_paymentsRecipient, 1000);
}
function deposit(uint256 collectionPresenceCount, bytes32[] calldata merkleProof, uint256 depositedDiscountQty, uint256 depositedStdQty) public saleActive payable {
if (msg.value == 0) {
revert ShouldBeGreaterThanZero();
}
uint256 availableDiscounts = availableDiscountQuantity(msg.sender, collectionPresenceCount, merkleProof);
if (depositedDiscountQty > availableDiscounts) {
revert ExceedsAllowedDiscounts(availableDiscounts, depositedDiscountQty);
}
if (msg.value != (depositedDiscountQty * discountPrice) + (depositedStdQty * stdPrice)) {
revert IncorrectEth((depositedDiscountQty * discountPrice) + (depositedStdQty * stdPrice), msg.value);
}
discountedCredits[msg.sender] += depositedDiscountQty;
stdCredits[msg.sender] += depositedStdQty;
depositedEth[msg.sender] += msg.value;
totalDepositedUnspentETH += msg.value;
}
function withdrawBalance() nonReentrant public {
uint256 spentAmount = calcSpentDeposits(msg.sender);
uint amount = depositedEth[msg.sender] - spentAmount;
if (amount == 0) {
revert NoBalanceToWithdraw();
}
discountedCredits[msg.sender] = 0;
stdCredits[msg.sender] = 0;
depositedEth[msg.sender] -= amount;
totalDepositedUnspentETH -= amount;
(bool success, ) = msg.sender.call{value: amount}("");
if (!success) {
revert TransferFailed();
}
}
function availableDiscountQuantity(address addr, uint256 collectionPresenceCount, bytes32[] calldata merkleProof) public view returns (uint256) {
bytes32 leaf = keccak256(abi.encodePacked(addr, collectionPresenceCount));
if (MerkleProofLib.verify(merkleProof, merkleRoot, leaf)) {
return (collectionPresenceCount * discountsPerCollection) - claimedDiscounted[addr] - directPaidDiscounted[addr];
} else {
return 0;
}
}
function eligibleDiscountQuantity(address addr, uint256 collectionPresenceCount, bytes32[] calldata merkleProof) public view returns (uint256) {
bytes32 leaf = keccak256(abi.encodePacked(addr, collectionPresenceCount));
if (MerkleProofLib.verify(merkleProof, merkleRoot, leaf)) {
return (collectionPresenceCount * discountsPerCollection);
} else {
return 0;
}
}
function discountQuantities(address addr, uint256 collectionPresenceCount, bytes32[] calldata merkleProof) public view returns (uint256 total, uint256 available) {
total = eligibleDiscountQuantity(addr, collectionPresenceCount, merkleProof);
available = availableDiscountQuantity(addr, collectionPresenceCount, merkleProof);
return (total, available);
}
function totalActiveCredits(address addr) public view returns (uint256) {
return discountedCredits[addr] + stdCredits[addr];
}
function setMerkleRoot(bytes32 root) external onlyOwner {
merkleRoot = root;
}
function updateMaxSupply(uint newMaxSupply) external onlyOwner {
maxSupply = newMaxSupply;
}
function updateBaseUri(string memory newBaseUri) external onlyOwner {
baseURI = newBaseUri;
}
function toggleSale() external onlyOwner {
isSaleActive = !isSaleActive;
}
function isMinted(uint tokenId) public view returns (bool) {
if(tokenId < 1 || tokenId > maxSupply) {
return false;
}
uint256 index = tokenId / 256;
uint256 position = tokenId % 256;
uint256 flag = (mintedBitmap[index] >> position) & uint256(1);
return flag == 1;
}
function isFrameOnlyId(uint tokenId) public view returns (bool) {
if(tokenId < 1 || tokenId > maxSupply) {
return false;
}
uint256 index = tokenId / 256;
uint256 position = tokenId % 256;
uint256 flag = (frameOnlyIdsBitmap[index] >> position) & uint256(1);
return flag == 1;
}
function initializeFrameOnlyIds(uint256[] calldata frameOnlyIds) external onlyOwner {
for (uint i = 0; i < frameOnlyIds.length; i++) {
setFrameOnlyId(frameOnlyIds[i]);
}
frameOnlyCount = frameOnlyIds.length;
}
function setFrameOnlyCount(uint256 count) external onlyOwner {
frameOnlyCount = count;
}
function withdrawTeamBalance() public {
if (ethTowardsMints == 0) {
revert NoBalanceToWithdraw();
}
(bool success, ) = payable(paymentsRecipient).call{value: ethTowardsMints}("");
if (!success) {
revert TransferFailed();
}
ethTowardsMints = 0;
}
function mint(address receiver, uint tokenId) public saleActive onlyOwner {
if (totalSupply + 1 > maxSupply) {
revert MaxMintableLimitReached();
}
if(tokenId < 1 || tokenId > maxSupply) {
revert TokenIdOutOfRange();
}
if (isMinted(tokenId)) {
revert TokenAlreadyMinted();
}
if (discountedCredits[receiver] > 0) {
discountedCredits[receiver]--;
claimedDiscounted[receiver]++;
ethTowardsMints += discountPrice;
totalDepositedUnspentETH -= discountPrice;
} else if (stdCredits[receiver] > 0) {
stdCredits[receiver]--;
claimedStd[receiver]++;
ethTowardsMints += stdPrice;
totalDepositedUnspentETH -= stdPrice;
} else {
revert InsufficientBalance();
}
totalClaimedCount++;
_mintToken(receiver, tokenId);
}
function calcSpentDeposits(address addr) public view returns (uint256) {
return (claimedDiscounted[addr] * discountPrice) + (claimedStd[addr] * stdPrice);
}
function setRoyalty(
address receiver,
uint96 feeNumerator
) external onlyOwner {
_setDefaultRoyalty(receiver, feeNumerator);
}
function mintMultipleByQuantity(
uint quantity,
uint256 collectionPresenceCount,
bytes32[] calldata merkleProof,
uint256 discountQty,
uint256 stdQty
) public payable saleActive {
if (quantity == 0) {
revert ShouldBeGreaterThanZero();
}
if (totalSupply + quantity > maxSupply - frameOnlyCount) {
revert MaxMintableLimitReached();
}
if(discountQty + stdQty != quantity){
revert Nope();
}
uint256 rawAvailDiscounts = availableDiscountQuantity(msg.sender, collectionPresenceCount, merkleProof);
uint256 availableDiscounts = rawAvailDiscounts > 0 ? rawAvailDiscounts - discountedCredits[msg.sender] : 0;
if (discountQty > availableDiscounts) {
revert ExceedsAllowedDiscounts(availableDiscounts, discountQty);
}
if (msg.value != (discountQty * discountPrice) + (stdQty * stdPrice)) {
revert IncorrectEth((discountQty * discountPrice) + (stdQty * stdPrice), msg.value);
}
ethTowardsMints += msg.value;
directPaidDiscounted[msg.sender] = directPaidDiscounted[msg.sender] + discountQty;
directPaidStd[msg.sender] = directPaidStd[msg.sender] + stdQty;
uint256 tokensMinted = 0;
uint256 maxId;
for (uint256 i = lastBulkMintedId; tokensMinted < quantity && i <= maxSupply; i++) {
if (!isMinted(i) && !isFrameOnlyId(i)) {
maxId = i;
tokensMinted++;
_mintToken(msg.sender, i);
}
}
lastBulkMintedId = maxId;
if (tokensMinted != quantity) {
revert NotEnoughTokensAvailableToMint();
}
}
function tokenURI(
uint256 tokenId
) public view override returns (string memory) {
require(
isMinted(tokenId),
"ERC721Metadata: URI query for nonexistent token"
);
return string(abi.encodePacked(baseURI, LibString.toString(tokenId), ".json"));
}
function _mintToken(address receiver, uint tokenId) private {
uint256 index = tokenId / 256;
uint256 position = tokenId % 256;
mintedBitmap[index] = mintedBitmap[index] | (uint256(1) << position);
totalSupply++;
_mint(receiver, tokenId);
}
function setFrameOnlyId(uint256 tokenId) public onlyOwner {
uint256 index = tokenId / 256;
uint256 position = tokenId % 256;
frameOnlyIdsBitmap[index] = frameOnlyIdsBitmap[index] | (uint256(1) << position);
}
function withdrawToken(
address tokenAddress,
uint256 amount
) external {
require(
IERC20(tokenAddress).transfer(paymentsRecipient, amount),
"Transfer failed"
);
}
function supportsInterface(
bytes4 interfaceId
) public view virtual override(ERC721, ERC2981) returns (bool) {
return super.supportsInterface(interfaceId);
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
receive() external payable {
ethTowardsMints += msg.value;
}
}
{
"compilationTarget": {
"src/Workstation95.sol": "Workstation95"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":@openzeppelin/=node_modules/@openzeppelin/",
":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
":ERC721A/=lib/ERC721A/contracts/",
":ds-test/=lib/forge-std/lib/ds-test/src/",
":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
":forge-std/=lib/forge-std/src/",
":openzeppelin-contracts/=lib/openzeppelin-contracts/",
":solmate/=lib/solmate/src/"
]
}
[{"inputs":[{"internalType":"address","name":"initialOwner","type":"address"},{"internalType":"address","name":"_paymentsRecipient","type":"address"},{"internalType":"string","name":"_baseURI","type":"string"},{"internalType":"uint256","name":"_stdPrice","type":"uint256"},{"internalType":"uint256","name":"_discountPrice","type":"uint256"},{"internalType":"uint256","name":"_maxSupply","type":"uint256"},{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"},{"internalType":"uint256","name":"_discountsPerCollection","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidDefaultRoyalty","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidDefaultRoyaltyReceiver","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidTokenRoyalty","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidTokenRoyaltyReceiver","type":"error"},{"inputs":[{"internalType":"uint256","name":"allowed","type":"uint256"},{"internalType":"uint256","name":"requested","type":"uint256"}],"name":"ExceedsAllowedDiscounts","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"received","type":"uint256"}],"name":"IncorrectEth","type":"error"},{"inputs":[],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"MaxMintableLimitReached","type":"error"},{"inputs":[],"name":"NoBalanceToWithdraw","type":"error"},{"inputs":[],"name":"Nope","type":"error"},{"inputs":[],"name":"NotEnoughTokensAvailableToMint","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"SaleNotActive","type":"error"},{"inputs":[],"name":"ShouldBeGreaterThanZero","type":"error"},{"inputs":[],"name":"TokenAlreadyMinted","type":"error"},{"inputs":[],"name":"TokenIdOutOfRange","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","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":"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":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"collectionPresenceCount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"availableDiscountQuantity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"calcSpentDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimedDiscounted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimedStd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"collectionPresenceCount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"},{"internalType":"uint256","name":"depositedDiscountQty","type":"uint256"},{"internalType":"uint256","name":"depositedStdQty","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"depositedEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"directPaidDiscounted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"directPaidStd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"discountPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"collectionPresenceCount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"discountQuantities","outputs":[{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"available","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"discountedCredits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"discountsPerCollection","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"collectionPresenceCount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"eligibleDiscountQuantity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ethTowardsMints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"frameOnlyIdsBitmap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"frameOnlyIds","type":"uint256[]"}],"name":"initializeFrameOnlyIds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"isFrameOnlyId","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"isMinted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isSaleActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastBulkMintedId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"uint256","name":"collectionPresenceCount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"},{"internalType":"uint256","name":"discountQty","type":"uint256"},{"internalType":"uint256","name":"stdQty","type":"uint256"}],"name":"mintMultipleByQuantity","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"mintedBitmap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paymentsRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","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":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","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":"id","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":"count","type":"uint256"}],"name":"setFrameOnlyCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"setFrameOnlyId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stdCredits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stdPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"totalActiveCredits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalClaimedCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDepositedUnspentETH","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":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseUri","type":"string"}],"name":"updateBaseUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxSupply","type":"uint256"}],"name":"updateMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawTeamBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]