编译器
0.8.24+commit.e11b9ed9
文件 1 的 8: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;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 2 的 8:GodVaultClaimOptimized.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
interface IInfiniPass is IERC721 {
function getTokenRarity(uint256 tokenId) external view returns (uint8);
}
contract GodVaultClaimOptimized is Ownable, ReentrancyGuard, Pausable, IERC721Receiver {
IInfiniPass public immutable infiniPassContract;
IERC721 public vaultContract;
bool public vaultContractSet;
mapping(uint256 => bool) public passClaimed;
uint8 public constant ULTIMATE_VAULTS = 5;
uint8 public constant COMMUNITY_VAULTS = 1;
uint256 public constant MAX_TOKEN_ID = 4260;
uint256 public immutable startingVaultId;
uint256 public currentHighestVaultId;
uint256 public immutable totalVaultSupply;
uint256 public nextAvailableVaultId;
bool public initialized;
event VaultsClaimed(address indexed claimer, uint256[] passIds, uint256[] vaultIds);
event Initialized(uint256 startId, uint256 endId, uint256 totalSupply);
event VaultContractSet(address vaultContract);
constructor(address _infiniPassContract, uint256 _startingVaultId, uint256 _totalSupply) {
require(_infiniPassContract != address(0), "Zero address not allowed");
require(_totalSupply > 0, "Supply must be positive");
infiniPassContract = IInfiniPass(_infiniPassContract);
startingVaultId = _startingVaultId;
currentHighestVaultId = _startingVaultId + _totalSupply - 1;
totalVaultSupply = _totalSupply;
nextAvailableVaultId = _startingVaultId;
}
function setVaultContract(address _vaultContract) external onlyOwner {
require(!vaultContractSet, "Vault contract already set");
require(_vaultContract != address(0), "Zero address not allowed");
vaultContract = IERC721(_vaultContract);
vaultContractSet = true;
emit VaultContractSet(_vaultContract);
}
function initialize() external onlyOwner {
require(!initialized, "Already initialized");
require(vaultContractSet, "Vault contract not set");
require(vaultContract.balanceOf(address(this)) == totalVaultSupply, "Incorrect vault balance");
initialized = true;
emit Initialized(startingVaultId, currentHighestVaultId, totalVaultSupply);
}
function claimMultiple(uint256[] calldata _passIds) external nonReentrant whenNotPaused {
require(initialized, "Not initialized");
require(msg.sender != address(0), "Zero address not allowed");
uint256 totalVaultsToClaim = 0;
for (uint256 i = 0; i < _passIds.length; i++) {
uint256 passId = _passIds[i];
require(passId <= MAX_TOKEN_ID, "Token ID exceeds maximum allowed");
require(infiniPassContract.ownerOf(passId) == msg.sender, "You must own the pass to claim");
require(!passClaimed[passId], "This pass has already been used to claim vaults");
uint256 rarity = infiniPassContract.getTokenRarity(passId);
require(rarity <= 1, "Invalid pass rarity");
totalVaultsToClaim += (rarity == 1) ? ULTIMATE_VAULTS : COMMUNITY_VAULTS;
passClaimed[passId] = true;
}
require(totalVaultsToClaim > 0, "No vaults to claim");
require(nextAvailableVaultId + totalVaultsToClaim <= currentHighestVaultId + 1, "Not enough vaults left");
unchecked {
for (uint256 i = 0; i < totalVaultsToClaim; i++) {
vaultContract.transferFrom(address(this), msg.sender, nextAvailableVaultId++);
}
}
emit VaultsClaimed(
msg.sender, _passIds, _getClaimedVaultIds(nextAvailableVaultId - totalVaultsToClaim, totalVaultsToClaim)
);
}
function _getClaimedVaultIds(uint256 startId, uint256 count) internal pure returns (uint256[] memory) {
uint256[] memory vaultIds = new uint256[](count);
for (uint256 i = 0; i < count; i++) {
vaultIds[i] = startId + i;
}
return vaultIds;
}
function getRemainingVaults() public view returns (uint256) {
return currentHighestVaultId + 1 - nextAvailableVaultId;
}
function getClaimStatus(uint256[] calldata passIds) external view returns (bool[] memory) {
bool[] memory claimStatuses = new bool[](passIds.length);
for (uint256 i = 0; i < passIds.length; i++) {
require(passIds[i] <= MAX_TOKEN_ID, "Token ID exceeds maximum allowed");
claimStatuses[i] = passClaimed[passIds[i]];
}
return claimStatuses;
}
function pause() external onlyOwner {
_pause();
}
function unpause() external onlyOwner {
_unpause();
}
function onERC721Received(address operator, address from, uint256 tokenId, bytes memory)
public
virtual
override
returns (bytes4)
{
return this.onERC721Received.selector;
}
function withdrawUnclaimedVaults(address recipient, uint256 amount) external onlyOwner nonReentrant {
require(recipient != address(0), "Zero address not allowed");
require(amount > 0, "Amount must be positive");
require(amount <= getRemainingVaults(), "Not enough unclaimed vaults");
uint256 startId = nextAvailableVaultId;
unchecked {
for (uint256 i = 0; i < amount; i++) {
vaultContract.transferFrom(address(this), recipient, nextAvailableVaultId++);
}
}
emit VaultsClaimed(
recipient,
new uint256[](0),
_getClaimedVaultIds(startId, amount)
);
}
function emergencyWithdrawByIds(address recipient, uint256[] calldata tokenIds)
external
onlyOwner
nonReentrant
whenPaused
{
require(recipient != address(0), "Zero address not allowed");
require(tokenIds.length > 0, "Empty array not allowed");
for (uint256 i = 0; i < tokenIds.length; i++) {
require(vaultContract.ownerOf(tokenIds[i]) == address(this), "Contract does not own token");
vaultContract.transferFrom(address(this), recipient, tokenIds[i]);
}
emit VaultsClaimed(
recipient,
new uint256[](0),
tokenIds
);
}
}
文件 3 的 8:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 4 的 8: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);
}
文件 5 的 8:IERC721Receiver.sol
pragma solidity ^0.8.0;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 6 的 8: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);
}
}
文件 7 的 8: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());
}
}
文件 8 的 8:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
}
function _nonReentrantAfter() private {
_status = _NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}
{
"compilationTarget": {
"src/GodVaultClaimOptimized.sol": "GodVaultClaimOptimized"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":@openzeppelin/=node_modules/@openzeppelin/",
":@thirdweb-dev/=node_modules/@thirdweb-dev/",
":forge-std/=lib/forge-std/src/"
]
}
[{"inputs":[{"internalType":"address","name":"_infiniPassContract","type":"address"},{"internalType":"uint256","name":"_startingVaultId","type":"uint256"},{"internalType":"uint256","name":"_totalSupply","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"startId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalSupply","type":"uint256"}],"name":"Initialized","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"vaultContract","type":"address"}],"name":"VaultContractSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"claimer","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"passIds","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"vaultIds","type":"uint256[]"}],"name":"VaultsClaimed","type":"event"},{"inputs":[],"name":"COMMUNITY_VAULTS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKEN_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ULTIMATE_VAULTS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_passIds","type":"uint256[]"}],"name":"claimMultiple","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentHighestVaultId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"emergencyWithdrawByIds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"passIds","type":"uint256[]"}],"name":"getClaimStatus","outputs":[{"internalType":"bool[]","name":"","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRemainingVaults","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"infiniPassContract","outputs":[{"internalType":"contract IInfiniPass","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextAvailableVaultId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"passClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"address","name":"_vaultContract","type":"address"}],"name":"setVaultContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startingVaultId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalVaultSupply","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":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vaultContract","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultContractSet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawUnclaimedVaults","outputs":[],"stateMutability":"nonpayable","type":"function"}]