编译器
0.8.17+commit.8df45f5f
文件 1 的 18:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
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");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
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");
}
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);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
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);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
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);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
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 {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 2 的 18:ERC20Minter.sol
pragma solidity ^0.8.17;
import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IProtocolRewards} from "@zoralabs/protocol-rewards/src/interfaces/IProtocolRewards.sol";
import {IERC20Minter} from "../../interfaces/IERC20Minter.sol";
import {LimitedMintPerAddress} from "../../minters/utils/LimitedMintPerAddress.sol";
import {SaleStrategy} from "../../minters/SaleStrategy.sol";
import {ICreatorCommands} from "../../interfaces/ICreatorCommands.sol";
import {ERC20MinterRewards} from "./ERC20MinterRewards.sol";
import {IZora1155} from "./IZora1155.sol";
contract ERC20Minter is ReentrancyGuard, IERC20Minter, SaleStrategy, LimitedMintPerAddress, ERC20MinterRewards {
using SafeERC20 for IERC20;
address public zoraRewardRecipientAddress;
mapping(address => mapping(uint256 => SalesConfig)) internal salesConfigs;
function initialize(address _zoraRewardRecipientAddress) external {
if (_zoraRewardRecipientAddress == address(0)) {
revert AddressZero();
}
if (zoraRewardRecipientAddress != address(0)) {
revert AlreadyInitialized();
}
zoraRewardRecipientAddress = _zoraRewardRecipientAddress;
emit ERC20MinterInitialized(TOTAL_REWARD_PCT);
}
function computeTotalReward(uint256 totalValue) public pure returns (uint256) {
return (totalValue * TOTAL_REWARD_PCT) / BPS_TO_PERCENT_2_DECIMAL_PERCISION;
}
function computeReward(uint256 totalReward, uint256 rewardPct) public pure returns (uint256) {
return (totalReward * rewardPct) / BPS_TO_PERCENT_8_DECIMAL_PERCISION;
}
function computePaidMintRewards(uint256 totalReward) public pure returns (RewardsSettings memory) {
uint256 createReferralReward = computeReward(totalReward, CREATE_REFERRAL_PAID_MINT_REWARD_PCT);
uint256 mintReferralReward = computeReward(totalReward, MINT_REFERRAL_PAID_MINT_REWARD_PCT);
uint256 firstMinterReward = computeReward(totalReward, FIRST_MINTER_REWARD_PCT);
uint256 zoraReward = totalReward - (createReferralReward + mintReferralReward + firstMinterReward);
return
RewardsSettings({
createReferralReward: createReferralReward,
mintReferralReward: mintReferralReward,
zoraReward: zoraReward,
firstMinterReward: firstMinterReward
});
}
function getCreateReferral(address tokenContract, uint256 tokenId) public view returns (address createReferral) {
try IZora1155(tokenContract).createReferrals(tokenId) returns (address contractCreateReferral) {
createReferral = contractCreateReferral;
} catch {}
if (createReferral == address(0)) {
createReferral = zoraRewardRecipientAddress;
}
}
function getFirstMinter(address tokenContract, uint256 tokenId) public view returns (address firstMinter) {
try IZora1155(tokenContract).firstMinters(tokenId) returns (address contractFirstMinter) {
firstMinter = contractFirstMinter;
if (firstMinter == address(0)) {
firstMinter = IZora1155(tokenContract).getCreatorRewardRecipient(tokenId);
}
} catch {
firstMinter = zoraRewardRecipientAddress;
}
}
function _handleIncomingTransfer(address currency, uint256 totalValue) internal {
uint256 beforeBalance = IERC20(currency).balanceOf(address(this));
IERC20(currency).safeTransferFrom(msg.sender, address(this), totalValue);
uint256 afterBalance = IERC20(currency).balanceOf(address(this));
if ((beforeBalance + totalValue) != afterBalance) {
revert ERC20TransferSlippage();
}
}
function _distributeRewards(uint256 totalReward, address currency, uint256 tokenId, address tokenAddress, address mintReferral) private {
RewardsSettings memory settings = computePaidMintRewards(totalReward);
address createReferral = getCreateReferral(tokenAddress, tokenId);
address firstMinter = getFirstMinter(tokenAddress, tokenId);
if (mintReferral == address(0)) {
mintReferral = zoraRewardRecipientAddress;
}
IERC20(currency).safeTransfer(createReferral, settings.createReferralReward);
IERC20(currency).safeTransfer(firstMinter, settings.firstMinterReward);
IERC20(currency).safeTransfer(mintReferral, settings.mintReferralReward);
IERC20(currency).safeTransfer(zoraRewardRecipientAddress, settings.zoraReward);
emit ERC20RewardsDeposit(
createReferral,
mintReferral,
firstMinter,
zoraRewardRecipientAddress,
tokenAddress,
currency,
tokenId,
settings.createReferralReward,
settings.mintReferralReward,
settings.firstMinterReward,
settings.zoraReward
);
}
function mint(
address mintTo,
uint256 quantity,
address tokenAddress,
uint256 tokenId,
uint256 totalValue,
address currency,
address mintReferral,
string calldata comment
) external nonReentrant {
SalesConfig storage config = salesConfigs[tokenAddress][tokenId];
if (config.currency == address(0) || config.currency != currency) {
revert InvalidCurrency();
}
if (totalValue != (config.pricePerToken * quantity)) {
revert WrongValueSent();
}
if (block.timestamp < config.saleStart) {
revert SaleHasNotStarted();
}
if (block.timestamp > config.saleEnd) {
revert SaleEnded();
}
if (config.maxTokensPerAddress > 0) {
_requireMintNotOverLimitAndUpdate(config.maxTokensPerAddress, quantity, tokenAddress, tokenId, mintTo);
}
_handleIncomingTransfer(currency, totalValue);
IZora1155(tokenAddress).adminMint(mintTo, tokenId, quantity, "");
uint256 totalReward = computeTotalReward(totalValue);
_distributeRewards(totalReward, currency, tokenId, tokenAddress, mintReferral);
IERC20(config.currency).safeTransfer(config.fundsRecipient, totalValue - totalReward);
if (bytes(comment).length > 0) {
emit MintComment(mintTo, tokenAddress, tokenId, quantity, comment);
}
}
function totalRewardPct() external pure returns (uint256) {
return TOTAL_REWARD_PCT;
}
function contractURI() external pure returns (string memory) {
return "https://github.com/ourzora/zora-protocol/";
}
function contractName() external pure returns (string memory) {
return "ERC20 Minter";
}
function contractVersion() external pure returns (string memory) {
return "1.0.0";
}
function setSale(uint256 tokenId, SalesConfig memory salesConfig) external {
if (salesConfig.pricePerToken < MIN_PRICE_PER_TOKEN) {
revert PricePerTokenTooLow();
}
if (salesConfig.currency == address(0)) {
revert AddressZero();
}
if (salesConfig.fundsRecipient == address(0)) {
revert AddressZero();
}
salesConfigs[msg.sender][tokenId] = salesConfig;
emit SaleSet(msg.sender, tokenId, salesConfig);
}
function resetSale(uint256 tokenId) external override {
delete salesConfigs[msg.sender][tokenId];
emit SaleSet(msg.sender, tokenId, salesConfigs[msg.sender][tokenId]);
}
function sale(address tokenContract, uint256 tokenId) external view returns (SalesConfig memory) {
return salesConfigs[tokenContract][tokenId];
}
function supportsInterface(bytes4 interfaceId) public pure virtual override(LimitedMintPerAddress, SaleStrategy) returns (bool) {
return super.supportsInterface(interfaceId) || LimitedMintPerAddress.supportsInterface(interfaceId) || SaleStrategy.supportsInterface(interfaceId);
}
function requestMint(address, uint256, uint256, uint256, bytes calldata) external pure returns (ICreatorCommands.CommandSet memory) {
revert RequestMintInvalidUseMint();
}
function setZoraRewardsRecipient(address recipient) external {
if (msg.sender != zoraRewardRecipientAddress) {
revert OnlyZoraRewardsRecipient();
}
if (recipient == address(0)) {
revert AddressZero();
}
emit ZoraRewardsRecipientSet(zoraRewardRecipientAddress, recipient);
zoraRewardRecipientAddress = recipient;
}
}
文件 3 的 18:ERC20MinterRewards.sol
pragma solidity ^0.8.17;
abstract contract ERC20MinterRewards {
uint256 internal constant MIN_PRICE_PER_TOKEN = 10_000;
uint256 internal constant TOTAL_REWARD_PCT = 5;
uint256 internal constant BPS_TO_PERCENT_2_DECIMAL_PERCISION = 100;
uint256 internal constant BPS_TO_PERCENT_8_DECIMAL_PERCISION = 100_000_000;
uint256 internal constant CREATE_REFERRAL_PAID_MINT_REWARD_PCT = 28_571400;
uint256 internal constant MINT_REFERRAL_PAID_MINT_REWARD_PCT = 28_571400;
uint256 internal constant ZORA_PAID_MINT_REWARD_PCT = 28_571400;
uint256 internal constant FIRST_MINTER_REWARD_PCT = 14_228500;
}
文件 4 的 18:IContractMetadata.sol
pragma solidity ^0.8.17;
interface IHasContractName {
function contractName() external returns (string memory);
}
interface IContractMetadata is IHasContractName {
function contractURI() external returns (string memory);
}
文件 5 的 18:ICreatorCommands.sol
pragma solidity ^0.8.17;
interface ICreatorCommands {
enum CreatorActions {
NO_OP,
SEND_ETH,
MINT
}
struct Command {
CreatorActions method;
bytes args;
}
struct CommandSet {
Command[] commands;
uint256 at;
}
}
文件 6 的 18:IERC165Upgradeable.sol
pragma solidity ^0.8.0;
interface IERC165Upgradeable {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 7 的 18:IERC20.sol
pragma solidity ^0.8.0;
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 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
文件 8 的 18:IERC20Minter.sol
pragma solidity ^0.8.17;
interface IERC20Minter {
struct RewardsSettings {
uint256 createReferralReward;
uint256 mintReferralReward;
uint256 zoraReward;
uint256 firstMinterReward;
}
struct SalesConfig {
uint64 saleStart;
uint64 saleEnd;
uint64 maxTokensPerAddress;
uint256 pricePerToken;
address fundsRecipient;
address currency;
}
event ERC20RewardsDeposit(
address indexed createReferral,
address indexed mintReferral,
address indexed firstMinter,
address zora,
address collection,
address currency,
uint256 tokenId,
uint256 createReferralReward,
uint256 mintReferralReward,
uint256 firstMinterReward,
uint256 zoraReward
);
event ERC20MinterInitialized(uint256 rewardPercentage);
event MintComment(address indexed sender, address indexed tokenContract, uint256 indexed tokenId, uint256 quantity, string comment);
event SaleSet(address indexed mediaContract, uint256 indexed tokenId, SalesConfig salesConfig);
event ZoraRewardsRecipientSet(address indexed prevRecipient, address indexed newRecipient);
error AddressZero();
error InvalidCurrency();
error PricePerTokenTooLow();
error RequestMintInvalidUseMint();
error SaleEnded();
error SaleHasNotStarted();
error WrongValueSent();
error ERC20TransferSlippage();
error AlreadyInitialized();
error OnlyZoraRewardsRecipient();
function mint(
address mintTo,
uint256 quantity,
address tokenAddress,
uint256 tokenId,
uint256 totalValue,
address currency,
address mintReferral,
string calldata comment
) external;
function setSale(uint256 tokenId, SalesConfig memory salesConfig) external;
function sale(address tokenContract, uint256 tokenId) external view returns (SalesConfig memory);
}
文件 9 的 18:IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
文件 10 的 18:ILimitedMintPerAddress.sol
pragma solidity ^0.8.17;
import {IERC165Upgradeable} from "@zoralabs/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC165Upgradeable.sol";
interface ILimitedMintPerAddressErrors {
error UserExceedsMintLimit(address user, uint256 limit, uint256 requestedAmount);
}
interface ILimitedMintPerAddress is IERC165Upgradeable, ILimitedMintPerAddressErrors {
function getMintedPerWallet(address token, uint256 tokenId, address wallet) external view returns (uint256);
}
文件 11 的 18:IMinter1155.sol
pragma solidity ^0.8.17;
import {IERC165Upgradeable} from "@zoralabs/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC165Upgradeable.sol";
import {ICreatorCommands} from "./ICreatorCommands.sol";
interface IMinter1155 is IERC165Upgradeable {
function requestMint(
address sender,
uint256 tokenId,
uint256 quantity,
uint256 ethValueSent,
bytes calldata minterArguments
) external returns (ICreatorCommands.CommandSet memory commands);
}
文件 12 的 18:IProtocolRewards.sol
pragma solidity ^0.8.17;
interface IProtocolRewards {
event RewardsDeposit(
address indexed creator,
address indexed createReferral,
address indexed mintReferral,
address firstMinter,
address zora,
address from,
uint256 creatorReward,
uint256 createReferralReward,
uint256 mintReferralReward,
uint256 firstMinterReward,
uint256 zoraReward
);
event Deposit(address indexed from, address indexed to, bytes4 indexed reason, uint256 amount, string comment);
event Withdraw(address indexed from, address indexed to, uint256 amount);
error ADDRESS_ZERO();
error ARRAY_LENGTH_MISMATCH();
error INVALID_DEPOSIT();
error INVALID_SIGNATURE();
error INVALID_WITHDRAW();
error SIGNATURE_DEADLINE_EXPIRED();
error TRANSFER_FAILED();
function deposit(address to, bytes4 why, string calldata comment) external payable;
function depositBatch(address[] calldata recipients, uint256[] calldata amounts, bytes4[] calldata reasons, string calldata comment) external payable;
function depositRewards(
address creator,
uint256 creatorReward,
address createReferral,
uint256 createReferralReward,
address mintReferral,
uint256 mintReferralReward,
address firstMinter,
uint256 firstMinterReward,
address zora,
uint256 zoraReward
) external payable;
function withdraw(address to, uint256 amount) external;
function withdrawWithSig(address from, address to, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;
}
文件 13 的 18:IVersionedContract.sol
pragma solidity ^0.8.17;
interface IVersionedContract {
function contractVersion() external returns (string memory);
}
文件 14 的 18:IZora1155.sol
pragma solidity ^0.8.17;
interface IZora1155 {
function createReferrals(uint256 tokenId) external view returns (address);
function firstMinters(uint256 tokenId) external view returns (address);
function getCreatorRewardRecipient(uint256 tokenId) external view returns (address);
function adminMint(address recipient, uint256 tokenId, uint256 quantity, bytes memory data) external;
}
文件 15 的 18:LimitedMintPerAddress.sol
pragma solidity 0.8.17;
import {ILimitedMintPerAddress} from "../../interfaces/ILimitedMintPerAddress.sol";
contract LimitedMintPerAddress is ILimitedMintPerAddress {
mapping(address => mapping(uint256 => mapping(address => uint256))) internal mintedPerAddress;
function getMintedPerWallet(address tokenContract, uint256 tokenId, address wallet) external view returns (uint256) {
return mintedPerAddress[tokenContract][tokenId][wallet];
}
function _requireMintNotOverLimitAndUpdate(uint256 limit, uint256 numRequestedMint, address tokenContract, uint256 tokenId, address wallet) internal {
mintedPerAddress[tokenContract][tokenId][wallet] += numRequestedMint;
if (mintedPerAddress[tokenContract][tokenId][wallet] > limit) {
revert UserExceedsMintLimit(wallet, limit, mintedPerAddress[tokenContract][tokenId][wallet]);
}
}
function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) {
return interfaceId == type(ILimitedMintPerAddress).interfaceId;
}
}
文件 16 的 18:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
}
function _nonReentrantAfter() private {
_status = _NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}
文件 17 的 18:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
文件 18 的 18:SaleStrategy.sol
pragma solidity 0.8.17;
import {IERC165Upgradeable} from "@zoralabs/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC165Upgradeable.sol";
import {IMinter1155} from "../interfaces/IMinter1155.sol";
import {IContractMetadata} from "../interfaces/IContractMetadata.sol";
import {IVersionedContract} from "../interfaces/IVersionedContract.sol";
abstract contract SaleStrategy is IMinter1155, IVersionedContract, IContractMetadata {
function resetSale(uint256 tokenId) external virtual;
function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) {
return interfaceId == type(IMinter1155).interfaceId || interfaceId == type(IERC165Upgradeable).interfaceId;
}
}
{
"compilationTarget": {
"src/minters/erc20/ERC20Minter.sol": "ERC20Minter"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 0
},
"remappings": [
":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
":@zoralabs/mints-contracts/src/=node_modules/@zoralabs/mints-contracts/src/",
":@zoralabs/openzeppelin-contracts-upgradeable/=node_modules/@zoralabs/openzeppelin-contracts-upgradeable/",
":@zoralabs/protocol-rewards/src/=node_modules/@zoralabs/protocol-rewards/src/",
":@zoralabs/shared-contracts/=node_modules/@zoralabs/shared-contracts/src/",
":_imagine/=_imagine/",
":ds-test/=node_modules/ds-test/src/",
":forge-std/=node_modules/forge-std/src/",
":mint/=_imagine/mint/",
":solady/=node_modules/solady/src/",
":solemate/=/node_modules/solemate/src/",
":solmate/=node_modules/solmate/"
]
}
[{"inputs":[],"name":"AddressZero","type":"error"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"ERC20TransferSlippage","type":"error"},{"inputs":[],"name":"InvalidCurrency","type":"error"},{"inputs":[],"name":"OnlyZoraRewardsRecipient","type":"error"},{"inputs":[],"name":"PricePerTokenTooLow","type":"error"},{"inputs":[],"name":"RequestMintInvalidUseMint","type":"error"},{"inputs":[],"name":"SaleEnded","type":"error"},{"inputs":[],"name":"SaleHasNotStarted","type":"error"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"limit","type":"uint256"},{"internalType":"uint256","name":"requestedAmount","type":"uint256"}],"name":"UserExceedsMintLimit","type":"error"},{"inputs":[],"name":"WrongValueSent","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"rewardPercentage","type":"uint256"}],"name":"ERC20MinterInitialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"createReferral","type":"address"},{"indexed":true,"internalType":"address","name":"mintReferral","type":"address"},{"indexed":true,"internalType":"address","name":"firstMinter","type":"address"},{"indexed":false,"internalType":"address","name":"zora","type":"address"},{"indexed":false,"internalType":"address","name":"collection","type":"address"},{"indexed":false,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"createReferralReward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintReferralReward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"firstMinterReward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"zoraReward","type":"uint256"}],"name":"ERC20RewardsDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"tokenContract","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"},{"indexed":false,"internalType":"string","name":"comment","type":"string"}],"name":"MintComment","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"mediaContract","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint64","name":"saleStart","type":"uint64"},{"internalType":"uint64","name":"saleEnd","type":"uint64"},{"internalType":"uint64","name":"maxTokensPerAddress","type":"uint64"},{"internalType":"uint256","name":"pricePerToken","type":"uint256"},{"internalType":"address","name":"fundsRecipient","type":"address"},{"internalType":"address","name":"currency","type":"address"}],"indexed":false,"internalType":"struct IERC20Minter.SalesConfig","name":"salesConfig","type":"tuple"}],"name":"SaleSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"prevRecipient","type":"address"},{"indexed":true,"internalType":"address","name":"newRecipient","type":"address"}],"name":"ZoraRewardsRecipientSet","type":"event"},{"inputs":[{"internalType":"uint256","name":"totalReward","type":"uint256"}],"name":"computePaidMintRewards","outputs":[{"components":[{"internalType":"uint256","name":"createReferralReward","type":"uint256"},{"internalType":"uint256","name":"mintReferralReward","type":"uint256"},{"internalType":"uint256","name":"zoraReward","type":"uint256"},{"internalType":"uint256","name":"firstMinterReward","type":"uint256"}],"internalType":"struct IERC20Minter.RewardsSettings","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"totalReward","type":"uint256"},{"internalType":"uint256","name":"rewardPct","type":"uint256"}],"name":"computeReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"totalValue","type":"uint256"}],"name":"computeTotalReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"contractName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"contractVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getCreateReferral","outputs":[{"internalType":"address","name":"createReferral","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getFirstMinter","outputs":[{"internalType":"address","name":"firstMinter","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"wallet","type":"address"}],"name":"getMintedPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_zoraRewardRecipientAddress","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"mintTo","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"totalValue","type":"uint256"},{"internalType":"address","name":"currency","type":"address"},{"internalType":"address","name":"mintReferral","type":"address"},{"internalType":"string","name":"comment","type":"string"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"requestMint","outputs":[{"components":[{"components":[{"internalType":"enum ICreatorCommands.CreatorActions","name":"method","type":"uint8"},{"internalType":"bytes","name":"args","type":"bytes"}],"internalType":"struct ICreatorCommands.Command[]","name":"commands","type":"tuple[]"},{"internalType":"uint256","name":"at","type":"uint256"}],"internalType":"struct ICreatorCommands.CommandSet","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"resetSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"sale","outputs":[{"components":[{"internalType":"uint64","name":"saleStart","type":"uint64"},{"internalType":"uint64","name":"saleEnd","type":"uint64"},{"internalType":"uint64","name":"maxTokensPerAddress","type":"uint64"},{"internalType":"uint256","name":"pricePerToken","type":"uint256"},{"internalType":"address","name":"fundsRecipient","type":"address"},{"internalType":"address","name":"currency","type":"address"}],"internalType":"struct IERC20Minter.SalesConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint64","name":"saleStart","type":"uint64"},{"internalType":"uint64","name":"saleEnd","type":"uint64"},{"internalType":"uint64","name":"maxTokensPerAddress","type":"uint64"},{"internalType":"uint256","name":"pricePerToken","type":"uint256"},{"internalType":"address","name":"fundsRecipient","type":"address"},{"internalType":"address","name":"currency","type":"address"}],"internalType":"struct IERC20Minter.SalesConfig","name":"salesConfig","type":"tuple"}],"name":"setSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"setZoraRewardsRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"totalRewardPct","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"zoraRewardRecipientAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]