编译器
0.8.17+commit.8df45f5f
文件 1 的 11: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;
}
}
文件 2 的 11:IERC721AQueryableUpgradeable.sol
pragma solidity ^0.8.4;
import '../extensions/IERC721AQueryableUpgradeable.sol';
文件 3 的 11:IERC721AUpgradeable.sol
pragma solidity ^0.8.4;
interface IERC721AUpgradeable {
error ApprovalCallerNotOwnerNorApproved();
error ApprovalQueryForNonexistentToken();
error ApproveToCaller();
error BalanceQueryForZeroAddress();
error MintToZeroAddress();
error MintZeroQuantity();
error OwnerQueryForNonexistentToken();
error TransferCallerNotOwnerNorApproved();
error TransferFromIncorrectOwner();
error TransferToNonERC721ReceiverImplementer();
error TransferToZeroAddress();
error URIQueryForNonexistentToken();
error MintERC2309QuantityExceedsLimit();
error OwnershipNotInitializedForExtraData();
struct TokenOwnership {
address addr;
uint64 startTimestamp;
bool burned;
uint24 extraData;
}
function totalSupply() external view returns (uint256);
function supportsInterface(bytes4 interfaceId) external view returns (bool);
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);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}
文件 4 的 11:IEquipmentV2.sol
pragma solidity ^0.8.17;
import "./IItemTypeV2.sol";
interface IEquipmentV2 {
struct EquipmentTargetItem {
uint256 itemTokenId;
IItemTypeV2.ItemMintType itemMintType;
}
struct Equipment {
uint256 itemId;
address itemAddr;
}
struct EquipmentTargetSpecial {
uint256 specialType;
bool combinationable;
}
}
文件 5 的 11:IItemTypeV2.sol
pragma solidity ^0.8.17;
interface IItemTypeV2 {
enum ItemType { CLOTHES, HEAD, HAND, FOOT, STAMP, BACKGROUND }
enum ItemMintType { SLOTH_ITEM, SPECIAL_SLOTH_ITEM, USER_GENERATED_SLOTH_ITEM }
}
文件 6 的 11:ISlothBodyV2.sol
pragma solidity ^0.8.17;
import { IEquipmentV2 } from "./IEquipmentV2.sol";
interface ISlothBodyV2 {
function exists(uint256 tokenId) external view returns (bool);
function ownerOf(uint256 tokenId) external view returns (address);
function getEquipments(uint256 tokenId) external view returns (IEquipmentV2.Equipment[6] memory);
}
文件 7 的 11:ISlothItemV4.sol
pragma solidity ^0.8.17;
import { IERC721AQueryableUpgradeable } from "erc721a-upgradeable/contracts/interfaces/IERC721AQueryableUpgradeable.sol";
import "./IItemTypeV2.sol";
interface ISlothItemV4 is IERC721AQueryableUpgradeable {
function getItemType(uint256 tokenId) external view returns (IItemTypeV2.ItemType);
function getItemMintCount(address sender) external view returns (uint256);
function exists(uint256 tokenId) external view returns (bool);
function clothesMint(address sender, uint256 quantity) external;
function itemMint(address sender, uint256 quantity) external;
}
文件 8 的 11:ISlothV3.sol
pragma solidity ^0.8.17;
import { IERC721AQueryableUpgradeable } from "erc721a-upgradeable/contracts/interfaces/IERC721AQueryableUpgradeable.sol";
import { IEquipmentV2 } from "./IEquipmentV2.sol";
import { IItemTypeV2 } from "./IItemTypeV2.sol";
interface ISlothV3 is IERC721AQueryableUpgradeable {
function mint(address sender, uint8 quantity) external;
function numberMinted(address sender) external view returns (uint256);
function setItem(uint256 _tokenId, IEquipmentV2.EquipmentTargetItem memory _targetItem, IItemTypeV2.ItemType _targetItemType, address sender) external returns (address);
function receiveItem(address tokenOwner, address itemContractAddress, uint256 itemTokenId) external;
function sendItem(address tokenOwner, address itemContractAddress, uint256 itemTokenId) external;
}
文件 9 的 11:ISpecialSlothItemV3.sol
pragma solidity ^0.8.17;
import "./IItemTypeV2.sol";
import { IERC721AQueryableUpgradeable } from "erc721a-upgradeable/contracts/interfaces/IERC721AQueryableUpgradeable.sol";
interface ISpecialSlothItemV3 is IERC721AQueryableUpgradeable, IItemTypeV2 {
function getItemType(uint256 tokenId) external view returns (IItemTypeV2.ItemType);
function getSpecialType(uint256 tokenId) external view returns (uint256);
function getClothType(uint256 tokenId) external view returns (uint256);
function exists(uint256 tokenId) external view returns (bool);
function isCombinational(uint256 _specialType) external view returns (bool);
function mintPoupelle(address sender, uint256 quantity) external;
function mintCollaboCloth(address sender, uint256 quantity, uint256 _specialType) external;
function mintHalloweenJiangshiSet(address sender, uint256 quantity) external;
function mintHalloweenJacKOLanternSet(address sender, uint256 quantity) external;
function mintHalloweenGhostSet(address sender, uint256 quantity) external;
function mintSlothCollectionNovember(address sender, uint256 quantity, uint8 clothType) external;
}
文件 10 的 11: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);
}
}
文件 11 的 11:SlothEquipmentV3.sol
pragma solidity ^0.8.17;
import "./interfaces/ISlothItemV4.sol";
import "./interfaces/ISpecialSlothItemV3.sol";
import "./interfaces/IItemTypeV2.sol";
import "./interfaces/IEquipmentV2.sol";
import "./interfaces/ISlothBodyV2.sol";
import "./interfaces/ISlothV3.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract SlothEquipmentV3 is Ownable {
event SetItem (
uint256 indexed _tokenId,
uint256[] _itemIds,
IItemTypeV2.ItemMintType[] _itemMintType,
address[] _slothItemAddr,
uint256 _setAt
);
address private _slothAddr;
address private _slothItemAddr;
address private _specialSlothItemAddr;
address private _userGeneratedSlothItemAddr;
uint8 private constant _ITEM_NUM = 6;
bool private _itemAvailable;
function _getSpecialType(uint256 _itemTokenId) internal view returns (uint256) {
ISpecialSlothItemV3 specialSlothItem = ISpecialSlothItemV3(_specialSlothItemAddr);
return specialSlothItem.getSpecialType(_itemTokenId);
}
function _checkIsCombinationalCollabo(uint256 _specialType) internal view returns (bool) {
ISpecialSlothItemV3 specialSlothItem = ISpecialSlothItemV3(_specialSlothItemAddr);
return specialSlothItem.isCombinational(_specialType);
}
function setItems(uint256 tokenId, IEquipmentV2.EquipmentTargetItem[] memory _targetItems, address _contractAddress) external {
require(_itemAvailable, "item not available");
require(ISlothBodyV2(_contractAddress).exists(tokenId), "not exist");
require(ISlothBodyV2(_contractAddress).ownerOf(tokenId) == msg.sender, "not owner");
require(_targetItems.length == _ITEM_NUM, "invalid itemIds length");
IEquipmentV2.Equipment[_ITEM_NUM] memory _equipments = ISlothBodyV2(_contractAddress).getEquipments(tokenId);
uint256[] memory _equipmentItemIds = new uint256[](_ITEM_NUM);
for (uint8 i = 0; i < _ITEM_NUM; i++) {
_equipmentItemIds[i] = _equipments[i].itemId;
}
validateSetItems(_equipmentItemIds, _targetItems, msg.sender);
address[] memory itemAddrs = new address[](_ITEM_NUM);
uint256[] memory _itemIds = new uint256[](_ITEM_NUM);
IItemTypeV2.ItemMintType[] memory _itemMintTypes = new IItemTypeV2.ItemMintType[](_ITEM_NUM);
for (uint8 i = 0; i < _ITEM_NUM; i++) {
itemAddrs[i] = ISlothV3(_contractAddress).setItem(tokenId, _targetItems[i], IItemTypeV2.ItemType(i), msg.sender);
_itemIds[i] = _targetItems[i].itemTokenId;
_itemMintTypes[i] = _targetItems[i].itemMintType;
}
emit SetItem(tokenId, _itemIds, _itemMintTypes, itemAddrs, block.timestamp);
}
function _checkOwner(uint256 _itemTokenId, IItemTypeV2.ItemMintType _itemMintType, address sender) internal view {
if (_itemMintType == IItemTypeV2.ItemMintType.SLOTH_ITEM) {
ISlothItemV4 slothItem = ISlothItemV4(_slothItemAddr);
require(slothItem.exists(_itemTokenId), "token not exists");
require(slothItem.ownerOf(_itemTokenId) == sender, "not owner");
return;
}
if (uint(_itemMintType) == uint(IItemTypeV2.ItemMintType.SPECIAL_SLOTH_ITEM)) {
ISpecialSlothItemV3 specialSlothItem = ISpecialSlothItemV3(_specialSlothItemAddr);
require(specialSlothItem.exists(_itemTokenId), "token not exists");
require(specialSlothItem.ownerOf(_itemTokenId) == sender, "not owner");
return;
}
revert("wrorng itemMintType");
}
function _checkItemType(uint256 _itemTokenId, IItemTypeV2.ItemMintType _itemMintType, IItemTypeV2.ItemType _itemType) internal view {
if (_itemMintType == IItemTypeV2.ItemMintType.SLOTH_ITEM) {
ISlothItemV4 slothItem = ISlothItemV4(_slothItemAddr);
require(slothItem.getItemType(_itemTokenId) == _itemType, "wrong item type");
return;
}
if (_itemMintType == IItemTypeV2.ItemMintType.SPECIAL_SLOTH_ITEM) {
ISpecialSlothItemV3 specialSlothItem = ISpecialSlothItemV3(_specialSlothItemAddr);
require(specialSlothItem.getItemType(_itemTokenId) == _itemType, "wrong item type");
return;
}
revert("wrorng itemMintType");
}
function validateSetItems(uint256[] memory equipmentItemIds, IEquipmentV2.EquipmentTargetItem[] memory equipmentTargetItems, address sender) internal view returns (bool) {
uint8 equipmentTargetSlothItemNum = 0;
uint8 specialItemCount = 0;
uint256 latestSpecialType = 99;
bool latestSpecialTypeCombinationable = true;
for (uint8 i = 0; i < _ITEM_NUM; i++) {
uint256 _itemTokenId = equipmentTargetItems[i].itemTokenId;
IItemTypeV2.ItemMintType _itemMintType = equipmentTargetItems[i].itemMintType;
if (_itemTokenId != 0) {
if (equipmentItemIds[i] != _itemTokenId) {
_checkOwner(_itemTokenId, _itemMintType, sender);
}
if (_itemMintType == IItemTypeV2.ItemMintType.SPECIAL_SLOTH_ITEM) {
_checkItemType(_itemTokenId, _itemMintType, IItemTypeV2.ItemType(i));
uint256 _specialType = _getSpecialType(_itemTokenId);
if (latestSpecialType != _specialType) {
bool combinationable = _checkIsCombinationalCollabo(_specialType);
latestSpecialTypeCombinationable = combinationable;
specialItemCount++;
if (specialItemCount >= 2) {
if (combinationable && latestSpecialTypeCombinationable) {
} else {
revert("not combinationable");
}
}
latestSpecialType = _specialType;
}
} else {
_checkItemType(_itemTokenId, _itemMintType, IItemTypeV2.ItemType(i));
equipmentTargetSlothItemNum++;
}
}
}
if (latestSpecialTypeCombinationable == false && equipmentTargetSlothItemNum > 0) {
revert("not combinationable");
}
return true;
}
function getTargetItemContractAddress(IItemTypeV2.ItemMintType _itemMintType) external view returns (address) {
if (_itemMintType == IItemTypeV2.ItemMintType.SLOTH_ITEM) {
return _slothItemAddr;
} else if (_itemMintType == IItemTypeV2.ItemMintType.SPECIAL_SLOTH_ITEM) {
return _specialSlothItemAddr;
} else if (_itemMintType == IItemTypeV2.ItemMintType.USER_GENERATED_SLOTH_ITEM) {
return _userGeneratedSlothItemAddr;
} else {
revert("invalid itemMintType");
}
}
function setItemAvailable(bool newItemAvailable) external onlyOwner {
_itemAvailable = newItemAvailable;
}
function setSlothAddr(address newSlothAddr) external onlyOwner {
_slothAddr = newSlothAddr;
}
function setSlothItemAddr(address newSlothItemAddr) external onlyOwner {
_slothItemAddr = newSlothItemAddr;
}
function setSpecialSlothItemAddr(address newSpecialSlothItemAddr) external onlyOwner {
_specialSlothItemAddr = newSpecialSlothItemAddr;
}
}
{
"compilationTarget": {
"contracts/SlothEquipmentV3.sol": "SlothEquipmentV3"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"_itemIds","type":"uint256[]"},{"indexed":false,"internalType":"enum IItemTypeV2.ItemMintType[]","name":"_itemMintType","type":"uint8[]"},{"indexed":false,"internalType":"address[]","name":"_slothItemAddr","type":"address[]"},{"indexed":false,"internalType":"uint256","name":"_setAt","type":"uint256"}],"name":"SetItem","type":"event"},{"inputs":[{"internalType":"enum IItemTypeV2.ItemMintType","name":"_itemMintType","type":"uint8"}],"name":"getTargetItemContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newItemAvailable","type":"bool"}],"name":"setItemAvailable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint256","name":"itemTokenId","type":"uint256"},{"internalType":"enum IItemTypeV2.ItemMintType","name":"itemMintType","type":"uint8"}],"internalType":"struct IEquipmentV2.EquipmentTargetItem[]","name":"_targetItems","type":"tuple[]"},{"internalType":"address","name":"_contractAddress","type":"address"}],"name":"setItems","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newSlothAddr","type":"address"}],"name":"setSlothAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newSlothItemAddr","type":"address"}],"name":"setSlothItemAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newSpecialSlothItemAddr","type":"address"}],"name":"setSpecialSlothItemAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]