编译器
0.8.25+commit.b61c2a91
文件 1 的 21:Context.sol
pragma solidity ^0.8.20;
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 的 21:ERC165.sol
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 3 的 21:ERC721.sol
pragma solidity ^0.8.20;
import {IERC721} from "./IERC721.sol";
import {IERC721Receiver} from "./IERC721Receiver.sol";
import {IERC721Metadata} from "./extensions/IERC721Metadata.sol";
import {Context} from "../../utils/Context.sol";
import {Strings} from "../../utils/Strings.sol";
import {IERC165, ERC165} from "../../utils/introspection/ERC165.sol";
import {IERC721Errors} from "../../interfaces/draft-IERC6093.sol";
abstract contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Errors {
using Strings for uint256;
string private _name;
string private _symbol;
mapping(uint256 tokenId => address) private _owners;
mapping(address owner => uint256) private _balances;
mapping(uint256 tokenId => address) private _tokenApprovals;
mapping(address owner => mapping(address operator => 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 returns (uint256) {
if (owner == address(0)) {
revert ERC721InvalidOwner(address(0));
}
return _balances[owner];
}
function ownerOf(uint256 tokenId) public view virtual returns (address) {
return _requireOwned(tokenId);
}
function name() public view virtual returns (string memory) {
return _name;
}
function symbol() public view virtual returns (string memory) {
return _symbol;
}
function tokenURI(uint256 tokenId) public view virtual returns (string memory) {
_requireOwned(tokenId);
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string.concat(baseURI, tokenId.toString()) : "";
}
function _baseURI() internal view virtual returns (string memory) {
return "";
}
function approve(address to, uint256 tokenId) public virtual {
_approve(to, tokenId, _msgSender());
}
function getApproved(uint256 tokenId) public view virtual returns (address) {
_requireOwned(tokenId);
return _getApproved(tokenId);
}
function setApprovalForAll(address operator, bool approved) public virtual {
_setApprovalForAll(_msgSender(), operator, approved);
}
function isApprovedForAll(address owner, address operator) public view virtual returns (bool) {
return _operatorApprovals[owner][operator];
}
function transferFrom(address from, address to, uint256 tokenId) public virtual {
if (to == address(0)) {
revert ERC721InvalidReceiver(address(0));
}
address previousOwner = _update(to, tokenId, _msgSender());
if (previousOwner != from) {
revert ERC721IncorrectOwner(from, tokenId, previousOwner);
}
}
function safeTransferFrom(address from, address to, uint256 tokenId) public {
safeTransferFrom(from, to, tokenId, "");
}
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual {
transferFrom(from, to, tokenId);
_checkOnERC721Received(from, to, tokenId, data);
}
function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
return _owners[tokenId];
}
function _getApproved(uint256 tokenId) internal view virtual returns (address) {
return _tokenApprovals[tokenId];
}
function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) {
return
spender != address(0) &&
(owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender);
}
function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual {
if (!_isAuthorized(owner, spender, tokenId)) {
if (owner == address(0)) {
revert ERC721NonexistentToken(tokenId);
} else {
revert ERC721InsufficientApproval(spender, tokenId);
}
}
}
function _increaseBalance(address account, uint128 value) internal virtual {
unchecked {
_balances[account] += value;
}
}
function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) {
address from = _ownerOf(tokenId);
if (auth != address(0)) {
_checkAuthorized(from, auth, tokenId);
}
if (from != address(0)) {
_approve(address(0), tokenId, address(0), false);
unchecked {
_balances[from] -= 1;
}
}
if (to != address(0)) {
unchecked {
_balances[to] += 1;
}
}
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
return from;
}
function _mint(address to, uint256 tokenId) internal {
if (to == address(0)) {
revert ERC721InvalidReceiver(address(0));
}
address previousOwner = _update(to, tokenId, address(0));
if (previousOwner != address(0)) {
revert ERC721InvalidSender(address(0));
}
}
function _safeMint(address to, uint256 tokenId) internal {
_safeMint(to, tokenId, "");
}
function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {
_mint(to, tokenId);
_checkOnERC721Received(address(0), to, tokenId, data);
}
function _burn(uint256 tokenId) internal {
address previousOwner = _update(address(0), tokenId, address(0));
if (previousOwner == address(0)) {
revert ERC721NonexistentToken(tokenId);
}
}
function _transfer(address from, address to, uint256 tokenId) internal {
if (to == address(0)) {
revert ERC721InvalidReceiver(address(0));
}
address previousOwner = _update(to, tokenId, address(0));
if (previousOwner == address(0)) {
revert ERC721NonexistentToken(tokenId);
} else if (previousOwner != from) {
revert ERC721IncorrectOwner(from, tokenId, previousOwner);
}
}
function _safeTransfer(address from, address to, uint256 tokenId) internal {
_safeTransfer(from, to, tokenId, "");
}
function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {
_transfer(from, to, tokenId);
_checkOnERC721Received(from, to, tokenId, data);
}
function _approve(address to, uint256 tokenId, address auth) internal {
_approve(to, tokenId, auth, true);
}
function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual {
if (emitEvent || auth != address(0)) {
address owner = _requireOwned(tokenId);
if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) {
revert ERC721InvalidApprover(auth);
}
if (emitEvent) {
emit Approval(owner, to, tokenId);
}
}
_tokenApprovals[tokenId] = to;
}
function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {
if (operator == address(0)) {
revert ERC721InvalidOperator(operator);
}
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
function _requireOwned(uint256 tokenId) internal view returns (address) {
address owner = _ownerOf(tokenId);
if (owner == address(0)) {
revert ERC721NonexistentToken(tokenId);
}
return owner;
}
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private {
if (to.code.length > 0) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
if (retval != IERC721Receiver.onERC721Received.selector) {
revert ERC721InvalidReceiver(to);
}
} catch (bytes memory reason) {
if (reason.length == 0) {
revert ERC721InvalidReceiver(to);
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
}
}
}
文件 4 的 21:IERC165.sol
pragma solidity ^0.8.20;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 5 的 21:IERC721.sol
pragma solidity ^0.8.20;
import {IERC165} from "../../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);
}
文件 6 的 21:IERC721Metadata.sol
pragma solidity ^0.8.20;
import {IERC721} from "../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);
}
文件 7 的 21:IERC721Receiver.sol
pragma solidity ^0.8.20;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 8 的 21:IHCT.sol
pragma solidity >=0.8.0;
interface IHCT {
error NotWrappedNFT();
error NothingToClaim();
event TotalNFTWrapped(uint256 totalWrappedNFT);
event PowerAdded(address indexed wrappedNFT, address indexed user, uint128 multiplier);
event PowerRemoved(
address indexed wrappedNFT, address indexed user, uint128 multiplier
);
event Transferred(
address indexed wrappedNFT,
address indexed from,
address indexed to,
uint128 multiplier
);
event Claimed(address indexed user, uint256 amount);
event BurnedForRenaming(
address indexed wrappedNFT, address indexed user, uint256 amount
);
event InflationRateSet(uint256 inflationRate);
event BaseRateSet(uint256 baseRate);
event InflationThresholdSet(uint256 inflationThreshold);
struct UserInfo {
uint256 multiplier;
uint256 userRates;
}
function addPower(address _user, uint128 _addMultiplier, bool _newNFT) external;
function removePower(address _user, uint128 _removeMultiplier) external;
function burn(address _user, uint256 _amount) external;
function usesForRenaming(address _user) external;
function getUserPendingRewards(address _user) external view returns (uint256);
function getSystemPendingRewards() external view returns (uint256);
function getTotalRewardsGenerated() external view returns (uint256);
function getUserInfo(address _user) external view returns (UserInfo memory);
}
文件 9 的 21:ILiteTicker.sol
pragma solidity >=0.8.0;
interface ILiteTicker {
error NotWrappedNFT();
error NotDeposited();
error AlreadyDeposited();
event Deposited(address indexed wrappedNFT, uint256 indexed nftId);
event Withdrawn(address indexed wrappedNFT, uint256 indexed nftId);
function virtualDeposit(bytes32 _identity, uint256 _tokenId, address _receiver)
external;
function virtualWithdraw(
bytes32 _identity,
uint256 _tokenId,
address _receiver,
bool _ignoreRewards
) external;
function claim(
bytes32 _identity,
uint256 _tokenId,
address _receiver,
bool _ignoreRewards
) external;
function getClaimableRewards(bytes32 _identity, uint256 _extraRewards)
external
view
returns (uint256 rewards_, address rewardsToken_);
}
文件 10 的 21:INFTPass.sol
pragma solidity >=0.8.0;
interface INFTPass {
error NoNeedToPay();
error InvalidBPS();
error MsgValueTooLow();
error AlreadyClaimed();
error InvalidProof();
error NameTooLong();
error ClaimingEnded();
event NFTPassCreated(
uint256 indexed nftId, string indexed name, address indexed receiver, uint256 cost
);
event NFTPassUpdated(
uint256 indexed nftId, string indexed name, address indexed receiver
);
event MaxIdentityPerDayAtInitialPriceUpdated(uint32 newMaxIdentityPerDayAtInitialPrice);
event PriceIncreaseThresholdUpdated(uint32 newPriceIncreaseThreshold);
event PriceDecayBPSUpdated(uint32 newPriceDecayBPS);
struct Metadata {
string name;
address walletReceiver;
uint8 imageIndex;
}
function claimPass(
string calldata _name,
address _receiverWallet,
bytes32[] calldata merkleProof
) external;
function create(string calldata _name, address _receiverWallet) external payable;
function updateReceiverAddress(uint256 _nftId, string calldata _name, address _receiver)
external;
function getCost() external view returns (uint256);
function getMetadata(uint256 _nftId, string calldata _name)
external
view
returns (Metadata memory);
}
文件 11 的 21:IObeliskNFT.sol
pragma solidity >=0.8.0;
interface IObeliskNFT {
event TickerDeactivated(uint256 indexed tokenId, address indexed stakedPool);
event TickerActivated(uint256 indexed tokenId, address indexed stakedPool);
event TickerClaimed(uint256 indexed tokenId, address indexed stakedPool);
event NameUpdated(uint256 indexed tokenId, string name);
function claim(uint256 _tokenId) external;
function getIdentityInformation(uint256 _tokenId)
external
view
returns (bytes32 identityInTicker_, address rewardReceiver_);
}
文件 12 的 21:IObeliskRegistry.sol
pragma solidity >=0.8.0;
interface IObeliskRegistry {
error TooManyEth();
error GoalReached();
error AmountExceedsDeposit();
error TransferFailed();
error FailedDeployment();
error TickerAlreadyExists();
error NotSupporterDepositor();
error AlreadyRemoved();
error SupportNotFinished();
error NothingToClaim();
error NotWrappedNFT();
error CollectionNotAllowed();
error NotAuthorized();
error OnlyOneValue();
error AmountTooLow();
error ContributionBalanceTooLow();
error ZeroAddress();
error CollectionAlreadyAllowed();
error NoAccess();
event WrappedNFTCreated(address indexed collection, address indexed wrappedNFT);
event WrappedNFTEnabled(address indexed collection, address indexed wrappedNFT);
event WrappedNFTDisabled(address indexed collection, address indexed wrappedNFT);
event MegapoolFactorySet(address indexed megapoolFactory);
event TickerCreationAccessSet(address indexed to, bool status);
event TickerLogicSet(string indexed ticker, address indexed pool, string readableName);
event NewGenesisTickerCreated(string indexed ticker, address pool);
event Supported(uint32 indexed supportId, address indexed supporter, uint256 amount);
event SupportRetrieved(
uint32 indexed supportId, address indexed supporter, uint256 amount
);
event CollectionContributed(
address indexed collection, address indexed contributor, uint256 amount
);
event CollectionContributionWithdrawn(
address indexed collection, address indexed contributor, uint256 amount
);
event Claimed(address indexed collection, address indexed contributor, uint256 amount);
event SlotBought(address indexed wrappedNFT, uint256 toCollection, uint256 toTreasury);
event CollectionAllowed(
address indexed collection,
uint256 totalSupply,
uint32 collectionStartedUnixTime,
bool premium
);
event TreasurySet(address indexed treasury);
event MaxRewardPerCollectionSet(uint256 maxRewardPerCollection);
event CollectionImageIPFSUpdated(uint256 indexed id, string ipfsImage);
struct Collection {
uint256 totalSupply;
uint256 contributionBalance;
address wrappedVersion;
uint32 collectionStartedUnixTime;
bool allowed;
bool premium;
}
struct Supporter {
address depositor;
address token;
uint128 amount;
uint32 lockUntil;
bool removed;
}
struct CollectionRewards {
uint128 totalRewards;
uint128 claimedRewards;
}
struct ContributionInfo {
uint128 deposit;
uint128 claimed;
}
function isWrappedNFT(address _collection) external view returns (bool);
function addToCollection(address _collection) external payable;
function removeFromCollection(address _collection, uint256 _amount) external;
function supportYieldPool(uint256 _amount) external payable;
function retrieveSupportToYieldPool(uint32 _id) external;
function setTickerLogic(string memory _ticker, address _pool, bool _override) external;
function onSlotBought() external payable;
function getTickerLogic(string memory _ticker) external view returns (address);
function getSupporter(uint32 _id) external view returns (Supporter memory);
function getUserContribution(address _user, address _collection)
external
view
returns (ContributionInfo memory);
function getCollectionRewards(address _collection)
external
view
returns (CollectionRewards memory);
function getCollection(address _collection) external view returns (Collection memory);
function getCollectionImageIPFS(uint256 _id) external view returns (string memory);
}
文件 13 的 21:IWrappedNFTHero.sol
pragma solidity >=0.8.0;
interface IWrappedNFTHero {
error AlreadyMinted();
error NotMinted();
error NotNFTHolder();
error NoFreeSlots();
error FreeSlotAvailable();
error CannotTransferUnwrapFirst();
error SameMultiplier();
error InvalidNameLength();
error InvalidWalletReceiver();
error EmergencyWithdrawDisabled();
error EmergencyModeIsActive();
error NotObeliskRegistry();
error NotNFTPassHolder();
event Wrapped(uint256 indexed tokenId);
event Unwrapped(uint256 indexed tokenId);
event SlotBought(address indexed user, uint256 indexed inputCollectionNFTId);
event FreeSlotUsed(uint256 freeSlotLeft);
event EmergencyWithdrawEnabled();
event MultiplierUpdated(uint256 indexed tokenId, uint128 newMultiplier);
struct NFTData {
bool isMinted;
bool hasBeenRenamed;
bool wrappedOnce;
uint128 assignedMultiplier;
}
function wrap(uint256 _inputCollectionNFTId) external payable;
function rename(uint256 _tokenId, string memory _newName) external;
function unwrap(uint256 _tokenId) external;
function updateMultiplier(uint256 _tokenId) external;
function getWrapperMultiplier() external view returns (uint128);
function getNFTData(uint256 _tokenId) external view returns (NFTData memory);
function enableEmergencyWithdraw() external;
}
文件 14 的 21:Math.sol
pragma solidity ^0.8.20;
library Math {
error MathOverflowedMulDiv();
enum Rounding {
Floor,
Ceil,
Trunc,
Expand
}
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
if (b == 0) {
return a / b;
}
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
uint256 prod0 = x * y;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
if (denominator <= prod1) {
revert MathOverflowedMulDiv();
}
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (0 - denominator);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1 << (log2(a) >> 1);
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
}
}
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
}
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
}
}
function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
return uint8(rounding) % 2 == 1;
}
}
文件 15 的 21:ObeliskNFT.sol
pragma solidity ^0.8.25;
import { IObeliskNFT } from "src/interfaces/IObeliskNFT.sol";
import { ILiteTicker } from "src/interfaces/ILiteTicker.sol";
import { IObeliskRegistry } from "src/interfaces/IObeliskRegistry.sol";
import { INFTPass } from "src/interfaces/INFTPass.sol";
import { strings } from "src/lib/strings.sol";
import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
abstract contract ObeliskNFT is IObeliskNFT, ReentrancyGuard {
using strings for string;
using strings for strings.slice;
string public constant TICKER_START_INDICE = "#";
string public constant TICKER_SPLIT_STRING = ",";
string public constant TICKER_START_IDENTITY = "@";
uint32 public constant MAX_NAME_BYTES_LENGTH = 29;
IObeliskRegistry public immutable obeliskRegistry;
INFTPass public immutable NFT_PASS;
mapping(uint256 => string) public nftPassAttached;
mapping(uint256 => address[]) internal linkedTickers;
mapping(uint256 => string) public names;
constructor(address _obeliskRegistry, address _nftPass) {
obeliskRegistry = IObeliskRegistry(_obeliskRegistry);
NFT_PASS = INFTPass(_nftPass);
}
function _removeOldTickers(
bytes32 _identity,
address _receiver,
uint256 _tokenId,
bool _ignoreRewards
) internal nonReentrant {
address[] memory activePools = linkedTickers[_tokenId];
delete linkedTickers[_tokenId];
address currentPool;
for (uint256 i = 0; i < activePools.length; ++i) {
currentPool = activePools[i];
ILiteTicker(currentPool).virtualWithdraw(
_identity, _tokenId, _receiver, _ignoreRewards
);
emit TickerDeactivated(_tokenId, currentPool);
}
}
function _addNewTickers(
bytes32 _identity,
address _receiver,
uint256 _tokenId,
string memory _name
) internal virtual nonReentrant {
strings.slice memory nameSlice = _name.toSlice();
strings.slice memory needle = TICKER_START_INDICE.toSlice();
strings.slice memory substring =
nameSlice.find(needle).beyond(needle).split(string(" ").toSlice());
strings.slice memory delim = TICKER_SPLIT_STRING.toSlice();
address[] memory poolTargets = new address[](substring.count(delim) + 1);
address poolTarget;
string memory tickerName;
for (uint256 i = 0; i < poolTargets.length; ++i) {
tickerName = substring.split(delim).toString();
if (bytes(tickerName).length == 0) continue;
poolTarget = obeliskRegistry.getTickerLogic(tickerName);
if (poolTarget == address(0)) continue;
poolTargets[i] = poolTarget;
ILiteTicker(poolTarget).virtualDeposit(_identity, _tokenId, _receiver);
emit TickerActivated(_tokenId, poolTarget);
}
linkedTickers[_tokenId] = poolTargets;
}
function claim(uint256 _tokenId) external nonReentrant {
address[] memory activePools = linkedTickers[_tokenId];
assert(_claimRequirements(_tokenId));
(bytes32 identity, address identityReceiver) = _getIdentityInformation(_tokenId);
for (uint256 i = 0; i < activePools.length; i++) {
ILiteTicker(activePools[i]).claim(identity, _tokenId, identityReceiver, false);
emit TickerClaimed(_tokenId, activePools[i]);
}
}
function _claimRequirements(uint256 _tokenId) internal view virtual returns (bool);
function getIdentityInformation(uint256 _tokenId)
external
view
override
returns (bytes32 identityInTicker_, address rewardReceiver_)
{
return _getIdentityInformation(_tokenId);
}
function _getIdentityInformation(uint256 _tokenId)
internal
view
virtual
returns (bytes32, address);
function getLinkedTickers(uint256 _tokenId) external view returns (address[] memory) {
return linkedTickers[_tokenId];
}
function getPendingRewards(uint256 _tokenId)
external
view
returns (uint256[] memory pendingRewards_, address[] memory pendingRewardsTokens_)
{
address[] memory activePools = linkedTickers[_tokenId];
(bytes32 identity,) = _getIdentityInformation(_tokenId);
pendingRewards_ = new uint256[](activePools.length);
pendingRewardsTokens_ = new address[](activePools.length);
uint256 pendingRewards;
address pendingRewardsToken;
for (uint256 i = 0; i < activePools.length; ++i) {
(pendingRewards, pendingRewardsToken) =
ILiteTicker(activePools[i]).getClaimableRewards(identity, 0);
pendingRewards_[i] = pendingRewards;
pendingRewardsTokens_[i] = pendingRewardsToken;
}
return (pendingRewards_, pendingRewardsTokens_);
}
}
文件 16 的 21:ReentrancyGuard.sol
pragma solidity ^0.8.20;
abstract contract ReentrancyGuard {
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
_status = ENTERED;
}
function _nonReentrantAfter() private {
_status = NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}
文件 17 的 21:SignedMath.sol
pragma solidity ^0.8.20;
library SignedMath {
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
function average(int256 a, int256 b) internal pure returns (int256) {
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
function abs(int256 n) internal pure returns (uint256) {
unchecked {
return uint256(n >= 0 ? n : -n);
}
}
}
文件 18 的 21:Strings.sol
pragma solidity ^0.8.20;
import {Math} from "./math/Math.sol";
import {SignedMath} from "./math/SignedMath.sol";
library Strings {
bytes16 private constant HEX_DIGITS = "0123456789abcdef";
uint8 private constant ADDRESS_LENGTH = 20;
error StringsInsufficientHexLength(uint256 value, uint256 length);
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
assembly {
mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
function toStringSigned(int256 value) internal pure returns (string memory) {
return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value)));
}
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
uint256 localValue = value;
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_DIGITS[localValue & 0xf];
localValue >>= 4;
}
if (localValue != 0) {
revert StringsInsufficientHexLength(value, length);
}
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);
}
function equal(string memory a, string memory b) internal pure returns (bool) {
return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));
}
}
文件 19 的 21:WrappedNFTHero.sol
pragma solidity ^0.8.25;
import { IWrappedNFTHero } from "src/interfaces/IWrappedNFTHero.sol";
import { ObeliskNFT } from "./ObeliskNFT.sol";
import { IHCT } from "src/interfaces/IHCT.sol";
import { IObeliskRegistry } from "src/interfaces/IObeliskRegistry.sol";
import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import { IERC721Receiver } from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";
import { strings } from "src/lib/strings.sol";
import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
contract WrappedNFTHero is IWrappedNFTHero, ERC721, IERC721Receiver, ObeliskNFT {
using strings for string;
using strings for strings.slice;
uint256 private constant MAX_BPS = 10_000;
uint256 private constant SECONDS_PER_YEAR = 31_557_600;
uint256 public constant SLOT_PRICE = 0.1e18;
uint256 public constant FREE_SLOT_BPS = 2500;
uint256 public constant RATE_PER_YEAR = 0.43e18;
uint256 public constant MAX_RATE = 3e18;
IHCT public immutable HCT;
ERC721 public immutable INPUT_COLLECTION;
uint32 public immutable COLLECTION_STARTED_UNIX_TIME;
bool public immutable FREE_SLOT_FOR_ODD;
bool public immutable PREMIUM;
bool public emergencyWithdrawEnabled;
uint256 public freeSlots;
mapping(uint256 => NFTData) internal nftData;
uint256 public immutable ID;
constructor(
address _HCT,
address _nftPass,
address _inputCollection,
address _obeliskRegistry,
uint256 _currentSupply,
uint32 _collectionStartedUnixTime,
bool _premium,
uint256 _id
) ERC721("WrappedNFTHero", "WNH") ObeliskNFT(_obeliskRegistry, _nftPass) {
HCT = IHCT(_HCT);
INPUT_COLLECTION = ERC721(_inputCollection);
freeSlots = _currentSupply * FREE_SLOT_BPS / MAX_BPS;
FREE_SLOT_FOR_ODD = uint256(keccak256(abi.encode(_inputCollection))) % 2 == 1;
COLLECTION_STARTED_UNIX_TIME = _collectionStartedUnixTime;
PREMIUM = _premium;
ID = _id;
}
function wrap(uint256 _inputCollectionNFTId) external payable override {
if (emergencyWithdrawEnabled) revert EmergencyModeIsActive();
if (IERC721(address(NFT_PASS)).balanceOf(msg.sender) == 0) revert NotNFTPassHolder();
bool isIdOdd = _inputCollectionNFTId % 2 == 1;
bool canHaveFreeSlot = freeSlots != 0 && FREE_SLOT_FOR_ODD == isIdOdd;
NFTData storage nftdata = nftData[_inputCollectionNFTId];
bool didWrapBefore = nftdata.wrappedOnce;
if (nftdata.isMinted) revert AlreadyMinted();
if ((canHaveFreeSlot || didWrapBefore) && msg.value != 0) revert FreeSlotAvailable();
if ((!canHaveFreeSlot && !didWrapBefore) && msg.value != SLOT_PRICE) {
revert NoFreeSlots();
}
nftdata.isMinted = true;
INPUT_COLLECTION.transferFrom(msg.sender, address(this), _inputCollectionNFTId);
_safeMint(msg.sender, _inputCollectionNFTId);
emit Wrapped(_inputCollectionNFTId);
if (didWrapBefore) return;
nftdata.wrappedOnce = true;
if (!canHaveFreeSlot) {
obeliskRegistry.onSlotBought{ value: msg.value }();
emit SlotBought(msg.sender, _inputCollectionNFTId);
} else {
freeSlots--;
emit FreeSlotUsed(freeSlots);
}
}
function rename(uint256 _tokenId, string memory _newName) external override {
uint256 nameBytesLength = bytes(_newName).length;
if (nameBytesLength == 0 || nameBytesLength > MAX_NAME_BYTES_LENGTH) {
revert InvalidNameLength();
}
_renameRequirements(_tokenId);
_updateMultiplier(_tokenId);
bytes32 identity;
address receiver;
if (bytes(names[_tokenId]).length != 0) {
(identity, receiver) = _getIdentityInformation(_tokenId);
_removeOldTickers(identity, receiver, _tokenId, false);
}
(identity, receiver) = _updateIdentity(_tokenId, _newName);
_addNewTickers(identity, receiver, _tokenId, _newName);
emit NameUpdated(_tokenId, _newName);
names[_tokenId] = _newName;
}
function _renameRequirements(uint256 _tokenId) internal {
NFTData storage nftdata = nftData[_tokenId];
if (!nftdata.isMinted) revert NotMinted();
if (_ownerOf(_tokenId) != msg.sender) revert NotNFTHolder();
if (PREMIUM && !nftdata.hasBeenRenamed) {
nftdata.hasBeenRenamed = true;
return;
}
HCT.usesForRenaming(msg.sender);
}
function _updateIdentity(uint256 _tokenId, string memory _name)
internal
virtual
returns (bytes32 _identity, address receiver_)
{
strings.slice memory nameSlice = _name.toSlice();
strings.slice memory needle = TICKER_START_IDENTITY.toSlice();
string memory substring =
nameSlice.find(needle).beyond(needle).split(string(" ").toSlice()).toString();
receiver_ = NFT_PASS.getMetadata(0, substring).walletReceiver;
if (receiver_ == address(0)) revert InvalidWalletReceiver();
nftPassAttached[_tokenId] = substring;
return (keccak256(abi.encode(substring)), receiver_);
}
function unwrap(uint256 _tokenId) external override {
NFTData storage nftdata = nftData[_tokenId];
if (!nftdata.isMinted) revert NotMinted();
if (_ownerOf(_tokenId) != msg.sender) revert NotNFTHolder();
if (!emergencyWithdrawEnabled) {
(bytes32 identity, address receiver) = _getIdentityInformation(_tokenId);
_removeOldTickers(identity, receiver, _tokenId, false);
}
_burn(_tokenId);
delete names[_tokenId];
delete nftPassAttached[_tokenId];
nftdata.assignedMultiplier = 0;
nftdata.isMinted = false;
INPUT_COLLECTION.safeTransferFrom(address(this), msg.sender, _tokenId);
emit Unwrapped(_tokenId);
}
function _claimRequirements(uint256 _tokenId) internal view override returns (bool) {
if (_ownerOf(_tokenId) != msg.sender) revert NotNFTHolder();
return true;
}
function _update(address to, uint256 tokenId, address auth)
internal
override
returns (address)
{
NFTData storage nftdata = nftData[tokenId];
address from = _ownerOf(tokenId);
uint128 multiplier = nftdata.assignedMultiplier;
if (to == address(0)) {
HCT.removePower(from, multiplier);
multiplier = 0;
} else if (from == address(0)) {
multiplier = getWrapperMultiplier();
HCT.addPower(to, multiplier, true);
} else {
revert CannotTransferUnwrapFirst();
}
nftdata.assignedMultiplier = multiplier;
emit MultiplierUpdated(tokenId, multiplier);
return super._update(to, tokenId, auth);
}
function _getIdentityInformation(uint256 _tokenId)
internal
view
override
returns (bytes32, address)
{
string memory nftPass = nftPassAttached[_tokenId];
return
(keccak256(abi.encode(nftPass)), NFT_PASS.getMetadata(0, nftPass).walletReceiver);
}
function updateMultiplier(uint256 _tokenId) external override {
if (!_updateMultiplier(_tokenId)) revert SameMultiplier();
}
function _updateMultiplier(uint256 _tokenId) internal returns (bool) {
NFTData storage nftdata = nftData[_tokenId];
if (_ownerOf(_tokenId) != msg.sender) revert NotNFTHolder();
uint128 newMultiplier = getWrapperMultiplier();
uint128 multiplier = nftdata.assignedMultiplier;
if (newMultiplier == multiplier) return false;
HCT.addPower(msg.sender, newMultiplier - multiplier, false);
nftData[_tokenId].assignedMultiplier = newMultiplier;
emit MultiplierUpdated(_tokenId, newMultiplier);
return true;
}
function enableEmergencyWithdraw() external override {
if (msg.sender != address(obeliskRegistry)) revert NotObeliskRegistry();
emergencyWithdrawEnabled = true;
emit EmergencyWithdrawEnabled();
}
function getWrapperMultiplier() public view override returns (uint128) {
if (PREMIUM) return uint128(MAX_RATE);
uint256 currentYear =
(block.timestamp - COLLECTION_STARTED_UNIX_TIME) / SECONDS_PER_YEAR;
return uint128(Math.min(currentYear * RATE_PER_YEAR, MAX_RATE));
}
function getNFTData(uint256 _tokenId) external view override returns (NFTData memory) {
return nftData[_tokenId];
}
function onERC721Received(address, address, uint256, bytes calldata)
external
pure
override
returns (bytes4)
{
return this.onERC721Received.selector;
}
function tokenURI(uint256 tokenId) public view override returns (string memory) {
_requireOwned(tokenId);
string memory name = names[tokenId];
if (bytes(name).length == 0) name = "Unnamed";
string memory data = string(
abi.encodePacked(
'{"name":"',
name,
'","description":"Wrapped Version of an external collection","image":"',
IObeliskRegistry(obeliskRegistry).getCollectionImageIPFS(ID),
'"}'
)
);
return string(abi.encodePacked("data:application/json;utf8,", data));
}
}
文件 20 的 21:draft-IERC6093.sol
pragma solidity ^0.8.20;
interface IERC20Errors {
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
error ERC20InvalidSender(address sender);
error ERC20InvalidReceiver(address receiver);
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
error ERC20InvalidApprover(address approver);
error ERC20InvalidSpender(address spender);
}
interface IERC721Errors {
error ERC721InvalidOwner(address owner);
error ERC721NonexistentToken(uint256 tokenId);
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
error ERC721InvalidSender(address sender);
error ERC721InvalidReceiver(address receiver);
error ERC721InsufficientApproval(address operator, uint256 tokenId);
error ERC721InvalidApprover(address approver);
error ERC721InvalidOperator(address operator);
}
interface IERC1155Errors {
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
error ERC1155InvalidSender(address sender);
error ERC1155InvalidReceiver(address receiver);
error ERC1155MissingApprovalForAll(address operator, address owner);
error ERC1155InvalidApprover(address approver);
error ERC1155InvalidOperator(address operator);
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}
文件 21 的 21:strings.sol
pragma solidity ^0.8.0;
library strings {
struct slice {
uint256 _len;
uint256 _ptr;
}
function memcpy(uint256 dest, uint256 src, uint256 _len) private pure {
for (; _len >= 32; _len -= 32) {
assembly {
mstore(dest, mload(src))
}
dest += 32;
src += 32;
}
uint256 mask = type(uint256).max;
if (_len > 0) {
mask = 256 ** (32 - _len) - 1;
}
assembly {
let srcpart := and(mload(src), not(mask))
let destpart := and(mload(dest), mask)
mstore(dest, or(destpart, srcpart))
}
}
function toSlice(string memory self) internal pure returns (slice memory) {
uint256 ptr;
assembly {
ptr := add(self, 0x20)
}
return slice(bytes(self).length, ptr);
}
function len(bytes32 self) internal pure returns (uint256) {
uint256 ret;
if (self == 0) {
return 0;
}
if (uint256(self) & type(uint128).max == 0) {
ret += 16;
self = bytes32(uint256(self) / 0x100000000000000000000000000000000);
}
if (uint256(self) & type(uint64).max == 0) {
ret += 8;
self = bytes32(uint256(self) / 0x10000000000000000);
}
if (uint256(self) & type(uint32).max == 0) {
ret += 4;
self = bytes32(uint256(self) / 0x100000000);
}
if (uint256(self) & type(uint16).max == 0) {
ret += 2;
self = bytes32(uint256(self) / 0x10000);
}
if (uint256(self) & type(uint8).max == 0) {
ret += 1;
}
return 32 - ret;
}
function toSliceB32(bytes32 self) internal pure returns (slice memory ret) {
assembly {
let ptr := mload(0x40)
mstore(0x40, add(ptr, 0x20))
mstore(ptr, self)
mstore(add(ret, 0x20), ptr)
}
ret._len = len(self);
}
function copy(slice memory self) internal pure returns (slice memory) {
return slice(self._len, self._ptr);
}
function toString(slice memory self) internal pure returns (string memory) {
string memory ret = new string(self._len);
uint256 retptr;
assembly {
retptr := add(ret, 32)
}
memcpy(retptr, self._ptr, self._len);
return ret;
}
function len(slice memory self) internal pure returns (uint256 l) {
uint256 ptr = self._ptr - 31;
uint256 end = ptr + self._len;
for (l = 0; ptr < end; l++) {
uint8 b;
assembly {
b := and(mload(ptr), 0xFF)
}
if (b < 0x80) {
ptr += 1;
} else if (b < 0xE0) {
ptr += 2;
} else if (b < 0xF0) {
ptr += 3;
} else if (b < 0xF8) {
ptr += 4;
} else if (b < 0xFC) {
ptr += 5;
} else {
ptr += 6;
}
}
}
function empty(slice memory self) internal pure returns (bool) {
return self._len == 0;
}
function compare(slice memory self, slice memory other) internal pure returns (int256) {
uint256 shortest = self._len;
if (other._len < self._len) {
shortest = other._len;
}
uint256 selfptr = self._ptr;
uint256 otherptr = other._ptr;
for (uint256 idx = 0; idx < shortest; idx += 32) {
uint256 a;
uint256 b;
assembly {
a := mload(selfptr)
b := mload(otherptr)
}
if (a != b) {
uint256 mask = type(uint256).max;
if (shortest < 32) {
mask = ~(2 ** (8 * (32 - shortest + idx)) - 1);
}
unchecked {
uint256 diff = (a & mask) - (b & mask);
if (diff != 0) {
return int256(diff);
}
}
}
selfptr += 32;
otherptr += 32;
}
return int256(self._len) - int256(other._len);
}
function equals(slice memory self, slice memory other) internal pure returns (bool) {
return compare(self, other) == 0;
}
function nextRune(slice memory self, slice memory rune)
internal
pure
returns (slice memory)
{
rune._ptr = self._ptr;
if (self._len == 0) {
rune._len = 0;
return rune;
}
uint256 l;
uint256 b;
assembly {
b := and(mload(sub(mload(add(self, 32)), 31)), 0xFF)
}
if (b < 0x80) {
l = 1;
} else if (b < 0xE0) {
l = 2;
} else if (b < 0xF0) {
l = 3;
} else {
l = 4;
}
if (l > self._len) {
rune._len = self._len;
self._ptr += self._len;
self._len = 0;
return rune;
}
self._ptr += l;
self._len -= l;
rune._len = l;
return rune;
}
function nextRune(slice memory self) internal pure returns (slice memory ret) {
nextRune(self, ret);
}
function ord(slice memory self) internal pure returns (uint256 ret) {
if (self._len == 0) {
return 0;
}
uint256 word;
uint256 length;
uint256 divisor = 2 ** 248;
assembly {
word := mload(mload(add(self, 32)))
}
uint256 b = word / divisor;
if (b < 0x80) {
ret = b;
length = 1;
} else if (b < 0xE0) {
ret = b & 0x1F;
length = 2;
} else if (b < 0xF0) {
ret = b & 0x0F;
length = 3;
} else {
ret = b & 0x07;
length = 4;
}
if (length > self._len) {
return 0;
}
for (uint256 i = 1; i < length; i++) {
divisor = divisor / 256;
b = (word / divisor) & 0xFF;
if (b & 0xC0 != 0x80) {
return 0;
}
ret = (ret * 64) | (b & 0x3F);
}
return ret;
}
function keccak(slice memory self) internal pure returns (bytes32 ret) {
assembly {
ret := keccak256(mload(add(self, 32)), mload(self))
}
}
function startsWith(slice memory self, slice memory needle)
internal
pure
returns (bool)
{
if (self._len < needle._len) {
return false;
}
if (self._ptr == needle._ptr) {
return true;
}
bool equal;
assembly {
let length := mload(needle)
let selfptr := mload(add(self, 0x20))
let needleptr := mload(add(needle, 0x20))
equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))
}
return equal;
}
function beyond(slice memory self, slice memory needle)
internal
pure
returns (slice memory)
{
if (self._len < needle._len) {
return self;
}
bool equal = true;
if (self._ptr != needle._ptr) {
assembly {
let length := mload(needle)
let selfptr := mload(add(self, 0x20))
let needleptr := mload(add(needle, 0x20))
equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))
}
}
if (equal) {
self._len -= needle._len;
self._ptr += needle._len;
}
return self;
}
function endsWith(slice memory self, slice memory needle) internal pure returns (bool) {
if (self._len < needle._len) {
return false;
}
uint256 selfptr = self._ptr + self._len - needle._len;
if (selfptr == needle._ptr) {
return true;
}
bool equal;
assembly {
let length := mload(needle)
let needleptr := mload(add(needle, 0x20))
equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))
}
return equal;
}
function until(slice memory self, slice memory needle)
internal
pure
returns (slice memory)
{
if (self._len < needle._len) {
return self;
}
uint256 selfptr = self._ptr + self._len - needle._len;
bool equal = true;
if (selfptr != needle._ptr) {
assembly {
let length := mload(needle)
let needleptr := mload(add(needle, 0x20))
equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))
}
}
if (equal) {
self._len -= needle._len;
}
return self;
}
function findPtr(uint256 selflen, uint256 selfptr, uint256 needlelen, uint256 needleptr)
private
pure
returns (uint256)
{
uint256 ptr = selfptr;
uint256 idx;
if (needlelen <= selflen) {
if (needlelen <= 32) {
bytes32 mask;
if (needlelen > 0) {
mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1));
}
bytes32 needledata;
assembly {
needledata := and(mload(needleptr), mask)
}
uint256 end = selfptr + selflen - needlelen;
bytes32 ptrdata;
assembly {
ptrdata := and(mload(ptr), mask)
}
while (ptrdata != needledata) {
if (ptr >= end) {
return selfptr + selflen;
}
ptr++;
assembly {
ptrdata := and(mload(ptr), mask)
}
}
return ptr;
} else {
bytes32 hash;
assembly {
hash := keccak256(needleptr, needlelen)
}
for (idx = 0; idx <= selflen - needlelen; idx++) {
bytes32 testHash;
assembly {
testHash := keccak256(ptr, needlelen)
}
if (hash == testHash) {
return ptr;
}
ptr += 1;
}
}
}
return selfptr + selflen;
}
function rfindPtr(
uint256 selflen,
uint256 selfptr,
uint256 needlelen,
uint256 needleptr
) private pure returns (uint256) {
uint256 ptr;
if (needlelen <= selflen) {
if (needlelen <= 32) {
bytes32 mask;
if (needlelen > 0) {
mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1));
}
bytes32 needledata;
assembly {
needledata := and(mload(needleptr), mask)
}
ptr = selfptr + selflen - needlelen;
bytes32 ptrdata;
assembly {
ptrdata := and(mload(ptr), mask)
}
while (ptrdata != needledata) {
if (ptr <= selfptr) {
return selfptr;
}
ptr--;
assembly {
ptrdata := and(mload(ptr), mask)
}
}
return ptr + needlelen;
} else {
bytes32 hash;
assembly {
hash := keccak256(needleptr, needlelen)
}
ptr = selfptr + (selflen - needlelen);
while (ptr >= selfptr) {
bytes32 testHash;
assembly {
testHash := keccak256(ptr, needlelen)
}
if (hash == testHash) {
return ptr + needlelen;
}
ptr -= 1;
}
}
}
return selfptr;
}
function find(slice memory self, slice memory needle)
internal
pure
returns (slice memory)
{
uint256 ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr);
self._len -= ptr - self._ptr;
self._ptr = ptr;
return self;
}
function rfind(slice memory self, slice memory needle)
internal
pure
returns (slice memory)
{
uint256 ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr);
self._len = ptr - self._ptr;
return self;
}
function split(slice memory self, slice memory needle, slice memory token)
internal
pure
returns (slice memory)
{
uint256 ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr);
token._ptr = self._ptr;
token._len = ptr - self._ptr;
if (ptr == self._ptr + self._len) {
self._len = 0;
} else {
self._len -= token._len + needle._len;
self._ptr = ptr + needle._len;
}
return token;
}
function split(slice memory self, slice memory needle)
internal
pure
returns (slice memory token)
{
split(self, needle, token);
}
function rsplit(slice memory self, slice memory needle, slice memory token)
internal
pure
returns (slice memory)
{
uint256 ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr);
token._ptr = ptr;
token._len = self._len - (ptr - self._ptr);
if (ptr == self._ptr) {
self._len = 0;
} else {
self._len -= token._len + needle._len;
}
return token;
}
function rsplit(slice memory self, slice memory needle)
internal
pure
returns (slice memory token)
{
rsplit(self, needle, token);
}
function count(slice memory self, slice memory needle)
internal
pure
returns (uint256 cnt)
{
uint256 ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr) + needle._len;
while (ptr <= self._ptr + self._len) {
cnt++;
ptr = findPtr(self._len - (ptr - self._ptr), ptr, needle._len, needle._ptr)
+ needle._len;
}
}
function contains(slice memory self, slice memory needle) internal pure returns (bool) {
return rfindPtr(self._len, self._ptr, needle._len, needle._ptr) != self._ptr;
}
function concat(slice memory self, slice memory other)
internal
pure
returns (string memory)
{
string memory ret = new string(self._len + other._len);
uint256 retptr;
assembly {
retptr := add(ret, 32)
}
memcpy(retptr, self._ptr, self._len);
memcpy(retptr + self._len, other._ptr, other._len);
return ret;
}
function join(slice memory self, slice[] memory parts)
internal
pure
returns (string memory)
{
if (parts.length == 0) {
return "";
}
uint256 length = self._len * (parts.length - 1);
for (uint256 i = 0; i < parts.length; i++) {
length += parts[i]._len;
}
string memory ret = new string(length);
uint256 retptr;
assembly {
retptr := add(ret, 32)
}
for (uint256 i = 0; i < parts.length; i++) {
memcpy(retptr, parts[i]._ptr, parts[i]._len);
retptr += parts[i]._len;
if (i < parts.length - 1) {
memcpy(retptr, self._ptr, self._len);
retptr += self._len;
}
}
return ret;
}
}
{
"compilationTarget": {
"src/services/nft/WrappedNFTHero.sol": "WrappedNFTHero"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":@axelar-network/=node_modules/@axelar-network/",
":@chainlink/=node_modules/@chainlink/",
":@eth-optimism/=node_modules/@eth-optimism/",
":@layerzerolabs/=node_modules/@layerzerolabs/",
":@openzeppelin/=node_modules/@openzeppelin/",
":@prb-math/=node_modules/@layerzerolabs/toolbox-foundry/lib/prb-math/",
":@prb/math/=node_modules/@layerzerolabs/toolbox-foundry/lib/prb-math/",
":@sablier/v2-core/=node_modules/@sablier/v2-core/",
":@uniswap/v3-core/=node_modules/@layerzerolabs/toolbox-foundry/lib/v3-core/",
":@uniswap/v3-periphery/=node_modules/@layerzerolabs/toolbox-foundry/lib/v3-periphery/",
":atoumic/=node_modules/@layerzerolabs/toolbox-foundry/lib/atoumic/src/",
":ds-test/=node_modules/@layerzerolabs/toolbox-foundry/lib/ds-test/",
":forge-std/=node_modules/@layerzerolabs/toolbox-foundry/lib/forge-std/src/",
":hardhat-deploy/=node_modules/hardhat-deploy/",
":hardhat/=node_modules/hardhat/",
":hero-tokens/test/=test/",
":heroglyph-library/=node_modules/@layerzerolabs/toolbox-foundry/lib/heroglyph-library/src/",
":solidity-bytes-utils/=node_modules/solidity-bytes-utils/"
],
"viaIR": true
}
[{"inputs":[{"internalType":"address","name":"_HCT","type":"address"},{"internalType":"address","name":"_nftPass","type":"address"},{"internalType":"address","name":"_inputCollection","type":"address"},{"internalType":"address","name":"_obeliskRegistry","type":"address"},{"internalType":"uint256","name":"_currentSupply","type":"uint256"},{"internalType":"uint32","name":"_collectionStartedUnixTime","type":"uint32"},{"internalType":"bool","name":"_premium","type":"bool"},{"internalType":"uint256","name":"_id","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyMinted","type":"error"},{"inputs":[],"name":"CannotTransferUnwrapFirst","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721IncorrectOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721InsufficientApproval","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC721InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC721InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721InvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC721InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC721InvalidSender","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721NonexistentToken","type":"error"},{"inputs":[],"name":"EmergencyModeIsActive","type":"error"},{"inputs":[],"name":"EmergencyWithdrawDisabled","type":"error"},{"inputs":[],"name":"FreeSlotAvailable","type":"error"},{"inputs":[],"name":"InvalidNameLength","type":"error"},{"inputs":[],"name":"InvalidWalletReceiver","type":"error"},{"inputs":[],"name":"NoFreeSlots","type":"error"},{"inputs":[],"name":"NotMinted","type":"error"},{"inputs":[],"name":"NotNFTHolder","type":"error"},{"inputs":[],"name":"NotNFTPassHolder","type":"error"},{"inputs":[],"name":"NotObeliskRegistry","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[],"name":"SameMultiplier","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","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":[],"name":"EmergencyWithdrawEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"freeSlotLeft","type":"uint256"}],"name":"FreeSlotUsed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"newMultiplier","type":"uint128"}],"name":"MultiplierUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"NameUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"inputCollectionNFTId","type":"uint256"}],"name":"SlotBought","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"stakedPool","type":"address"}],"name":"TickerActivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"stakedPool","type":"address"}],"name":"TickerClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"stakedPool","type":"address"}],"name":"TickerDeactivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Unwrapped","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Wrapped","type":"event"},{"inputs":[],"name":"COLLECTION_STARTED_UNIX_TIME","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FREE_SLOT_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FREE_SLOT_FOR_ODD","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HCT","outputs":[{"internalType":"contract IHCT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INPUT_COLLECTION","outputs":[{"internalType":"contract ERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_NAME_BYTES_LENGTH","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NFT_PASS","outputs":[{"internalType":"contract INFTPass","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PREMIUM","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RATE_PER_YEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SLOT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TICKER_SPLIT_STRING","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TICKER_START_IDENTITY","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TICKER_START_INDICE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyWithdrawEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableEmergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"freeSlots","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getIdentityInformation","outputs":[{"internalType":"bytes32","name":"identityInTicker_","type":"bytes32"},{"internalType":"address","name":"rewardReceiver_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getLinkedTickers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getNFTData","outputs":[{"components":[{"internalType":"bool","name":"isMinted","type":"bool"},{"internalType":"bool","name":"hasBeenRenamed","type":"bool"},{"internalType":"bool","name":"wrappedOnce","type":"bool"},{"internalType":"uint128","name":"assignedMultiplier","type":"uint128"}],"internalType":"struct IWrappedNFTHero.NFTData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getPendingRewards","outputs":[{"internalType":"uint256[]","name":"pendingRewards_","type":"uint256[]"},{"internalType":"address[]","name":"pendingRewardsTokens_","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWrapperMultiplier","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"names","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"nftPassAttached","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"obeliskRegistry","outputs":[{"internalType":"contract IObeliskRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"string","name":"_newName","type":"string"}],"name":"rename","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","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":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"unwrap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"updateMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_inputCollectionNFTId","type":"uint256"}],"name":"wrap","outputs":[],"stateMutability":"payable","type":"function"}]