文件 1 的 35:AccessControl.sol
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
return _roles[role].members[account];
}
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(uint160(account), 20),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
return _roles[role].adminRole;
}
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}
文件 2 的 35: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);
}
}
}
}
文件 3 的 35:Common.sol
pragma solidity ^0.8.0;
enum ItemType {
Empty,
Mainhand,
Offhand,
Pet
}
struct Item {
uint256 itemId;
uint8 powerLevel;
ItemType itemType;
}
function encodeOwnerIdAndItem(
uint256 ownerId,
Item memory item
) pure returns (bytes memory) {
return abi.encode(ownerId, item);
}
function decodeOwnerIdAndItem(
bytes calldata _data
) pure returns (uint256, Item memory) {
uint256 ownerId = abi.decode(_data[:32], (uint256));
Item memory item;
item.itemId = abi.decode(_data[32:64], (uint256));
item.powerLevel = abi.decode(_data[64:96], (uint8));
item.itemType = abi.decode(_data[96:], (ItemType));
return (ownerId, item);
}
contract CommonConstants {
bytes4 constant internal ERC1155_RECEIVED_VALUE = 0xf23a6e61;
bytes4 constant internal ERC1155_BATCH_RECEIVED_VALUE = 0xbc197c81;
}
文件 4 的 35:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 5 的 35:Counters.sol
pragma solidity ^0.8.0;
library Counters {
struct Counter {
uint256 _value;
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
unchecked {
counter._value += 1;
}
}
function decrement(Counter storage counter) internal {
uint256 value = counter._value;
require(value > 0, "Counter: decrement overflow");
unchecked {
counter._value = value - 1;
}
}
function reset(Counter storage counter) internal {
counter._value = 0;
}
}
文件 6 的 35:ECDSA.sol
pragma solidity ^0.8.0;
import "../Strings.sol";
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV
}
function _throwError(RecoverError error) private pure {
if (error == RecoverError.NoError) {
return;
} else if (error == RecoverError.InvalidSignature) {
revert("ECDSA: invalid signature");
} else if (error == RecoverError.InvalidSignatureLength) {
revert("ECDSA: invalid signature length");
} else if (error == RecoverError.InvalidSignatureS) {
revert("ECDSA: invalid signature 's' value");
} else if (error == RecoverError.InvalidSignatureV) {
revert("ECDSA: invalid signature 'v' value");
}
}
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else if (signature.length == 64) {
bytes32 r;
bytes32 vs;
assembly {
r := mload(add(signature, 0x20))
vs := mload(add(signature, 0x40))
}
return tryRecover(hash, r, vs);
} else {
return (address(0), RecoverError.InvalidSignatureLength);
}
}
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, signature);
_throwError(error);
return recovered;
}
function tryRecover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address, RecoverError) {
bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
uint8 v = uint8((uint256(vs) >> 255) + 27);
return tryRecover(hash, v, r, s);
}
function recover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, r, vs);
_throwError(error);
return recovered;
}
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address, RecoverError) {
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS);
}
if (v != 27 && v != 28) {
return (address(0), RecoverError.InvalidSignatureV);
}
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature);
}
return (signer, RecoverError.NoError);
}
function recover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, v, r, s);
_throwError(error);
return recovered;
}
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
}
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
}
}
文件 7 的 35:ERC1155.sol
pragma solidity ^0.8.0;
import "./IERC1155.sol";
import "./IERC1155Receiver.sol";
import "./extensions/IERC1155MetadataURI.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/introspection/ERC165.sol";
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
using Address for address;
mapping(uint256 => mapping(address => uint256)) private _balances;
mapping(address => mapping(address => bool)) private _operatorApprovals;
string private _uri;
constructor(string memory uri_) {
_setURI(uri_);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC1155).interfaceId ||
interfaceId == type(IERC1155MetadataURI).interfaceId ||
super.supportsInterface(interfaceId);
}
function uri(uint256) public view virtual override returns (string memory) {
return _uri;
}
function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
require(account != address(0), "ERC1155: address zero is not a valid owner");
return _balances[id][account];
}
function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
public
view
virtual
override
returns (uint256[] memory)
{
require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");
uint256[] memory batchBalances = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts[i], ids[i]);
}
return batchBalances;
}
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
return _operatorApprovals[account][operator];
}
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not token owner nor approved"
);
_safeTransferFrom(from, to, id, amount, data);
}
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not token owner nor approved"
);
_safeBatchTransferFrom(from, to, ids, amounts, data);
}
function _safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
uint256[] memory ids = _asSingletonArray(id);
uint256[] memory amounts = _asSingletonArray(amount);
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
emit TransferSingle(operator, from, to, id, amount);
_afterTokenTransfer(operator, from, to, ids, amounts, data);
_doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
}
function _safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
}
emit TransferBatch(operator, from, to, ids, amounts);
_afterTokenTransfer(operator, from, to, ids, amounts, data);
_doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
}
function _setURI(string memory newuri) internal virtual {
_uri = newuri;
}
function _mint(
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
address operator = _msgSender();
uint256[] memory ids = _asSingletonArray(id);
uint256[] memory amounts = _asSingletonArray(amount);
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
_balances[id][to] += amount;
emit TransferSingle(operator, address(0), to, id, amount);
_afterTokenTransfer(operator, address(0), to, ids, amounts, data);
_doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);
}
function _mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; i++) {
_balances[ids[i]][to] += amounts[i];
}
emit TransferBatch(operator, address(0), to, ids, amounts);
_afterTokenTransfer(operator, address(0), to, ids, amounts, data);
_doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
}
function _burn(
address from,
uint256 id,
uint256 amount
) internal virtual {
require(from != address(0), "ERC1155: burn from the zero address");
address operator = _msgSender();
uint256[] memory ids = _asSingletonArray(id);
uint256[] memory amounts = _asSingletonArray(amount);
_beforeTokenTransfer(operator, from, address(0), ids, amounts, "");
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
emit TransferSingle(operator, from, address(0), id, amount);
_afterTokenTransfer(operator, from, address(0), ids, amounts, "");
}
function _burnBatch(
address from,
uint256[] memory ids,
uint256[] memory amounts
) internal virtual {
require(from != address(0), "ERC1155: burn from the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, address(0), ids, amounts, "");
for (uint256 i = 0; i < ids.length; i++) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
}
emit TransferBatch(operator, from, address(0), ids, amounts);
_afterTokenTransfer(operator, from, address(0), ids, amounts, "");
}
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC1155: setting approval status for self");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {}
function _afterTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {}
function _doSafeTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
if (response != IERC1155Receiver.onERC1155Received.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _doSafeBatchTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
bytes4 response
) {
if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
uint256[] memory array = new uint256[](1);
array[0] = element;
return array;
}
}
文件 8 的 35:ERC1155Holder.sol
pragma solidity ^0.8.0;
import "./ERC1155Receiver.sol";
contract ERC1155Holder is ERC1155Receiver {
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] memory,
uint256[] memory,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155BatchReceived.selector;
}
}
文件 9 的 35:ERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../IERC1155Receiver.sol";
import "../../../utils/introspection/ERC165.sol";
abstract contract ERC1155Receiver is ERC165, IERC1155Receiver {
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);
}
}
文件 10 的 35:ERC1155Supply.sol
pragma solidity ^0.8.0;
import "../ERC1155.sol";
abstract contract ERC1155Supply is ERC1155 {
mapping(uint256 => uint256) private _totalSupply;
function totalSupply(uint256 id) public view virtual returns (uint256) {
return _totalSupply[id];
}
function exists(uint256 id) public view virtual returns (bool) {
return ERC1155Supply.totalSupply(id) > 0;
}
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
if (from == address(0)) {
for (uint256 i = 0; i < ids.length; ++i) {
_totalSupply[ids[i]] += amounts[i];
}
}
if (to == address(0)) {
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 supply = _totalSupply[id];
require(supply >= amount, "ERC1155: burn amount exceeds totalSupply");
unchecked {
_totalSupply[id] = supply - amount;
}
}
}
}
}
文件 11 的 35:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 12 的 35:ERC20.sol
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function decimals() public view virtual override returns (uint8) {
return 18;
}
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
function _transfer(
address from,
address to,
uint256 amount
) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
}
_balances[to] += amount;
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
}
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _spendAllowance(
address owner,
address spender,
uint256 amount
) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}
文件 13 的 35:ERC721.sol
pragma solidity ^0.8.0;
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
using Address for address;
using Strings for uint256;
string private _name;
string private _symbol;
mapping(uint256 => address) private _owners;
mapping(address => uint256) private _balances;
mapping(uint256 => address) private _tokenApprovals;
mapping(address => mapping(address => bool)) private _operatorApprovals;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: address zero is not a valid owner");
return _balances[owner];
}
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _owners[tokenId];
require(owner != address(0), "ERC721: invalid token ID");
return owner;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
_requireMinted(tokenId);
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
function _baseURI() internal view virtual returns (string memory) {
return "";
}
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not token owner nor approved for all"
);
_approve(to, tokenId);
}
function getApproved(uint256 tokenId) public view virtual override returns (address) {
_requireMinted(tokenId);
return _tokenApprovals[tokenId];
}
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");
_transfer(from, to, tokenId);
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory data
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");
_safeTransfer(from, to, tokenId, data);
}
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory data
) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer");
}
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _owners[tokenId] != address(0);
}
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
address owner = ERC721.ownerOf(tokenId);
return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
}
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
function _safeMint(
address to,
uint256 tokenId,
bytes memory data
) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
_afterTokenTransfer(address(0), to, tokenId);
}
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
_approve(address(0), tokenId);
_balances[owner] -= 1;
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
_afterTokenTransfer(owner, address(0), tokenId);
}
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
_afterTokenTransfer(from, to, tokenId);
}
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC721: approve to caller");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
function _requireMinted(uint256 tokenId) internal view virtual {
require(_exists(tokenId), "ERC721: invalid token ID");
}
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory data
) private returns (bool) {
if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
function _afterTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
}
文件 14 的 35:ERC721Enumerable.sol
pragma solidity ^0.8.0;
import "../ERC721.sol";
import "./IERC721Enumerable.sol";
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
mapping(address => mapping(uint256 => uint256)) private _ownedTokens;
mapping(uint256 => uint256) private _ownedTokensIndex;
uint256[] private _allTokens;
mapping(uint256 => uint256) private _allTokensIndex;
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
}
function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
return _ownedTokens[owner][index];
}
function totalSupply() public view virtual override returns (uint256) {
return _allTokens.length;
}
function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
return _allTokens[index];
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual override {
super._beforeTokenTransfer(from, to, tokenId);
if (from == address(0)) {
_addTokenToAllTokensEnumeration(tokenId);
} else if (from != to) {
_removeTokenFromOwnerEnumeration(from, tokenId);
}
if (to == address(0)) {
_removeTokenFromAllTokensEnumeration(tokenId);
} else if (to != from) {
_addTokenToOwnerEnumeration(to, tokenId);
}
}
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
uint256 length = ERC721.balanceOf(to);
_ownedTokens[to][length] = tokenId;
_ownedTokensIndex[tokenId] = length;
}
function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
_allTokensIndex[tokenId] = _allTokens.length;
_allTokens.push(tokenId);
}
function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
uint256 tokenIndex = _ownedTokensIndex[tokenId];
if (tokenIndex != lastTokenIndex) {
uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
_ownedTokens[from][tokenIndex] = lastTokenId;
_ownedTokensIndex[lastTokenId] = tokenIndex;
}
delete _ownedTokensIndex[tokenId];
delete _ownedTokens[from][lastTokenIndex];
}
function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
uint256 lastTokenIndex = _allTokens.length - 1;
uint256 tokenIndex = _allTokensIndex[tokenId];
uint256 lastTokenId = _allTokens[lastTokenIndex];
_allTokens[tokenIndex] = lastTokenId;
_allTokensIndex[lastTokenId] = tokenIndex;
delete _allTokensIndex[tokenId];
_allTokens.pop();
}
}
文件 15 的 35:ERC721Holder.sol
pragma solidity ^0.8.0;
import "../IERC721Receiver.sol";
contract ERC721Holder is IERC721Receiver {
function onERC721Received(
address,
address,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC721Received.selector;
}
}
文件 16 的 35:IAccessControl.sol
pragma solidity ^0.8.0;
interface IAccessControl {
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
function hasRole(bytes32 role, address account) external view returns (bool);
function getRoleAdmin(bytes32 role) external view returns (bytes32);
function grantRole(bytes32 role, address account) external;
function revokeRole(bytes32 role, address account) external;
function renounceRole(bytes32 role, address account) external;
}
文件 17 的 35:IERC1155.sol
pragma solidity ^0.8.0;
import "../token/ERC1155/IERC1155.sol";
文件 18 的 35:IERC1155MetadataURI.sol
pragma solidity ^0.8.0;
import "../IERC1155.sol";
interface IERC1155MetadataURI is IERC1155 {
function uri(uint256 id) external view returns (string memory);
}
文件 19 的 35:IERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155Receiver is IERC165 {
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}
文件 20 的 35:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 21 的 35: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);
}
文件 22 的 35:IERC20Metadata.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
文件 23 的 35:IERC721.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
function approve(address to, uint256 tokenId) external;
function setApprovalForAll(address operator, bool _approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
文件 24 的 35:IERC721Enumerable.sol
pragma solidity ^0.8.0;
import "../IERC721.sol";
interface IERC721Enumerable is IERC721 {
function totalSupply() external view returns (uint256);
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);
function tokenByIndex(uint256 index) external view returns (uint256);
}
文件 25 的 35:IERC721Metadata.sol
pragma solidity ^0.8.0;
import "../IERC721.sol";
interface IERC721Metadata is IERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
文件 26 的 35:IERC721Receiver.sol
pragma solidity ^0.8.0;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 27 的 35:IGovernor.sol
pragma solidity ^0.8.0;
import "../utils/introspection/ERC165.sol";
abstract contract IGovernor is IERC165 {
enum ProposalState {
Pending,
Active,
Canceled,
Defeated,
Succeeded,
Queued,
Expired,
Executed
}
event ProposalCreated(
uint256 proposalId,
address proposer,
address[] targets,
uint256[] values,
string[] signatures,
bytes[] calldatas,
uint256 startBlock,
uint256 endBlock,
string description
);
event ProposalCanceled(uint256 proposalId);
event ProposalExecuted(uint256 proposalId);
event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason);
event VoteCastWithParams(
address indexed voter,
uint256 proposalId,
uint8 support,
uint256 weight,
string reason,
bytes params
);
function name() public view virtual returns (string memory);
function version() public view virtual returns (string memory);
function COUNTING_MODE() public pure virtual returns (string memory);
function hashProposal(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) public pure virtual returns (uint256);
function state(uint256 proposalId) public view virtual returns (ProposalState);
function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256);
function proposalDeadline(uint256 proposalId) public view virtual returns (uint256);
function votingDelay() public view virtual returns (uint256);
function votingPeriod() public view virtual returns (uint256);
function quorum(uint256 blockNumber) public view virtual returns (uint256);
function getVotes(address account, uint256 blockNumber) public view virtual returns (uint256);
function getVotesWithParams(
address account,
uint256 blockNumber,
bytes memory params
) public view virtual returns (uint256);
function hasVoted(uint256 proposalId, address account) public view virtual returns (bool);
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public virtual returns (uint256 proposalId);
function execute(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) public payable virtual returns (uint256 proposalId);
function castVote(uint256 proposalId, uint8 support) public virtual returns (uint256 balance);
function castVoteWithReason(
uint256 proposalId,
uint8 support,
string calldata reason
) public virtual returns (uint256 balance);
function castVoteWithReasonAndParams(
uint256 proposalId,
uint8 support,
string calldata reason,
bytes memory params
) public virtual returns (uint256 balance);
function castVoteBySig(
uint256 proposalId,
uint8 support,
uint8 v,
bytes32 r,
bytes32 s
) public virtual returns (uint256 balance);
function castVoteWithReasonAndParamsBySig(
uint256 proposalId,
uint8 support,
string calldata reason,
bytes memory params,
uint8 v,
bytes32 r,
bytes32 s
) public virtual returns (uint256 balance);
}
文件 28 的 35:MagicFolk.sol
pragma solidity ^0.8.0;
import "../utils/Common.sol";
import "../utils/SigVer.sol";
import "./MagicFolkGems.sol";
import "./MagicFolkItems.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/interfaces/IERC721.sol";
import "@openzeppelin/contracts/interfaces/IERC1155.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
contract MagicFolk is
ERC165,
ERC721,
ERC721Enumerable,
ERC721Holder,
CommonConstants,
IERC1155Receiver,
ReentrancyGuard,
SigVer,
AccessControl,
Ownable
{
using Counters for Counters.Counter;
struct Stats {
uint8 powerLevel;
Item mainHand;
Item offHand;
Item pet;
}
struct Payee {
address wallet;
uint16 percentagePoints;
bytes24 payeeId;
}
Payee[11] public _payees;
event Equipped(
uint256 indexed _tokenId,
uint256 indexed _itemId,
ItemType _itemType
);
event Unequipped(
uint256 indexed _tokenId,
uint256 indexed _itemId,
ItemType _itemType
);
event Staked(uint256 indexed _tokenId, address owner);
event Unstaked(uint256 indexed _tokenId, address owner);
event publicSaleToggled(bool state);
event privateSaleToggled(bool state);
event stakingToggled(bool state);
mapping(uint256 => Stats) private _tokenStats;
mapping(address => uint256) private _totalMintsPerAddress;
mapping(address => uint256) public _mintNonce;
mapping(uint256 => uint256) private _lastClaims;
mapping(uint256 => address) public _tokenOwners;
mapping(address => uint256[]) public _stakedTokens;
Counters.Counter private _tokenIdCounter;
MagicFolkItems MAGIC_FOLK_MAINHAND;
MagicFolkItems MAGIC_FOLK_OFFHAND;
MagicFolkItems MAGIC_FOLK_PET;
MagicFolkGems MAGIC_FOLK_GEMS;
uint256 public constant PUBLIC_ALLOWANCE = 10;
uint256 public constant MAX_MINT = 9500;
uint256 public constant TEAM_MINT = 500;
uint256 public constant PRIVATE_PRICE = 0.1 ether;
uint256 public constant PUBLIC_PRICE = 0.125 ether;
address public constant FEE_ADDRESS =
0x670326f4470d4D2F5347377Ff187717a81aB1318;
uint256 public _fees = 60.0 ether;
uint256 public _teamMinted = 0;
address public _signer;
uint256 _gemRate = 10;
uint256 constant SECONDS_PER_DAY = 86400;
string public _URI = "https://cdn-stg.magicfolk.io/api/genesis/";
uint8[MAX_MINT + TEAM_MINT] private _basePowerLevels;
bool private _publicSale = false;
bool private _privateSale = false;
bool private _powerLevelsSet = false;
bool public _publicSaleSignatureRequired = true;
bool public _stakingEnabled = false;
bool public _listable = false;
bool public _initialFeesWithdrawn = false;
constructor(
address signer,
address magicFolkMainhand,
address magicFolkOffhand,
address magicFolkPet
) ERC721("Magic Folk", "MF") {
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_signer = signer;
MAGIC_FOLK_MAINHAND = MagicFolkItems(magicFolkMainhand);
MAGIC_FOLK_OFFHAND = MagicFolkItems(magicFolkOffhand);
MAGIC_FOLK_PET = MagicFolkItems(magicFolkPet);
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_payees[0] = Payee(
0x586a6c03DA4959C6341845C210b4CdBec930Af37,
265,
"ELON_MUSK"
);
_payees[1] = Payee(
0xa8fD19cb5F949677504DD90f8B6efe044286e6B2,
80,
"DONALD_TRUMP"
);
_payees[2] = Payee(
0xD85aA7341a63B413972c8e8D63Ae7a7bC08A5aFD,
25,
"WARREN_BUFFET"
);
_payees[3] = Payee(
0x4fB91f8b17702aFf47BE977A226dDdabf5475661,
25,
"JEFF_BEZOS"
);
_payees[4] = Payee(
0x7913FEDA30503465EDAdc674a66fbDcB581f6840,
120,
"BILL_GATES"
);
_payees[5] = Payee(
0x2E8a3F14feDA7FA7690260a06A1656BFe20bE1aC,
60,
"LEBRON_JAMES"
);
_payees[6] = Payee(
0x60d1082D0fdaB22990f56A70B68AdDC049F75EC8,
100,
"NICOLAS_CAGE"
);
_payees[7] = Payee(
0x71dcB19A6D322C9D826aA6b61442828436Aa6fb2,
50,
"KENDRICK_LAMAR"
);
_payees[8] = Payee(
0x996107A817f0fbaF389F1DCC1A48Dfb2eDb78D33,
25,
"R_KELLY"
);
_payees[9] = Payee(
0xAB1ca28b50EdC107023d81e71640da3ee26F93A0,
150,
"LIL_DICKY"
);
_payees[10] = Payee(
0x3750737d7fbF284705a329AB674D9309485B5bE2,
100,
"JIMMY_CARR"
);
uint256 percentagePointSum = 0;
for (uint256 i = 0; i < _payees.length; i++) {
percentagePointSum += _payees[i].percentagePoints;
}
require(percentagePointSum == 1000, "INVALID_PERCENTAGES");
}
function setMagicFolkGemsContract(address magicFolkGems)
public
onlyRole(DEFAULT_ADMIN_ROLE)
{
MAGIC_FOLK_GEMS = MagicFolkGems(magicFolkGems);
}
function setMagicFolkItemsContract(
address magicFolkItems,
ItemType itemType
) public onlyRole(DEFAULT_ADMIN_ROLE) {
if (itemType == ItemType.Mainhand) {
MAGIC_FOLK_MAINHAND = MagicFolkItems(magicFolkItems);
} else if (itemType == ItemType.Offhand) {
MAGIC_FOLK_OFFHAND = MagicFolkItems(magicFolkItems);
} else if (itemType == ItemType.Pet) {
MAGIC_FOLK_PET = MagicFolkItems(magicFolkItems);
} else {
revert();
}
}
function setSignerAddress(address signer)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
_signer = signer;
}
function setBaseURI(string calldata URI)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
_URI = URI;
}
function enableListings() external onlyRole(DEFAULT_ADMIN_ROLE) {
_listable = true;
}
function isApprovedForAll(address owner, address operator)
public
view
override
returns (bool)
{
if (!_listable) {
return false;
} else {
return super.isApprovedForAll(owner, operator);
}
}
function _baseURI() internal view override returns (string memory) {
return _URI;
}
function publicSaleActive() public view returns (bool) {
return _publicSaleActive();
}
function togglePublicSale() public onlyRole(DEFAULT_ADMIN_ROLE) {
require(!_privateSaleActive());
_publicSale = !_publicSale;
emit publicSaleToggled(_publicSale);
}
function toggleStaking() external onlyRole(DEFAULT_ADMIN_ROLE) {
_stakingEnabled = !_stakingEnabled;
emit stakingToggled(_stakingEnabled);
}
function togglePublicSaleSigRequired() public onlyRole(DEFAULT_ADMIN_ROLE) {
_publicSaleSignatureRequired = !_publicSaleSignatureRequired;
}
function privateSaleActive() public view returns (bool) {
return _privateSaleActive();
}
function togglePrivateSale() public onlyRole(DEFAULT_ADMIN_ROLE) {
require(!_publicSaleActive());
_privateSale = !_privateSale;
emit privateSaleToggled(_privateSale);
}
function setPowerLevels(
uint8[] calldata powerLevels,
uint256[] calldata tokenIds
) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(!_powerLevelsSet);
require(powerLevels.length == tokenIds.length);
for (uint256 i = 0; i < powerLevels.length; i++) {
_basePowerLevels[tokenIds[i]] = powerLevels[i];
}
}
function lockPowerLevels() external onlyRole(DEFAULT_ADMIN_ROLE) {
require(!_powerLevelsSet);
_powerLevelsSet = true;
}
function safeMintPublic(
uint256 qty,
uint256 mintNonce,
bytes32 msgHash,
bytes calldata signature
) external payable nonReentrant {
address to = _msgSender();
require(_publicSaleActive(), "Public sale not active");
require(msg.value >= qty * PUBLIC_PRICE, "Insufficient funds");
require(qty <= PUBLIC_ALLOWANCE, "EXCEED_ALLOWANCE");
require(
_tokenIdCounter.current() + qty - _teamMinted <= MAX_MINT,
"SOLD_OUT"
);
require(mintNonce == _mintNonce[to], "INVALID_NONCE");
require(
_verifyMsg(to, mintNonce, msgHash, signature, _signer) ||
!_publicSaleSignatureRequired,
"INVALID_SIG"
);
for (uint256 i = 0; i < qty; i++) {
_safeMint(to);
}
_mintNonce[to]++;
}
function safeMintPrivate(
uint256 qty,
uint256 privateSaleAllowance,
bytes32 msgHash,
bytes calldata signature
) external payable nonReentrant {
address to = _msgSender();
require(_privateSaleActive(), "Private sale not active");
require(msg.value >= qty * PRIVATE_PRICE, "Insufficient funds");
require(
qty + _totalMintsPerAddress[to] <= privateSaleAllowance,
"Exceeded allowance"
);
require(
_verifyMsg(to, privateSaleAllowance, msgHash, signature, _signer),
"INVALID_SIG"
);
require(
_tokenIdCounter.current() + qty - _teamMinted <= MAX_MINT,
"SOLD_OUT"
);
for (uint256 i = 0; i < qty; i++) {
_safeMint(to);
}
_totalMintsPerAddress[to] += qty;
}
function teamMint(uint256 qty) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(_publicSaleActive() || _privateSaleActive());
address to = msg.sender;
require(qty + _teamMinted <= TEAM_MINT, "TEAM_MINT_LIMIT_REACHED");
for (uint256 i = 0; i < qty; i++) {
_safeMint(to);
}
_teamMinted += qty;
}
function isTokenStaked(uint256 tokenId) public view returns (bool) {
return _isTokenStaked(tokenId);
}
function stakeToken(uint256 tokenId) external nonReentrant {
_stakeToken(msg.sender, tokenId);
}
function stakeTokens(uint256[] calldata tokenIds) external nonReentrant {
for (uint256 i = 0; i < tokenIds.length; i++) {
_stakeToken(msg.sender, tokenIds[i]);
}
}
function getQuantityStaked(address owner) public view returns (uint256) {
return _stakedTokens[owner].length;
}
function getStakedTokens(address owner)
public
view
returns (uint256[] memory)
{
return _stakedTokens[owner];
}
function tokensOfOwner(address owner)
public
view
returns (uint256[] memory)
{
uint256 totalOwned = balanceOf(owner);
uint256[] memory ret = new uint256[](totalOwned);
for (uint256 i = 0; i < totalOwned; i++) {
ret[i] = ERC721Enumerable.tokenOfOwnerByIndex(owner, i);
}
return ret;
}
function setGemRate(uint256 newGemRate)
public
onlyRole(DEFAULT_ADMIN_ROLE)
{
_setGemRate(newGemRate);
}
function _stakeToken(address user, uint256 tokenId) internal {
require(_isApprovedOrOwner(user, tokenId), "NOT_AUTHORISED");
require(!_isTokenStaked(tokenId), "ALREADY_STAKED");
_setLastClaim(tokenId);
_tokenOwners[tokenId] = user;
_stakedTokens[user].push(tokenId);
safeTransferFrom(user, address(this), tokenId);
}
function unstakeToken(uint256 tokenId) external nonReentrant {
_unstakeToken(msg.sender, tokenId);
}
function unstakeTokens(uint256[] calldata tokenIds) external nonReentrant {
for (uint256 i = 0; i < tokenIds.length; i++) {
_unstakeToken(msg.sender, tokenIds[i]);
}
}
function claimGems(uint256 tokenId) public nonReentrant {
require(_isTokenStaked(tokenId), "NOT_STAKED");
require(_tokenOwners[tokenId] == _msgSender(), "NOT_AUTHORISED");
uint256 allocation = _calcAllocation(tokenId);
require(allocation > 0, "NO_GEMS");
MAGIC_FOLK_GEMS.mint(_msgSender(), allocation);
_setLastClaim(tokenId);
}
function claimAllGems() external {
uint256[] memory stakedTokens = _stakedTokens[_msgSender()];
for (uint256 i = 0; i < stakedTokens.length; i++) {
if (_calcAllocation(stakedTokens[i]) > 0) {
claimGems(stakedTokens[i]);
}
}
}
function getAllocation(uint256 tokenId) public view returns (uint256) {
return _calcAllocation(tokenId);
}
function getTotalUnclaimed(address owner) public view returns (uint256) {
uint256 sum = 0;
uint256[] memory stakedTokens = _stakedTokens[owner];
for (uint256 i = 0; i < stakedTokens.length; i++) {
sum += _calcAllocation(stakedTokens[i]);
}
return sum;
}
function _safeMint(address to) internal {
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(to, tokenId);
_rollStats(tokenId);
}
function _rollStats(uint256 tokenId) internal {
_setBasePowerLevel(tokenId, 5);
}
modifier tokenExists(uint256 tokenId) {
require(_exists(tokenId), "Token does not exist.");
_;
}
function getStats(uint256 tokenId)
public
view
tokenExists(tokenId)
returns (Stats memory)
{
Stats memory stats = _getStats(tokenId);
require(
_basePowerLevels[tokenId] > 0,
"Token traits have not been initialized."
);
return stats;
}
function getGemRate() public view returns (uint256) {
return _getGemRate();
}
function getBasePowerLevel(uint256 tokenId)
public
view
tokenExists(tokenId)
returns (uint8)
{
return _getBasePowerLevel(tokenId);
}
function onERC1155Received(
address _operator,
address _from,
uint256 _id,
uint256 _value,
bytes calldata _data
) external override returns (bytes4) {
require(_operator == _from, "NOT_AUTHORISED");
require(
msg.sender == address(MAGIC_FOLK_MAINHAND) ||
msg.sender == address(MAGIC_FOLK_OFFHAND) ||
msg.sender == address(MAGIC_FOLK_PET),
"INVALID_TOKEN_TYPE"
);
(uint256 _nftTokenId, Item memory _item) = decodeOwnerIdAndItem(_data);
require(
ownerOf(_nftTokenId) == _from || _tokenOwners[_nftTokenId] == _from,
"NOT_YOUR_NFT"
);
require(_item.itemId == _id, "INVALID_DECODED_ID");
require(_value == 1, "CAN_ONLY_EQUIP_ONE");
require(
_item.itemType == MagicFolkItems(msg.sender)._itemType(),
"INVALID_ITEMTYPE"
);
_equip(_item, _nftTokenId);
return ERC1155_RECEIVED_VALUE;
}
function unequip(address from, bytes calldata data) external {
require(
msg.sender == address(MAGIC_FOLK_MAINHAND) ||
msg.sender == address(MAGIC_FOLK_OFFHAND) ||
msg.sender == address(MAGIC_FOLK_PET),
"Invalid caller"
);
(uint256 nftTokenId, Item memory item) = decodeOwnerIdAndItem(data);
require(
ownerOf(nftTokenId) == from || _tokenOwners[nftTokenId] == from,
"NOT_YOUR_NFT"
);
_unequip(item, nftTokenId);
IERC1155(msg.sender).safeTransferFrom(
address(this),
from,
item.itemId,
1,
""
);
emit Unequipped(nftTokenId, item.itemId, item.itemType);
}
function onERC1155BatchReceived(
address,
address,
uint256[] memory,
uint256[] memory,
bytes calldata
) external pure override returns (bytes4) {
revert();
}
function withdraw() public onlyRole(DEFAULT_ADMIN_ROLE) {
uint256 amount;
uint256 balance = address(this).balance;
bool success = false;
if (!_initialFeesWithdrawn) {
if (balance <= _fees) {
amount = balance;
} else {
amount = _fees;
}
(success, ) = payable(FEE_ADDRESS).call{ value: amount }("");
require(success, "NOPE");
_initialFeesWithdrawn = true;
} else {
for (uint256 i = 0; i < _payees.length; i++) {
(success, ) = payable(_payees[i].wallet).call{
value: (balance * _payees[i].percentagePoints) / 1000
}("");
require(success);
}
}
}
function setFees(uint256 newFees) public onlyRole(DEFAULT_ADMIN_ROLE) {
_fees = newFees;
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal override(ERC721, ERC721Enumerable) {
super._beforeTokenTransfer(from, to, tokenId);
}
function supportsInterface(bytes4 interfaceID)
public
view
virtual
override(ERC721, ERC721Enumerable, IERC165, ERC165, AccessControl)
returns (bool)
{
return
super.supportsInterface(interfaceID) ||
interfaceID == type(IERC1155Receiver).interfaceId ||
interfaceID == 0x01ffc9a7 ||
interfaceID == 0x4e2312e0;
}
function _isTokenStaked(uint256 tokenId) internal view returns (bool) {
return ownerOf(tokenId) == address(this);
}
function _unstakeToken(address user, uint256 tokenId) internal {
require(_isTokenStaked(tokenId), "NOT_STAKED");
require(_tokenOwners[tokenId] == user, "NOT_AUTHORISED");
uint256 allocation = _calcAllocation(tokenId);
if (allocation > 0) {
MAGIC_FOLK_GEMS.mint(_msgSender(), allocation);
}
uint256 i = 0;
uint256 lastTokenIndex = _stakedTokens[user].length - 1;
while (_stakedTokens[user][i] != tokenId) {
i++;
}
_stakedTokens[user][i] = _stakedTokens[user][lastTokenIndex];
_stakedTokens[user].pop();
_lastClaims[tokenId] = 0;
delete _tokenOwners[tokenId];
_safeTransfer(address(this), user, tokenId, "");
}
function _publicSaleActive() internal view returns (bool) {
return _publicSale;
}
function _privateSaleActive() internal view returns (bool) {
return _privateSale;
}
function _equip(Item memory _item, uint256 _nftTokenId) internal {
require(
!(_isEquipped(_nftTokenId, _item.itemType)),
"Slot is not empty"
);
Stats memory stats = _getItemStats(_nftTokenId);
if (_item.itemType == ItemType.Mainhand) {
stats.mainHand = _item;
} else if (_item.itemType == ItemType.Offhand) {
stats.offHand = _item;
} else if (_item.itemType == ItemType.Pet) {
stats.pet = _item;
} else {
revert();
}
stats.powerLevel += _item.powerLevel;
_setStats(_nftTokenId, stats);
emit Equipped(_nftTokenId, _item.itemId, _item.itemType);
}
function _unequip(Item memory _item, uint256 _nftTokenId) internal {
require(_isEquipped(_nftTokenId, _item.itemType), "Slot is empty");
Stats memory stats = _getItemStats(_nftTokenId);
if (_item.itemType == ItemType.Mainhand) {
require(stats.mainHand.itemId == _item.itemId, "Incorrect item");
stats.mainHand = _emptyItem();
} else if (_item.itemType == ItemType.Offhand) {
require(stats.offHand.itemId == _item.itemId, "Incorrect item");
stats.offHand = _emptyItem();
} else if (_item.itemType == ItemType.Pet) {
require(stats.pet.itemId == _item.itemId, "Incorrect item");
stats.pet = _emptyItem();
} else {
revert();
}
stats.powerLevel -= _item.powerLevel;
_setStats(_nftTokenId, stats);
}
function _isEquipped(uint256 nftTokenId, ItemType slot)
internal
view
tokenExists(nftTokenId)
returns (bool)
{
Stats memory stats = _getItemStats(nftTokenId);
if (slot == ItemType.Mainhand) {
return stats.mainHand.itemType == ItemType.Mainhand;
} else if (slot == ItemType.Offhand) {
return stats.offHand.itemType == ItemType.Offhand;
} else {
return stats.pet.itemType == ItemType.Pet;
}
}
function _getItemStats(uint256 tokenId)
internal
view
tokenExists(tokenId)
returns (Stats memory)
{
Stats memory stats = _tokenStats[tokenId];
return stats;
}
function _getStats(uint256 tokenId)
internal
view
tokenExists(tokenId)
returns (Stats memory)
{
Stats memory stats = _getItemStats(tokenId);
stats.powerLevel = stats.powerLevel + _getBasePowerLevel(tokenId);
return stats;
}
function _setStats(uint256 tokenId, Stats memory stats)
internal
tokenExists(tokenId)
{
_tokenStats[tokenId] = stats;
}
function _setBasePowerLevel(uint256 tokenId, uint8 _powerLevel)
internal
tokenExists(tokenId)
{
_basePowerLevels[tokenId] = _powerLevel;
}
function _getBasePowerLevel(uint256 tokenId)
internal
view
tokenExists(tokenId)
returns (uint8)
{
return _basePowerLevels[tokenId];
}
function _calcAllocation(uint256 tokenId) internal view returns (uint256) {
Stats memory stats = _getStats(tokenId);
uint256 timeDeltaDays = (block.timestamp - _getLastClaim(tokenId)) /
SECONDS_PER_DAY;
return timeDeltaDays * stats.powerLevel * _gemRate;
}
function _getLastClaim(uint256 tokenId)
internal
view
tokenExists(tokenId)
returns (uint256)
{
return _lastClaims[tokenId];
}
function _setLastClaim(uint256 tokenId) internal tokenExists(tokenId) {
_lastClaims[tokenId] = block.timestamp;
}
function _setGemRate(uint256 newGemRate) internal {
_gemRate = newGemRate;
}
function _getGemRate() internal view returns (uint256) {
return _gemRate;
}
function _emptyItem() internal pure returns (Item memory) {
return Item(0, 0, ItemType.Empty);
}
}
文件 29 的 35:MagicFolkGems.sol
pragma solidity ^0.8.0;
import "../utils/Common.sol";
import "../utils/SigVer.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/interfaces/IERC721.sol";
import "@openzeppelin/contracts/interfaces/IERC1155.sol";
import "@openzeppelin/contracts/governance/IGovernor.sol";
contract MagicFolkGems is ERC20, AccessControl, Ownable, SigVer {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
bytes32 public constant DAO_ROLE = keccak256("DAO_ROLE");
IERC721 MAGIC_FOLK_CONTRACT;
IERC1155 MAGIC_FOLK_MAINHAND;
IERC1155 MAGIC_FOLK_OFFHAND;
IERC1155 MAGIC_FOLK_PET;
IGovernor DAO;
address public _signer;
mapping(address => bool) public _freeGemsClaimed;
bool public _transferLock;
bool public _devMintLock;
bool public _freeGemClaim = true;
constructor(
address magicFolkContract,
address magicFolkMainhand,
address magicFolkOffhand,
address magicFolkPet
) ERC20("MagicFolkGems", "MFGEM") {
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(MINTER_ROLE, magicFolkContract);
MAGIC_FOLK_CONTRACT = IERC721(magicFolkContract);
_grantRole(BURNER_ROLE, magicFolkMainhand);
MAGIC_FOLK_MAINHAND = IERC1155(magicFolkMainhand);
_grantRole(BURNER_ROLE, magicFolkOffhand);
MAGIC_FOLK_OFFHAND = IERC1155(magicFolkOffhand);
_grantRole(BURNER_ROLE, magicFolkPet);
MAGIC_FOLK_PET = IERC1155(magicFolkPet);
_transferLock = true;
}
modifier onlyAdminOrDAO() {
if (
!(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()) ||
hasRole(DAO_ROLE, _msgSender()))
) {
revert("NOT_AUTHORISED");
}
_;
}
function setMagicFolkAddress(address newAddress)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
_revokeRole(MINTER_ROLE, address(MAGIC_FOLK_CONTRACT));
MAGIC_FOLK_CONTRACT = IERC721(newAddress);
_grantRole(MINTER_ROLE, newAddress);
}
function setMagicFolkItemAddress(address newAddress, ItemType itemType)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
address oldAddress;
if (itemType == ItemType.Mainhand) {
oldAddress = address(MAGIC_FOLK_MAINHAND);
MAGIC_FOLK_MAINHAND = IERC1155(newAddress);
} else if (itemType == ItemType.Offhand) {
oldAddress = address(MAGIC_FOLK_OFFHAND);
MAGIC_FOLK_OFFHAND = IERC1155(newAddress);
} else if (itemType == ItemType.Pet) {
oldAddress = address(MAGIC_FOLK_PET);
MAGIC_FOLK_PET = IERC1155(newAddress);
} else {
revert();
}
_revokeRole(MINTER_ROLE, oldAddress);
_revokeRole(BURNER_ROLE, oldAddress);
_grantRole(MINTER_ROLE, newAddress);
_grantRole(BURNER_ROLE, newAddress);
}
function setDAO(address _DAO) public onlyRole(DEFAULT_ADMIN_ROLE) {
require(address(DAO) == address(0), "DAO_ALREADY_SET");
DAO = IGovernor(_DAO);
_grantRole(DAO_ROLE, _DAO);
}
function claimFreeGems(
uint256 qty,
bytes32 msgHash,
bytes calldata signature
) external {
address to = _msgSender();
require(_freeGemClaim, "FREE_GEMZ_DISABLED");
require(
_verifyMsg(to, qty, msgHash, signature, _signer),
"INVALID_SIG"
);
require(!_freeGemsClaimed[to], "GEMZ_ALREADY_CLAIMED");
_mint(to, qty);
_freeGemsClaimed[to] = true;
}
function toggleFreeGems() public onlyRole(DEFAULT_ADMIN_ROLE) {
_freeGemClaim = !_freeGemClaim;
}
function enableTransfers() public onlyRole(DAO_ROLE) {
require(_transferLock, "ALREADY_ENABLED");
_transferLock = false;
}
function disableTransfers() public onlyRole(DAO_ROLE) {
require(!_transferLock, "ALREADY_DISABLED");
_transferLock = true;
}
function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {
_mint(to, amount);
}
function decimals() public pure override returns (uint8) {
return 0;
}
function transfer(address to, uint256 amount)
public
override
returns (bool)
{
require(!_transferLock, "TRANSFERS_LOCKED");
return super.transfer(to, amount);
}
function transferFrom(
address from,
address to,
uint256 amount
) public override returns (bool) {
require(!_transferLock, "TRANSFERS_LOCKED");
return super.transferFrom(from, to, amount);
}
function addBurner(address newBurner) external onlyAdminOrDAO {
_grantRole(BURNER_ROLE, newBurner);
}
function removeBurner(address oldBurner) external onlyAdminOrDAO {
_revokeRole(BURNER_ROLE, oldBurner);
}
function burn(address from, uint256 amount) public onlyRole(BURNER_ROLE) {
_burn(from, amount);
}
function setSignerAddress(address signer)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
_signer = signer;
}
function lockDevMint() public onlyRole(DEFAULT_ADMIN_ROLE) {
require(!_devMintLock, "DEVMINT_LOCKED");
_devMintLock = true;
}
function devMint(address to, uint256 amount)
public
onlyRole(DEFAULT_ADMIN_ROLE)
{
require(!_devMintLock, "DEVMINT_LOCKED");
_mint(to, amount);
}
}
文件 30 的 35:MagicFolkItems.sol
pragma solidity ^0.8.0;
import "../utils/Common.sol";
import "../utils/SigVer.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Supply.sol";
import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "./MagicFolk.sol";
import "./MagicFolkGems.sol";
contract MagicFolkItems is
ERC1155,
ERC1155Holder,
SigVer,
Ownable,
AccessControl,
Pausable,
ERC1155Supply,
ReentrancyGuard
{
using ECDSA for bytes32;
using Counters for Counters.Counter;
MagicFolk _magicFolk;
MagicFolkGems _magicFolkGems;
address _signer;
Counters.Counter private _itemCount;
ItemType public immutable _itemType;
string public _contractURI;
mapping(uint256 => Item) public _items;
mapping(uint256 => uint256) public _prices;
mapping(uint256 => address) public _collabs;
mapping(uint256 => uint256) public _collabAllowancePerNFT;
mapping(address => mapping(uint256 => uint256)) public _collabItemsRedeemed;
constructor(address signer, ItemType itemType)
ERC1155("https://api.magicfolk.com/")
{
_grantRole(DEFAULT_ADMIN_ROLE, _msgSender());
_itemType = itemType;
_pause();
_signer = signer;
}
function setMagicFolkGemsAddress(address magicFolkGems)
public
onlyRole(DEFAULT_ADMIN_ROLE)
{
_magicFolkGems = MagicFolkGems(magicFolkGems);
}
function setMagicFolkContractAddress(address magicFolk)
public
onlyRole(DEFAULT_ADMIN_ROLE)
{
_magicFolk = MagicFolk(magicFolk);
}
function setSignerAddress(address newSigner)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
_signer = newSigner;
}
function setURI(string memory newuri) public onlyRole(DEFAULT_ADMIN_ROLE) {
_setURI(newuri);
}
function setContractURI(string memory newuri)
public
onlyRole(DEFAULT_ADMIN_ROLE)
{
_contractURI = newuri;
}
function contractURI() public view returns (string memory) {
return _contractURI;
}
function pause() public onlyRole(DEFAULT_ADMIN_ROLE) {
_pause();
}
function unpause() public onlyRole(DEFAULT_ADMIN_ROLE) {
_unpause();
}
function equip(
address from,
uint256 itemId,
uint256 magicFolkId
) public whenNotPaused {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not owner nor approved"
);
Item memory item = _getItem(itemId);
bytes memory ownerIdAndItem = encodeOwnerIdAndItem(magicFolkId, item);
_safeTransferFrom(from, address(_magicFolk), itemId, 1, ownerIdAndItem);
}
function unequip(
address from,
uint256 itemId,
uint256 magicFolkId
) public whenNotPaused {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not owner nor approved"
);
Item memory item = _getItem(itemId);
bytes memory ownerIdAndItem = encodeOwnerIdAndItem(magicFolkId, item);
_magicFolk.unequip(from, ownerIdAndItem);
}
function itemCount() public view returns (uint256) {
return _itemCount.current();
}
function getItem(uint256 itemId) public view returns (Item memory) {
require(_isInitialised(itemId), "Item not initalised");
return _getItem(itemId);
}
function _getItem(uint256 itemId) internal view returns (Item memory) {
return _items[itemId];
}
function _setPrice(uint256 itemId, uint256 price) internal {
_prices[itemId] = price;
}
function setPrice(uint256 itemId, uint256 price)
public
onlyRole(DEFAULT_ADMIN_ROLE)
{
_setPrice(itemId, price);
}
function _getPrice(uint256 itemId) internal view returns (uint256) {
return _prices[itemId];
}
function getPrice(uint256 itemId) public view returns (uint256) {
return _getPrice(itemId);
}
function getStockLeft(uint256 itemId) public view returns (uint256) {
return balanceOf(address(this), itemId);
}
function getOwnedItems(address owner)
public
view
returns (uint256[] memory)
{
uint256[] memory tokens = new uint256[](_itemCount.current());
for (uint256 i = 0; i < tokens.length; i++) {
tokens[i] = balanceOf(owner, i);
}
return tokens;
}
function buyItem(
address to,
uint256 itemId,
uint256 amount
) external nonReentrant {
require(!_isCollabItem(itemId), "COLLAB_ITEM");
uint256 totalPrice = amount * _getPrice(itemId);
uint256 gemBalance = _magicFolkGems.balanceOf(to);
require(gemBalance >= totalPrice, "Insufficient funds");
require(_isInitialised(itemId), "Item not initialised");
_safeTransferFrom(address(this), to, itemId, amount, "");
_magicFolkGems.burn(to, totalPrice);
}
function buyCollabItem(
uint256 itemId,
uint256 amount,
uint256 tokenId,
bytes32 msgHash,
bytes calldata signature
) external nonReentrant {
address to = msg.sender;
require(_isCollabItem(itemId), "NOT_COLLAB_ITEM");
require(_ownsToken(to, _collabs[itemId], tokenId), "NOT_YOUR_TOKEN");
uint256 totalPrice = amount * _getPrice(itemId);
uint256 gemBalance = _magicFolkGems.balanceOf(to);
require(gemBalance >= totalPrice, "INSUFFICIENT_FUNDS");
require(_isInitialised(itemId), "Item not initialised");
require(
amount + _getRedeemed(itemId, tokenId) <=
_collabAllowancePerNFT[itemId],
"TX_WILL_EXCEED_ALLOWANCE"
);
require(
_verifyMsg(to, tokenId, msgHash, signature, _signer),
"INVALID_SIG"
);
_safeTransferFrom(address(this), to, itemId, amount, "");
_magicFolkGems.burn(to, totalPrice);
_redeemCollabItem(itemId, tokenId, amount);
}
function setItem(
uint256 itemId,
uint8 powerLevel,
ItemType itemType,
uint256 price
) public onlyRole(DEFAULT_ADMIN_ROLE) {
_setItem(itemId, powerLevel, itemType, price);
}
function _setItem(
uint256 itemId,
uint8 powerLevel,
ItemType itemType,
uint256 price
) internal {
require(itemType == _itemType);
Item memory item;
item.itemId = itemId;
item.powerLevel = powerLevel;
item.itemType = itemType;
_items[itemId] = item;
_setPrice(itemId, price);
}
function mint(uint256 itemId, uint256 amount)
public
whenNotPaused
onlyRole(DEFAULT_ADMIN_ROLE)
{
require(itemId < _itemCount.current(), "ITEM_NOT_EXIST");
_mint(address(this), itemId, amount, "");
}
function createItem(
uint256 initialSupply,
uint8 powerLevel,
ItemType itemType,
uint256 price
) public onlyRole(DEFAULT_ADMIN_ROLE) {
uint256 itemId = _itemCount.current();
_setItem(itemId, powerLevel, itemType, price);
_mint(address(this), itemId, initialSupply, "");
_itemCount.increment();
}
function createItem(
uint256 initialSupply,
uint8 powerLevel,
ItemType itemType,
uint256 price,
address nftContract,
uint256 allowancePerNFT
) public onlyRole(DEFAULT_ADMIN_ROLE) {
uint256 itemId = _itemCount.current();
_addCollabItem(itemId, nftContract, allowancePerNFT);
_setItem(itemId, powerLevel, itemType, price);
_mint(address(this), itemId, initialSupply, "");
_itemCount.increment();
}
function mintBatch(
address,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public onlyRole(DEFAULT_ADMIN_ROLE) {
_mintBatch(address(this), ids, amounts, data);
}
function _ownsToken(
address to,
address nftContract,
uint256 tokenId
) internal view returns (bool) {
return IERC721(nftContract).ownerOf(tokenId) == to;
}
function _addCollabItem(
uint256 itemId,
address nftContract,
uint256 allowance
) internal {
_collabs[itemId] = nftContract;
_collabAllowancePerNFT[itemId] = allowance;
}
function _redeemCollabItem(
uint256 itemId,
uint256 tokenId,
uint256 qty
) internal {
_collabItemsRedeemed[_collabs[itemId]][tokenId] += qty;
}
function _getRedeemed(uint256 itemId, uint256 tokenId)
internal
view
returns (uint256)
{
return _collabItemsRedeemed[_collabs[itemId]][tokenId];
}
function isCollabItem(uint256 itemId) external view returns (bool) {
return _isCollabItem(itemId);
}
function _isCollabItem(uint256 itemId) internal view returns (bool) {
return _collabs[itemId] != address(0);
}
function _isInitialised(uint256 itemId) internal view returns (bool) {
Item memory item = _getItem(itemId);
return (item.itemType != ItemType.Empty);
}
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal override(ERC1155, ERC1155Supply) whenNotPaused {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
}
function supportsInterface(bytes4 interfaceID)
public
view
virtual
override(ERC1155, ERC1155Receiver, AccessControl)
returns (bool)
{
return
super.supportsInterface(interfaceID) ||
interfaceID == type(IERC1155Receiver).interfaceId ||
interfaceID == 0x01ffc9a7 ||
interfaceID == 0x4e2312e0;
}
function encodeItem(uint256 itemId) public view returns (bytes memory) {
return encodeOwnerIdAndItem(0, _items[itemId]);
}
function decodeItem(bytes calldata encodedOwnerIdAndItem)
public
pure
returns (uint256, Item memory)
{
require(encodedOwnerIdAndItem.length == 128, "wronglen");
return decodeOwnerIdAndItem(encodedOwnerIdAndItem);
}
}
文件 31 的 35:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 32 的 35:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 33 的 35: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;
}
}
文件 34 的 35:SigVer.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
contract SigVer {
using ECDSA for bytes32;
function verifyMsg(
address sender,
uint256 value,
bytes32 msgHash,
bytes memory signature,
address _signer
) public pure returns (bool) {
return _verifyMsg(sender, value, msgHash, signature, _signer);
}
function hashMsg(
address sender,
uint256 value
) public pure returns (bytes32) {
return _hashMsg(sender, value);
}
function verifySigner(
bytes32 msgHash,
bytes memory signature,
address _signer
) public pure returns (bool) {
return _verifySigner(msgHash, signature, _signer);
}
function _verifyMsg(
address sender,
uint256 value,
bytes32 msgHash,
bytes memory signature,
address _signer
) internal pure returns (bool) {
return (
_verifySigner(msgHash, signature, _signer)
&& _hashMsg(sender, value) == msgHash
);
}
function _hashMsg(
address sender,
uint256 value
) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(sender, value));
}
function _verifySigner(
bytes32 msgHash,
bytes memory signature,
address _signer
) internal pure returns (bool) {
return msgHash.toEthSignedMessageHash().recover(signature) == _signer;
}
}
文件 35 的 35:Strings.sol
pragma solidity ^0.8.0;
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}
{
"compilationTarget": {
"magic-on-chain/contracts/tokens/MagicFolkItems.sol": "MagicFolkItems"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"enum ItemType","name":"itemType","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_collabAllowancePerNFT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"_collabItemsRedeemed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_collabs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_itemType","outputs":[{"internalType":"enum ItemType","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_items","outputs":[{"internalType":"uint256","name":"itemId","type":"uint256"},{"internalType":"uint8","name":"powerLevel","type":"uint8"},{"internalType":"enum ItemType","name":"itemType","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_prices","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"buyCollabItem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"itemId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"buyItem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"initialSupply","type":"uint256"},{"internalType":"uint8","name":"powerLevel","type":"uint8"},{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"uint256","name":"price","type":"uint256"}],"name":"createItem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"initialSupply","type":"uint256"},{"internalType":"uint8","name":"powerLevel","type":"uint8"},{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"address","name":"nftContract","type":"address"},{"internalType":"uint256","name":"allowancePerNFT","type":"uint256"}],"name":"createItem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedOwnerIdAndItem","type":"bytes"}],"name":"decodeItem","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"components":[{"internalType":"uint256","name":"itemId","type":"uint256"},{"internalType":"uint8","name":"powerLevel","type":"uint8"},{"internalType":"enum ItemType","name":"itemType","type":"uint8"}],"internalType":"struct Item","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"encodeItem","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"itemId","type":"uint256"},{"internalType":"uint256","name":"magicFolkId","type":"uint256"}],"name":"equip","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"getItem","outputs":[{"components":[{"internalType":"uint256","name":"itemId","type":"uint256"},{"internalType":"uint8","name":"powerLevel","type":"uint8"},{"internalType":"enum ItemType","name":"itemType","type":"uint8"}],"internalType":"struct Item","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"getOwnedItems","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"getStockLeft","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"hashMsg","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"isCollabItem","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"itemCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mintBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","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":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newuri","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"},{"internalType":"uint8","name":"powerLevel","type":"uint8"},{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"uint256","name":"price","type":"uint256"}],"name":"setItem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"magicFolk","type":"address"}],"name":"setMagicFolkContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"magicFolkGems","type":"address"}],"name":"setMagicFolkGemsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newSigner","type":"address"}],"name":"setSignerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newuri","type":"string"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"itemId","type":"uint256"},{"internalType":"uint256","name":"magicFolkId","type":"uint256"}],"name":"unequip","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"address","name":"_signer","type":"address"}],"name":"verifyMsg","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"address","name":"_signer","type":"address"}],"name":"verifySigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}]