文件 1 的 17: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 functionCall(target, data, "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");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(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) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(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) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 17:Base.sol
pragma solidity >=0.8.0 <0.9.0;
import "./library/ProxyConfigUtils.sol";
import "./library/Registry.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
abstract contract Base is ReentrancyGuard {
function _initBase(IConfig config_) internal {
ProxyConfigUtils._setConfig(config_);
}
function getConfig() public view returns(IConfig config){
return ProxyConfigUtils._getConfig();
}
function hasRole(bytes32 role, address account) internal view returns(bool has){
return ProxyConfigUtils._getConfig().hasRole(role, account);
}
modifier isSuperAdmin() {
require(hasRole(Registry.SUPER_ADMIN_ROLE, msg.sender), "only super admin can do");
_;
}
modifier isAdmin() {
require(hasRole(Registry.ADMIN_ROLE, msg.sender), "only super admin can do");
_;
}
modifier isMinter() {
require(hasRole(Registry.MINTER_ROLE, msg.sender), "only minter role can do");
_;
}
modifier isDepositer() {
require(hasRole(Registry.DEPOSIT_ROLE, msg.sender), "only depositer role can do");
_;
}
modifier isOperator() {
require(hasRole(Registry.OPERATOR_ROLE, msg.sender), "only operator role can do");
_;
}
modifier isSuperAdminOrMinter() {
require(hasRole(Registry.SUPER_ADMIN_ROLE, msg.sender) || hasRole(Registry.MINTER_ROLE, msg.sender), "only super admin or minter role can do");
_;
}
}
文件 3 的 17:ConfigUtils.sol
pragma solidity >=0.8.0 <0.9.0;
import "../interfaces/IConfig.sol";
library ConfigUtils {
function _checkConfig(IConfig config) internal view {
require(config.version() > 0 || config.supportsInterface(type(IConfig).interfaceId), "SC130: not a valid config contract");
}
}
文件 4 的 17:EnumerableMap.sol
pragma solidity ^0.8.0;
import "./EnumerableSet.sol";
library EnumerableMap {
using EnumerableSet for EnumerableSet.Bytes32Set;
struct Map {
EnumerableSet.Bytes32Set _keys;
mapping(bytes32 => bytes32) _values;
}
function _set(
Map storage map,
bytes32 key,
bytes32 value
) private returns (bool) {
map._values[key] = value;
return map._keys.add(key);
}
function _remove(Map storage map, bytes32 key) private returns (bool) {
delete map._values[key];
return map._keys.remove(key);
}
function _contains(Map storage map, bytes32 key)
private
view
returns (bool)
{
return map._keys.contains(key);
}
function _length(Map storage map) private view returns (uint256) {
return map._keys.length();
}
function _at(Map storage map, uint256 index)
private
view
returns (bytes32, bytes32)
{
bytes32 key = map._keys.at(index);
return (key, map._values[key]);
}
function _tryGet(Map storage map, bytes32 key)
private
view
returns (bool, bytes32)
{
bytes32 value = map._values[key];
if (value == bytes32(0)) {
return (_contains(map, key), bytes32(0));
} else {
return (true, value);
}
}
function _get(Map storage map, bytes32 key) private view returns (bytes32) {
bytes32 value = map._values[key];
require(
value != 0 || _contains(map, key),
"EnumerableMap: nonexistent key"
);
return value;
}
function _get(
Map storage map,
bytes32 key,
string memory errorMessage
) private view returns (bytes32) {
bytes32 value = map._values[key];
require(value != 0 || _contains(map, key), errorMessage);
return value;
}
struct UintToAddressMap {
Map _inner;
}
function set(
UintToAddressMap storage map,
uint256 key,
address value
) internal returns (bool) {
return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
}
function remove(UintToAddressMap storage map, uint256 key)
internal
returns (bool)
{
return _remove(map._inner, bytes32(key));
}
function contains(UintToAddressMap storage map, uint256 key)
internal
view
returns (bool)
{
return _contains(map._inner, bytes32(key));
}
function length(UintToAddressMap storage map)
internal
view
returns (uint256)
{
return _length(map._inner);
}
function at(UintToAddressMap storage map, uint256 index)
internal
view
returns (uint256, address)
{
(bytes32 key, bytes32 value) = _at(map._inner, index);
return (uint256(key), address(uint160(uint256(value))));
}
function tryGet(UintToAddressMap storage map, uint256 key)
internal
view
returns (bool, address)
{
(bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));
return (success, address(uint160(uint256(value))));
}
function get(UintToAddressMap storage map, uint256 key)
internal
view
returns (address)
{
return address(uint160(uint256(_get(map._inner, bytes32(key)))));
}
function get(
UintToAddressMap storage map,
uint256 key,
string memory errorMessage
) internal view returns (address) {
return
address(
uint160(uint256(_get(map._inner, bytes32(key), errorMessage)))
);
}
struct AddressToBoolMap {
Map _inner;
}
function set(
AddressToBoolMap storage map,
address key,
bool value
) internal returns (bool) {
uint256 _value;
assembly {
_value := value
}
return
_set(map._inner, bytes32(uint256(uint160(key))), bytes32(_value));
}
function remove(AddressToBoolMap storage map, address key)
internal
returns (bool)
{
return _remove(map._inner, bytes32(uint256(uint160(key))));
}
function contains(AddressToBoolMap storage map, address key)
internal
view
returns (bool)
{
return _contains(map._inner, bytes32(uint256(uint160(key))));
}
function length(AddressToBoolMap storage map)
internal
view
returns (uint256)
{
return _length(map._inner);
}
function at(AddressToBoolMap storage map, uint256 index)
internal
view
returns (address, bool)
{
(bytes32 key, bytes32 value) = _at(map._inner, index);
bool _value;
uint256 tValue = uint256(value);
assembly {
_value := tValue
}
return (address(uint160(uint256(key))), _value);
}
function tryGet(AddressToBoolMap storage map, address key)
internal
view
returns (bool, bool)
{
(bool success, bytes32 value) = _tryGet(
map._inner,
bytes32(uint256(uint160(key)))
);
bool _value;
uint256 tValue = uint256(value);
assembly {
_value := tValue
}
return (success, _value);
}
function get(AddressToBoolMap storage map, address key)
internal
view
returns (bool)
{
bool _value;
uint256 tValue = uint256(
_get(map._inner, bytes32(uint256(uint160(key))))
);
assembly {
_value := tValue
}
return _value;
}
function get(
AddressToBoolMap storage map,
address key,
string memory errorMessage
) internal view returns (bool) {
bool _value;
uint256 tValue = uint256(
_get(map._inner, bytes32(uint256(uint160(key))), errorMessage)
);
assembly {
_value := tValue
}
return _value;
}
function values(AddressToBoolMap storage map)
internal
view
returns (address[] memory)
{
bytes32[] memory values = map._inner._keys.values();
address[] memory addrs;
assembly {
addrs := values
}
return addrs;
}
}
文件 5 的 17:EnumerableSet.sol
pragma solidity ^0.8.0;
library EnumerableSet {
struct Set {
bytes32[] _values;
mapping(bytes32 => uint256) _indexes;
}
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
function _remove(Set storage set, bytes32 value) private returns (bool) {
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
if (lastIndex != toDeleteIndex) {
bytes32 lastvalue = set._values[lastIndex];
set._values[toDeleteIndex] = lastvalue;
set._indexes[lastvalue] = valueIndex;
}
set._values.pop();
delete set._indexes[value];
return true;
} else {
return false;
}
}
function _contains(Set storage set, bytes32 value)
private
view
returns (bool)
{
return set._indexes[value] != 0;
}
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
function _at(Set storage set, uint256 index)
private
view
returns (bytes32)
{
return set._values[index];
}
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
struct Bytes32Set {
Set _inner;
}
function add(Bytes32Set storage set, bytes32 value)
internal
returns (bool)
{
return _add(set._inner, value);
}
function remove(Bytes32Set storage set, bytes32 value)
internal
returns (bool)
{
return _remove(set._inner, value);
}
function contains(Bytes32Set storage set, bytes32 value)
internal
view
returns (bool)
{
return _contains(set._inner, value);
}
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(Bytes32Set storage set, uint256 index)
internal
view
returns (bytes32)
{
return _at(set._inner, index);
}
function values(Bytes32Set storage set)
internal
view
returns (bytes32[] memory)
{
return _values(set._inner);
}
struct AddressSet {
Set _inner;
}
function add(AddressSet storage set, address value)
internal
returns (bool)
{
return _add(set._inner, bytes32(uint256(uint160(value))));
}
function remove(AddressSet storage set, address value)
internal
returns (bool)
{
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
function contains(AddressSet storage set, address value)
internal
view
returns (bool)
{
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(AddressSet storage set, uint256 index)
internal
view
returns (address)
{
return address(uint160(uint256(_at(set._inner, index))));
}
function values(AddressSet storage set)
internal
view
returns (address[] memory)
{
bytes32[] memory store = _values(set._inner);
address[] memory result;
assembly {
result := store
}
return result;
}
struct UintSet {
Set _inner;
}
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
function remove(UintSet storage set, uint256 value)
internal
returns (bool)
{
return _remove(set._inner, bytes32(value));
}
function contains(UintSet storage set, uint256 value)
internal
view
returns (bool)
{
return _contains(set._inner, bytes32(value));
}
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(UintSet storage set, uint256 index)
internal
view
returns (uint256)
{
return uint256(_at(set._inner, index));
}
function values(UintSet storage set)
internal
view
returns (uint256[] memory)
{
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
assembly {
result := store
}
return result;
}
}
文件 6 的 17:IConfig.sol
pragma solidity >=0.8.0 <0.9.0;
interface IConfig {
function version() external pure returns (uint256 v);
function getAddressByKey(bytes32 _key) external view returns (address);
function getUint256ByKey(bytes32 _key) external view returns (uint256);
function hasRole(bytes32 role, address account) external view returns(bool has);
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 7 的 17: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 的 17:IFilteredMinterV0.sol
pragma solidity ^0.8.0;
interface IFilteredMinterV0 {
event PricePerTokenInWeiUpdated(
uint256 indexed _projectId,
uint256 indexed _pricePerTokenInWei
);
event ProjectCurrencyInfoUpdated(
uint256 indexed _projectId,
address indexed _currencyAddress,
string _currencySymbol
);
event PurchaseToDisabledUpdated(
uint256 indexed _projectId,
bool _purchaseToDisabled
);
event SetProjectMintInfo(
uint256 projectId,
address token,
uint256 price,
uint256 maxInvocations,
uint256 startTime,
bool disable
);
event UpdateProjectMaxInvocations(
uint256 projectId,
uint256 maxInvocations
);
event Purchase(
uint256 projectId,
address currency,
address minter,
uint256 mintCount,
uint256 total
);
event UpdateProjectStartTime(uint256 projectId, uint256 startTime);
function minterType() external view returns (string memory);
function genArt721CoreAddress() external returns (address);
function minterFilterAddress() external returns (address);
function purchase(uint256 _projectId, uint8 mintCount)
external
payable;
function purchaseTo(address _to, uint256 _projectId, uint8 _mintCount)
external
payable;
function togglePurchaseToDisabled(uint256 _projectId) external;
function getPriceInfo(uint256 _projectId)
external
view
returns (
bool isConfigured,
uint256 tokenPriceInWei,
uint256 whitePriceInWei,
address currencyAddress
);
}
文件 9 的 17:IGenArt721CoreContractV3.sol
pragma solidity ^0.8.0;
interface IGenArt721CoreContractV3 {
event Mint(
address indexed _to,
uint256 indexed _tokenId,
bytes32 indexed _hash
);
event MinterUpdated(address indexed _currentMinter);
function admin() external view returns (address);
function nextProjectId() external view returns (uint256);
function tokenIdToProjectId(uint256 tokenId)
external
view
returns (uint256 projectId);
function isWhitelisted(address sender) external view returns (bool);
function isMintWhitelisted(address minter) external view returns (bool);
function projectIdToArtistAddress(uint256 _projectId)
external
view
returns (address payable);
function projectIdToAdditionalPayee(uint256 _projectId)
external
view
returns (address payable);
function projectIdToAdditionalPayeePercentage(uint256 _projectId)
external
view
returns (uint256);
function projectInfo(uint256 _projectId)
external
view
returns (
address,
uint256,
uint256,
bool,
address,
uint256
);
function alleriaAddress() external view returns (address payable);
function alleriaPercentage() external view returns (uint256);
function mint(
address _to,
uint256 _projectId,
address _by
) external returns (uint256 tokenId);
function updateProjectRoyaltyData(
uint256 _projectId,
address[] memory _addrs,
uint256[] memory _rates
) external;
function setProjectMinterType(uint256 _projectId, string memory _type)
external;
}
文件 10 的 17:IMinterFilterV0.sol
pragma solidity ^0.8.0;
interface IMinterFilterV0 {
event MinterApproved(address indexed _minterAddress, string _minterType);
event MinterRevoked(address indexed _minterAddress);
event ProjectMinterRegistered(
uint256 indexed _projectId,
address indexed _minterAddress,
string _minterType
);
event ProjectMinterRemoved(uint256 indexed _projectId);
function genArt721CoreAddress() external returns (address);
function setMinterForProject(uint256, address) external;
function removeMinterForProject(uint256) external;
function mint(
address _to,
uint256 _projectId,
address sender
) external returns (uint256);
function getMinterForProject(uint256) external view returns (address);
function projectHasMinter(uint256) external view returns (bool);
}
文件 11 的 17:MinterSetPrice.sol
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./interfaces/IGenArt721CoreContractV3.sol";
import "./interfaces/IMinterFilterV0.sol";
import "./interfaces/IFilteredMinterV0.sol";
import "./utils/EnumerableMap.sol";
import "./Base.sol";
pragma solidity 0.8.9;
contract MinterSetPrice is Base, IFilteredMinterV0 {
using SafeERC20 for IERC20;
using EnumerableMap for EnumerableMap.AddressToBoolMap;
address public immutable genArt721CoreAddress;
IGenArt721CoreContractV3 private immutable genArtCoreContract;
address public immutable minterFilterAddress;
IMinterFilterV0 private immutable minterFilter;
string public constant minterType = "MinterSetPrice";
uint256 constant ONE_MILLION = 1_000_000;
uint256 constant TEN_THOUSAND = 10_000;
uint256 public MAX_WHITE_LENGTH = 1_000;
uint256 public MAX_ADDITIONAL_FEE = 10;
mapping(uint256 => bool) public projectMaxHasBeenInvoked;
mapping(uint256 => uint256) public projectMaxInvocations;
mapping(uint256 => uint256) private projectIdToPricePerTokenInWei;
mapping(uint256 => bool) private projectIdToPriceIsConfigured;
mapping(uint256 => uint256) private projectIdToStartTime;
mapping(uint256 => bool) private projectIdToDisable;
mapping(uint256 => EnumerableMap.AddressToBoolMap)
private projectIdToWhitelists;
mapping(uint256 => uint256) private projectIdToWhitePrice;
mapping(uint256 => uint256) public projectIdToAdditionalPayeePercentage;
mapping(uint256 => address payable) public projectIdToAdditionalPayee;
mapping (uint256 => address) public projectIdToMintCurrency;
mapping(uint256 => uint256) public projectIdWhiteListMintCounts;
uint256 public defaultAdditionalPayee = 8;
bool public canArtistModify;
uint8 public maxBatchMintCount = 20;
uint8 public defaultWhiteListMintCount = 1;
modifier onlyArtist(uint256 _projectId) {
require(
msg.sender ==
genArtCoreContract.projectIdToArtistAddress(_projectId),
"Only Artist"
);
_;
}
modifier onlyArtistOrOperator(uint256 _projectId, bool _flag) {
require(
(_flag && msg.sender ==
genArtCoreContract.projectIdToArtistAddress(_projectId)) ||
hasRole(Registry.OPERATOR_ROLE, msg.sender),
"Only Artist"
);
_;
}
modifier onlyOperator() {
require(hasRole(Registry.OPERATOR_ROLE, msg.sender), "Only Operator");
_;
}
modifier onlyProjectMaxNotHasBeenInvoked(uint256 _projectId) {
require(
!projectMaxHasBeenInvoked[_projectId],
"Project has been invoked"
);
_;
}
modifier onlyProjectInvocationsIsZero(uint256 _projectId) {
uint256 invocations;
address artistAddress;
(artistAddress, invocations, , , , ) = genArtCoreContract.projectInfo(
_projectId
);
require(
artistAddress != address(0) && invocations == 0,
"Project not exist or Project has invocation"
);
_;
}
modifier onlyBeforeStartTime(uint256 _projectId) {
uint256 startTime = projectIdToStartTime[_projectId];
require(block.timestamp < startTime, "Current time after startTime");
_;
}
constructor(address _genArt721Address, address _minterFilter, IConfig _config)
{
genArt721CoreAddress = _genArt721Address;
genArtCoreContract = IGenArt721CoreContractV3(_genArt721Address);
minterFilterAddress = _minterFilter;
minterFilter = IMinterFilterV0(_minterFilter);
require(
minterFilter.genArt721CoreAddress() == _genArt721Address,
"Illegal contract pairing"
);
_initBase(_config);
}
function setProjectMintInfo(
uint256 _projectId,
address _token,
uint256 _pricePerTokenInWei,
uint256 _maxInvocations,
uint256 _startTime,
bool _disable,
address[] memory _addrs,
uint256[] memory _rates
) external onlyArtist(_projectId) onlyProjectInvocationsIsZero(_projectId) {
require(
_startTime > block.timestamp,
"Start time must > current block time"
);
{
uint256 invocations;
(, invocations, , , , ) = genArtCoreContract.projectInfo(_projectId);
require(
_maxInvocations <= ONE_MILLION,
"Max invocations must <= 1000000"
);
require(
_maxInvocations >= invocations,
"Max invocations must > current invocations"
);
projectIdToPricePerTokenInWei[_projectId] = _pricePerTokenInWei;
projectIdToPriceIsConfigured[_projectId] = true;
projectMaxInvocations[_projectId] = _maxInvocations;
if (invocations < _maxInvocations) {
projectMaxHasBeenInvoked[_projectId] = false;
}
}
projectIdToStartTime[_projectId] = _startTime;
projectIdToDisable[_projectId] = _disable;
projectIdToMintCurrency[_projectId] = _token;
minterFilter.setMinterForProject(_projectId, address(this));
genArtCoreContract.setProjectMinterType(_projectId, minterType);
emit SetProjectMintInfo(
_projectId,
_token,
_pricePerTokenInWei,
_maxInvocations,
_startTime,
_disable
);
}
function updateMaxBatchMintCount(uint8 _count) external onlyOperator {
require(_count > 0, "mint count must > 0");
maxBatchMintCount = _count;
}
function updateProjectIdWhiteListMintCounts(uint256 _projectId, uint256 _count) external onlyArtistOrOperator(_projectId, true) {
require(_count <= maxBatchMintCount, "count must < max batch count");
projectIdWhiteListMintCounts[_projectId] = _count;
}
function togglePurchaseToDisabled(uint256 _projectId)
external
onlyArtistOrOperator(_projectId, true)
onlyProjectMaxNotHasBeenInvoked(_projectId)
{
projectIdToDisable[_projectId] = !projectIdToDisable[_projectId];
emit PurchaseToDisabledUpdated(
_projectId,
!projectIdToDisable[_projectId]
);
}
function updatePricePerTokenInWei(
uint256 _projectId,
uint256 _pricePerTokenInWei
)
external
onlyArtistOrOperator(_projectId, true)
onlyProjectMaxNotHasBeenInvoked(_projectId)
onlyProjectInvocationsIsZero(_projectId)
{
projectIdToPricePerTokenInWei[_projectId] = _pricePerTokenInWei;
projectIdToPriceIsConfigured[_projectId] = true;
emit PricePerTokenInWeiUpdated(_projectId, _pricePerTokenInWei);
}
function updateMaxInvocations(uint256 _projectId, uint256 _maxInvocations)
external
onlyArtistOrOperator(_projectId, true)
onlyProjectMaxNotHasBeenInvoked(_projectId)
{
uint256 invocations;
(, invocations, , , , ) = genArtCoreContract.projectInfo(_projectId);
require(
_maxInvocations <= ONE_MILLION,
"Max invocations must <= 1000000"
);
require(
_maxInvocations >= invocations,
"Max invocations must > current invocations"
);
projectMaxInvocations[_projectId] = _maxInvocations;
emit UpdateProjectMaxInvocations(_projectId, _maxInvocations);
}
function updateStartTime(uint256 _projectId, uint256 _startTime)
external
onlyArtistOrOperator(_projectId, true)
onlyProjectMaxNotHasBeenInvoked(_projectId)
{
require(
_startTime > block.timestamp,
"Start time must > current block time"
);
projectIdToStartTime[_projectId] = _startTime;
emit UpdateProjectStartTime(_projectId, _startTime);
}
function updateMaxMintBatchCount(uint8 _count) external isOperator {
maxBatchMintCount = _count;
}
function updateDefaultWhiteListMintCount(uint8 _count) external isOperator {
defaultWhiteListMintCount = _count;
}
function updateCanArtistModify(bool _flag) external isOperator {
canArtistModify = _flag;
}
function updateDefaultAdditionalPayee(uint256 _fee) external isOperator {
require(_fee <= MAX_ADDITIONAL_FEE, "must < MAX_ADDITIONAL_FEE");
defaultAdditionalPayee = _fee;
}
function updateProjectAdditionalPayeePercentage(uint256 _projectId, uint256 _percentage) external onlyArtistOrOperator(_projectId, canArtistModify) {
require(_percentage <= MAX_ADDITIONAL_FEE, "must < MAX_ADDITIONAL_FEE");
projectIdToAdditionalPayeePercentage[_projectId] = _percentage;
}
function updateProjectIdToAdditionalPayee(uint256 _projectId, address payable _additionalAddr) external onlyArtistOrOperator(_projectId, canArtistModify) {
projectIdToAdditionalPayee[_projectId] = _additionalAddr;
}
function addProjectWhitelist(uint256 _projectId, address[] memory _addrs)
public
onlyArtistOrOperator(_projectId, true)
onlyBeforeStartTime(_projectId)
{
EnumerableMap.AddressToBoolMap storage whiteSet = projectIdToWhitelists[
_projectId
];
require(
_addrs.length + whiteSet.length() <= MAX_WHITE_LENGTH,
"white length > MAX_WHITE_LENGTH"
);
for (uint256 i = 0; i < _addrs.length; i++) {
require(_addrs[i] != address(0), "invalid address");
whiteSet.set(_addrs[i], true);
}
}
function updateProjectWhitelistPrice(uint256 _projectId, uint256 _price)
public
onlyArtistOrOperator(_projectId, true)
onlyBeforeStartTime(_projectId)
{
projectIdToWhitePrice[_projectId] = _price;
}
function updateProjectWhitelistMaxLength(uint256 _num)
public
isAdmin
{
MAX_WHITE_LENGTH = _num;
}
function purchase(uint256 _projectId, uint8 mintCount)
external
payable
{
require(mintCount > 0 && mintCount <= maxBatchMintCount, "invalid mint count");
purchaseTo(msg.sender, _projectId, mintCount);
}
function purchaseTo(address _to, uint256 _projectId, uint8 _mintCount)
public
payable
nonReentrant
{
require(
!projectMaxHasBeenInvoked[_projectId],
"Maximum number of invocations reached"
);
(,uint256 invocations,,,,) = genArtCoreContract.projectInfo(_projectId);
require(invocations + _mintCount <= projectMaxInvocations[_projectId], "not enough to mint");
require(
projectIdToPriceIsConfigured[_projectId],
"Price not configured"
);
require(!projectIdToDisable[_projectId], "Project is disable");
uint256 price = getPrice(_projectId);
price = price * _mintCount;
if (block.timestamp < projectIdToStartTime[_projectId]) {
uint256 allowCount = defaultWhiteListMintCount;
if (projectIdWhiteListMintCounts[_projectId] != 0) {
allowCount = projectIdWhiteListMintCounts[_projectId];
}
require(_mintCount <= allowCount, "white list only can mint allow count");
EnumerableMap.AddressToBoolMap
storage whiteSet = projectIdToWhitelists[_projectId];
(bool exist, ) = whiteSet.tryGet(msg.sender);
require(exist, "msg sender not in white list");
whiteSet.remove(msg.sender);
}
address mintCurrency = projectIdToMintCurrency[_projectId];
if (mintCurrency == address(0)) {
require(msg.value >= price, "Must send minimum value to mint!");
}
uint256 tokenId;
for (uint i; i<_mintCount; i++) {
tokenId = minterFilter.mint(_to, _projectId, msg.sender);
}
if (
projectMaxInvocations[_projectId] > 0 &&
tokenId % ONE_MILLION == projectMaxInvocations[_projectId] - 1
) {
projectMaxHasBeenInvoked[_projectId] = true;
}
if (mintCurrency == address(0)) {
_splitFundsETH(_projectId, price);
} else {
_splitFundsERC20(_projectId, price, mintCurrency);
}
emit Purchase(_projectId, mintCurrency, msg.sender, _mintCount, price);
}
function _splitFundsETH(uint256 _projectId, uint256 _price) internal {
if (msg.value > 0) {
uint256 pricePerTokenInWei = _price;
uint256 refund = msg.value - pricePerTokenInWei;
if (refund > 0) {
(bool success_, ) = msg.sender.call{value: refund}("");
require(success_, "Refund failed");
}
uint256 foundationAmount = (pricePerTokenInWei *
genArtCoreContract.alleriaPercentage()) / 100;
if (foundationAmount > 0) {
(bool success_, ) = genArtCoreContract.alleriaAddress().call{
value: foundationAmount
}("");
require(success_, "Foundation payment failed");
}
uint256 projectFunds = pricePerTokenInWei - foundationAmount;
uint256 additionalPayeeAmount;
uint256 payeeFee = defaultAdditionalPayee;
if (
projectIdToAdditionalPayee[_projectId] != address(0)
) {
uint256 useFee = projectIdToAdditionalPayeePercentage[_projectId];
if (useFee != 0) {
payeeFee = useFee;
}
additionalPayeeAmount =
(projectFunds * payeeFee) / 100;
if (additionalPayeeAmount > 0) {
(bool success_, ) = projectIdToAdditionalPayee[_projectId]
.call{value: additionalPayeeAmount}("");
require(success_, "Additional payment failed");
}
}
uint256 creatorFunds = projectFunds - additionalPayeeAmount;
if (creatorFunds > 0) {
(bool success_, ) = genArtCoreContract
.projectIdToArtistAddress(_projectId)
.call{value: creatorFunds}("");
require(success_, "Artist payment failed");
}
}
}
function _splitFundsERC20(uint256 _projectId, uint256 _price, address _currency) internal {
uint256 pricePerTokenInWei = _price;
IERC20(_currency).safeTransferFrom(msg.sender, address(this), pricePerTokenInWei);
uint256 foundationAmount = (pricePerTokenInWei *
genArtCoreContract.alleriaPercentage()) / 100;
if (foundationAmount > 0) {
IERC20(_currency).safeTransfer(genArtCoreContract.alleriaAddress(), foundationAmount);
}
uint256 projectFunds = pricePerTokenInWei - foundationAmount;
uint256 additionalPayeeAmount;
uint256 payeeFee = defaultAdditionalPayee;
if (
projectIdToAdditionalPayee[_projectId] != address(0)
) {
uint256 useFee = projectIdToAdditionalPayeePercentage[_projectId];
if (useFee != 0) {
payeeFee = useFee;
}
additionalPayeeAmount =
(projectFunds * payeeFee) / 100;
if (additionalPayeeAmount > 0) {
IERC20(_currency).safeTransfer(projectIdToAdditionalPayee[_projectId], additionalPayeeAmount);
}
}
uint256 creatorFunds = projectFunds - additionalPayeeAmount;
if (creatorFunds > 0) {
IERC20(_currency).safeTransfer(genArtCoreContract.projectIdToArtistAddress(_projectId), creatorFunds);
}
}
function getPriceInfo(uint256 _projectId)
external
view
returns (
bool isConfigured,
uint256 tokenPriceInWei,
uint256 whitePriceInWei,
address currencyAddress
)
{
isConfigured = projectIdToPriceIsConfigured[_projectId];
tokenPriceInWei = projectIdToPricePerTokenInWei[_projectId];
whitePriceInWei = projectIdToWhitePrice[_projectId];
currencyAddress = projectIdToMintCurrency[_projectId];
}
function getMintInfo(uint256 _projectId)
external
view
returns (
uint256 pricePerTokenInWei,
uint256 whitePerTokenInWei,
uint256 invocations,
uint256 maxInvocations,
uint256 startTime,
bool disable
)
{
(, invocations, , , , ) = genArtCoreContract.projectInfo(_projectId);
pricePerTokenInWei = projectIdToPricePerTokenInWei[_projectId];
whitePerTokenInWei = projectIdToWhitePrice[_projectId];
maxInvocations = projectMaxInvocations[_projectId];
startTime = projectIdToStartTime[_projectId];
disable = projectIdToDisable[_projectId];
}
function getPrice(uint256 _projectId)
internal
view
returns (uint256 price)
{
if (block.timestamp < projectIdToStartTime[_projectId]) {
price = projectIdToWhitePrice[_projectId];
} else {
price = projectIdToPricePerTokenInWei[_projectId];
}
return price;
}
function getWhitelists(uint256 _projectId)
external
view
returns (address[] memory)
{
EnumerableMap.AddressToBoolMap storage set = projectIdToWhitelists[
_projectId
];
return set.values();
}
}
文件 12 的 17:ProxyConfigUtils.sol
pragma solidity >=0.8.0 <0.9.0;
import "./ConfigUtils.sol";
import "@openzeppelin/contracts/utils/StorageSlot.sol";
library ProxyConfigUtils{
using ConfigUtils for IConfig;
bytes32 internal constant _CONFIG_SLOT = 0x54c601f62ced84cb3960726428d8409adc363a3fa5c7abf6dba0c198dcc43c14;
function _getConfig() internal view returns(IConfig addr){
address configAddr = StorageSlot.getAddressSlot(_CONFIG_SLOT).value;
require(configAddr != address(0x0), "SC133: config not set");
return IConfig(configAddr);
}
function _setConfig(IConfig config) internal{
ConfigUtils._checkConfig(config);
StorageSlot.getAddressSlot(_CONFIG_SLOT).value = address(config);
}
function _getContractAddress(bytes32 key) internal view returns(address){
return _getConfig().getAddressByKey(key);
}
function _getValueOfUint256(bytes32 key) internal view returns(uint256){
return _getConfig().getUint256ByKey(key);
}
}
文件 13 的 17: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() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
文件 14 的 17:Registry.sol
pragma solidity >=0.8.0 <0.9.0;
library Registry {
bytes32 internal constant SUPER_ADMIN_ROLE = 0x0000000000000000000000000000000000000000000000000000000000000000;
bytes32 internal constant MINTER_ROLE = keccak256("minter.role");
bytes32 internal constant ADMIN_ROLE = keccak256("admin.role");
bytes32 internal constant DEPOSIT_ROLE = keccak256("deposit.role");
bytes32 internal constant OPERATOR_ROLE = keccak256("operator.role");
bytes32 internal constant POOL_CENTER = keccak256("pool.center");
bytes32 internal constant ALLERIA = keccak256("alleria.address");
bytes32 internal constant PLATFORM = keccak256("platform.address");
bytes32 internal constant OTHER = keccak256("other.address");
bytes32 internal constant CURATOR_CENTER = keccak256("curator.center");
bytes32 internal constant ARTIST_RATE = keccak256("artist.rate");
bytes32 internal constant CURATOR_RATE = keccak256("curator.rate");
bytes32 internal constant GLOBAL_POOL_RATE = keccak256("global.pool.rate");
bytes32 internal constant COLLECTION_POOL_RATE = keccak256("collection.pool.rate");
bytes32 internal constant OTHER_RATE = keccak256("other.rate");
address internal constant SENTIENT_ADDRESS = 0x0000000000000000000000000000000000000001;
}
文件 15 的 17:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/draft-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 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
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");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
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");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
文件 16 的 17:StorageSlot.sol
pragma solidity ^0.8.0;
library StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
assembly {
r.slot := slot
}
}
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
assembly {
r.slot := slot
}
}
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
assembly {
r.slot := slot
}
}
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
assembly {
r.slot := slot
}
}
}
文件 17 的 17:draft-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);
}
{
"compilationTarget": {
"contracts/MinterSetPrice.sol": "MinterSetPrice"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 100
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_genArt721Address","type":"address"},{"internalType":"address","name":"_minterFilter","type":"address"},{"internalType":"contract IConfig","name":"_config","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_pricePerTokenInWei","type":"uint256"}],"name":"PricePerTokenInWeiUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"},{"indexed":true,"internalType":"address","name":"_currencyAddress","type":"address"},{"indexed":false,"internalType":"string","name":"_currencySymbol","type":"string"}],"name":"ProjectCurrencyInfoUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"projectId","type":"uint256"},{"indexed":false,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"mintCount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"total","type":"uint256"}],"name":"Purchase","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_purchaseToDisabled","type":"bool"}],"name":"PurchaseToDisabledUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"projectId","type":"uint256"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxInvocations","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTime","type":"uint256"},{"indexed":false,"internalType":"bool","name":"disable","type":"bool"}],"name":"SetProjectMintInfo","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"projectId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxInvocations","type":"uint256"}],"name":"UpdateProjectMaxInvocations","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"projectId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTime","type":"uint256"}],"name":"UpdateProjectStartTime","type":"event"},{"inputs":[],"name":"MAX_ADDITIONAL_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_WHITE_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"address[]","name":"_addrs","type":"address[]"}],"name":"addProjectWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"canArtistModify","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultAdditionalPayee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultWhiteListMintCount","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"genArt721CoreAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConfig","outputs":[{"internalType":"contract IConfig","name":"config","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"getMintInfo","outputs":[{"internalType":"uint256","name":"pricePerTokenInWei","type":"uint256"},{"internalType":"uint256","name":"whitePerTokenInWei","type":"uint256"},{"internalType":"uint256","name":"invocations","type":"uint256"},{"internalType":"uint256","name":"maxInvocations","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"bool","name":"disable","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"getPriceInfo","outputs":[{"internalType":"bool","name":"isConfigured","type":"bool"},{"internalType":"uint256","name":"tokenPriceInWei","type":"uint256"},{"internalType":"uint256","name":"whitePriceInWei","type":"uint256"},{"internalType":"address","name":"currencyAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"getWhitelists","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxBatchMintCount","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterFilterAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterType","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"projectIdToAdditionalPayee","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"projectIdToAdditionalPayeePercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"projectIdToMintCurrency","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"projectIdWhiteListMintCounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"projectMaxHasBeenInvoked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"projectMaxInvocations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"uint8","name":"mintCount","type":"uint8"}],"name":"purchase","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"uint8","name":"_mintCount","type":"uint8"}],"name":"purchaseTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_pricePerTokenInWei","type":"uint256"},{"internalType":"uint256","name":"_maxInvocations","type":"uint256"},{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"bool","name":"_disable","type":"bool"},{"internalType":"address[]","name":"_addrs","type":"address[]"},{"internalType":"uint256[]","name":"_rates","type":"uint256[]"}],"name":"setProjectMintInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"togglePurchaseToDisabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_flag","type":"bool"}],"name":"updateCanArtistModify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"updateDefaultAdditionalPayee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_count","type":"uint8"}],"name":"updateDefaultWhiteListMintCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_count","type":"uint8"}],"name":"updateMaxBatchMintCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"uint256","name":"_maxInvocations","type":"uint256"}],"name":"updateMaxInvocations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_count","type":"uint8"}],"name":"updateMaxMintBatchCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"uint256","name":"_pricePerTokenInWei","type":"uint256"}],"name":"updatePricePerTokenInWei","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"uint256","name":"_percentage","type":"uint256"}],"name":"updateProjectAdditionalPayeePercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"address payable","name":"_additionalAddr","type":"address"}],"name":"updateProjectIdToAdditionalPayee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"updateProjectIdWhiteListMintCounts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"updateProjectWhitelistMaxLength","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"updateProjectWhitelistPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"uint256","name":"_startTime","type":"uint256"}],"name":"updateStartTime","outputs":[],"stateMutability":"nonpayable","type":"function"}]