编译器
0.8.24+commit.e11b9ed9
文件 1 的 24:AbstractNFT.sol
pragma solidity ^0.8.17;
import {ERC721ConduitPreapproved_Solady, ERC721} from "./tokens/erc721/ERC721ConduitPreapproved_Solady.sol";
import {json} from "./onchain/json.sol";
import {Metadata} from "./onchain/Metadata.sol";
import {LibString} from "solady/utils/LibString.sol";
import {Solarray} from "solarray/Solarray.sol";
import {OnchainTraits, DynamicTraits} from "./dynamic-traits/OnchainTraits.sol";
abstract contract AbstractNFT is OnchainTraits, ERC721ConduitPreapproved_Solady {
string _name;
string _symbol;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
return _stringURI(tokenId);
}
function _stringURI(uint256 tokenId) internal view virtual returns (string memory) {
return "";
}
function _attributes(uint256 tokenId) internal view virtual returns (string memory) {
string[] memory staticTraits = _staticAttributes(tokenId);
string[] memory dynamicTraits = _dynamicAttributes(tokenId);
return json.rawProperty("attributes", json.arrayOf(staticTraits, dynamicTraits));
}
function _staticAttributes(uint256 tokenId) internal view virtual returns (string[] memory);
function _image(uint256 tokenId) internal view virtual returns (string memory);
function supportsInterface(bytes4 interfaceId) public view virtual override(DynamicTraits, ERC721) returns (bool) {
return DynamicTraits.supportsInterface(interfaceId) || ERC721.supportsInterface(interfaceId);
}
}
文件 2 的 24:Base64.sol
pragma solidity ^0.8.4;
library Base64 {
function encode(bytes memory data, bool fileSafe, bool noPadding)
internal
pure
returns (string memory result)
{
assembly {
let dataLength := mload(data)
if dataLength {
let encodedLength := shl(2, div(add(dataLength, 2), 3))
result := mload(0x40)
mstore(0x1f, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef")
mstore(0x3f, xor("ghijklmnopqrstuvwxyz0123456789-_", mul(iszero(fileSafe), 0x0670)))
let ptr := add(result, 0x20)
let end := add(ptr, encodedLength)
let dataEnd := add(add(0x20, data), dataLength)
let dataEndValue := mload(dataEnd)
mstore(dataEnd, 0x00)
for {} 1 {} {
data := add(data, 3)
let input := mload(data)
mstore8(0, mload(and(shr(18, input), 0x3F)))
mstore8(1, mload(and(shr(12, input), 0x3F)))
mstore8(2, mload(and(shr(6, input), 0x3F)))
mstore8(3, mload(and(input, 0x3F)))
mstore(ptr, mload(0x00))
ptr := add(ptr, 4)
if iszero(lt(ptr, end)) { break }
}
mstore(dataEnd, dataEndValue)
mstore(0x40, add(end, 0x20))
let o := div(2, mod(dataLength, 3))
mstore(sub(ptr, o), shl(240, 0x3d3d))
o := mul(iszero(iszero(noPadding)), o)
mstore(sub(ptr, o), 0)
mstore(result, sub(encodedLength, o))
}
}
}
function encode(bytes memory data) internal pure returns (string memory result) {
result = encode(data, false, false);
}
function encode(bytes memory data, bool fileSafe)
internal
pure
returns (string memory result)
{
result = encode(data, fileSafe, false);
}
function decode(string memory data) internal pure returns (bytes memory result) {
assembly {
let dataLength := mload(data)
if dataLength {
let decodedLength := mul(shr(2, dataLength), 3)
for {} 1 {} {
if iszero(and(dataLength, 3)) {
let t := xor(mload(add(data, dataLength)), 0x3d3d)
decodedLength := sub(
decodedLength,
add(iszero(byte(30, t)), iszero(byte(31, t)))
)
break
}
decodedLength := add(decodedLength, sub(and(dataLength, 3), 1))
break
}
result := mload(0x40)
mstore(result, decodedLength)
let ptr := add(result, 0x20)
let end := add(ptr, decodedLength)
let m := 0xfc000000fc00686c7074787c8084888c9094989ca0a4a8acb0b4b8bcc0c4c8cc
mstore(0x5b, m)
mstore(0x3b, 0x04080c1014181c2024282c3034383c4044484c5054585c6064)
mstore(0x1a, 0xf8fcf800fcd0d4d8dce0e4e8ecf0f4)
for {} 1 {} {
data := add(data, 4)
let input := mload(data)
mstore(ptr, or(
and(m, mload(byte(28, input))),
shr(6, or(
and(m, mload(byte(29, input))),
shr(6, or(
and(m, mload(byte(30, input))),
shr(6, mload(byte(31, input)))
))
))
))
ptr := add(ptr, 3)
if iszero(lt(ptr, end)) { break }
}
mstore(0x40, add(end, 0x20))
mstore(end, 0)
mstore(0x60, 0)
}
}
}
}
文件 3 的 24:Constants.sol
pragma solidity ^0.8.17;
address constant CONDUIT = 0x1E0049783F008A0085193E00003D00cd54003c71;
uint256 constant _APPROVAL_FOR_ALL_EVENT_SIGNATURE = 0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31;
uint256 constant SOLADY_ERC721_MASTER_SLOT_SEED_MASKED = 0x0a5a2e7a00000000;
uint256 constant SOLADY_ERC1155_MASTER_SLOT_SEED = 0x9a31110384e0b0c9;
uint256 constant SOLADY_TRANSFER_SINGLE_EVENT_SIGNATURE =
0xc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62;
uint256 constant SOLADY_TRANSFER_BATCH_EVENT_SIGNATURE =
0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb;
uint256 constant SOLADY_ERC20_ALLOWANCE_SLOT_SEED = 0x7f5e9f20;
uint256 constant SOLADY_ERC20_BALANCE_SLOT_SEED = 0x87a211a2;
uint256 constant SOLADY_ERC20_TRANSFER_EVENT_SIGNATURE =
0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;
uint256 constant SOLADY_ERC20_APPROVAL_EVENT_SIGNATURE = 0;
uint256 constant SOLADY_ERC20_NONCES_SLOT_SEED_WITH_SIGNATURE_PREFIX = 0x383775081901;
bytes32 constant SOLADY_ERC20_DOMAIN_TYPEHASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;
bytes32 constant SOLADY_ERC20_VERSION_HASH = 0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6;
bytes32 constant SOLADY_ERC20_PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
文件 4 的 24:DateTimeLib.sol
pragma solidity ^0.8.4;
library DateTimeLib {
uint256 internal constant MON = 1;
uint256 internal constant TUE = 2;
uint256 internal constant WED = 3;
uint256 internal constant THU = 4;
uint256 internal constant FRI = 5;
uint256 internal constant SAT = 6;
uint256 internal constant SUN = 7;
uint256 internal constant JAN = 1;
uint256 internal constant FEB = 2;
uint256 internal constant MAR = 3;
uint256 internal constant APR = 4;
uint256 internal constant MAY = 5;
uint256 internal constant JUN = 6;
uint256 internal constant JUL = 7;
uint256 internal constant AUG = 8;
uint256 internal constant SEP = 9;
uint256 internal constant OCT = 10;
uint256 internal constant NOV = 11;
uint256 internal constant DEC = 12;
uint256 internal constant MAX_SUPPORTED_YEAR = 0xffffffff;
uint256 internal constant MAX_SUPPORTED_EPOCH_DAY = 0x16d3e098039;
uint256 internal constant MAX_SUPPORTED_TIMESTAMP = 0x1e18549868c76ff;
function dateToEpochDay(uint256 year, uint256 month, uint256 day)
internal
pure
returns (uint256 epochDay)
{
assembly {
year := sub(year, lt(month, 3))
let doy := add(shr(11, add(mul(62719, mod(add(month, 9), 12)), 769)), day)
let yoe := mod(year, 400)
let doe := sub(add(add(mul(yoe, 365), shr(2, yoe)), doy), div(yoe, 100))
epochDay := sub(add(mul(div(year, 400), 146097), doe), 719469)
}
}
function epochDayToDate(uint256 epochDay)
internal
pure
returns (uint256 year, uint256 month, uint256 day)
{
assembly {
epochDay := add(epochDay, 719468)
let doe := mod(epochDay, 146097)
let yoe :=
div(sub(sub(add(doe, div(doe, 36524)), div(doe, 1460)), eq(doe, 146096)), 365)
let doy := sub(doe, sub(add(mul(365, yoe), shr(2, yoe)), div(yoe, 100)))
let mp := div(add(mul(5, doy), 2), 153)
day := add(sub(doy, shr(11, add(mul(mp, 62719), 769))), 1)
month := byte(mp, shl(160, 0x030405060708090a0b0c0102))
year := add(add(yoe, mul(div(epochDay, 146097), 400)), lt(month, 3))
}
}
function dateToTimestamp(uint256 year, uint256 month, uint256 day)
internal
pure
returns (uint256 result)
{
unchecked {
result = dateToEpochDay(year, month, day) * 86400;
}
}
function timestampToDate(uint256 timestamp)
internal
pure
returns (uint256 year, uint256 month, uint256 day)
{
(year, month, day) = epochDayToDate(timestamp / 86400);
}
function dateTimeToTimestamp(
uint256 year,
uint256 month,
uint256 day,
uint256 hour,
uint256 minute,
uint256 second
) internal pure returns (uint256 result) {
unchecked {
result = dateToEpochDay(year, month, day) * 86400 + hour * 3600 + minute * 60 + second;
}
}
function timestampToDateTime(uint256 timestamp)
internal
pure
returns (
uint256 year,
uint256 month,
uint256 day,
uint256 hour,
uint256 minute,
uint256 second
)
{
unchecked {
(year, month, day) = epochDayToDate(timestamp / 86400);
uint256 secs = timestamp % 86400;
hour = secs / 3600;
secs = secs % 3600;
minute = secs / 60;
second = secs % 60;
}
}
function isLeapYear(uint256 year) internal pure returns (bool leap) {
assembly {
leap := iszero(and(add(mul(iszero(mod(year, 25)), 12), 3), year))
}
}
function daysInMonth(uint256 year, uint256 month) internal pure returns (uint256 result) {
bool flag = isLeapYear(year);
assembly {
result :=
add(byte(month, shl(152, 0x1f1c1f1e1f1e1f1f1e1f1e1f)), and(eq(month, 2), flag))
}
}
function weekday(uint256 timestamp) internal pure returns (uint256 result) {
unchecked {
result = ((timestamp / 86400 + 3) % 7) + 1;
}
}
function isSupportedDate(uint256 year, uint256 month, uint256 day)
internal
pure
returns (bool result)
{
uint256 md = daysInMonth(year, month);
assembly {
result :=
and(
lt(sub(year, 1970), sub(MAX_SUPPORTED_YEAR, 1969)),
and(lt(sub(month, 1), 12), lt(sub(day, 1), md))
)
}
}
function isSupportedDateTime(
uint256 year,
uint256 month,
uint256 day,
uint256 hour,
uint256 minute,
uint256 second
) internal pure returns (bool result) {
if (isSupportedDate(year, month, day)) {
assembly {
result := and(lt(hour, 24), and(lt(minute, 60), lt(second, 60)))
}
}
}
function isSupportedEpochDay(uint256 epochDay) internal pure returns (bool result) {
unchecked {
result = epochDay < MAX_SUPPORTED_EPOCH_DAY + 1;
}
}
function isSupportedTimestamp(uint256 timestamp) internal pure returns (bool result) {
unchecked {
result = timestamp < MAX_SUPPORTED_TIMESTAMP + 1;
}
}
function nthWeekdayInMonthOfYearTimestamp(uint256 year, uint256 month, uint256 n, uint256 wd)
internal
pure
returns (uint256 result)
{
uint256 d = dateToEpochDay(year, month, 1);
uint256 md = daysInMonth(year, month);
assembly {
let diff := sub(wd, add(mod(add(d, 3), 7), 1))
let date := add(mul(sub(n, 1), 7), add(mul(gt(diff, 6), 7), diff))
result := mul(mul(86400, add(date, d)), and(lt(date, md), iszero(iszero(n))))
}
}
function mondayTimestamp(uint256 timestamp) internal pure returns (uint256 result) {
uint256 t = timestamp;
assembly {
let day := div(t, 86400)
result := mul(mul(sub(day, mod(add(day, 3), 7)), 86400), gt(t, 345599))
}
}
function isWeekEnd(uint256 timestamp) internal pure returns (bool result) {
result = weekday(timestamp) > FRI;
}
function addYears(uint256 timestamp, uint256 numYears) internal pure returns (uint256 result) {
(uint256 year, uint256 month, uint256 day) = epochDayToDate(timestamp / 86400);
result = _offsetted(year + numYears, month, day, timestamp);
}
function addMonths(uint256 timestamp, uint256 numMonths)
internal
pure
returns (uint256 result)
{
(uint256 year, uint256 month, uint256 day) = epochDayToDate(timestamp / 86400);
month = _sub(month + numMonths, 1);
result = _offsetted(year + month / 12, _add(month % 12, 1), day, timestamp);
}
function addDays(uint256 timestamp, uint256 numDays) internal pure returns (uint256 result) {
result = timestamp + numDays * 86400;
}
function addHours(uint256 timestamp, uint256 numHours) internal pure returns (uint256 result) {
result = timestamp + numHours * 3600;
}
function addMinutes(uint256 timestamp, uint256 numMinutes)
internal
pure
returns (uint256 result)
{
result = timestamp + numMinutes * 60;
}
function addSeconds(uint256 timestamp, uint256 numSeconds)
internal
pure
returns (uint256 result)
{
result = timestamp + numSeconds;
}
function subYears(uint256 timestamp, uint256 numYears) internal pure returns (uint256 result) {
(uint256 year, uint256 month, uint256 day) = epochDayToDate(timestamp / 86400);
result = _offsetted(year - numYears, month, day, timestamp);
}
function subMonths(uint256 timestamp, uint256 numMonths)
internal
pure
returns (uint256 result)
{
(uint256 year, uint256 month, uint256 day) = epochDayToDate(timestamp / 86400);
uint256 yearMonth = _totalMonths(year, month) - _add(numMonths, 1);
result = _offsetted(yearMonth / 12, _add(yearMonth % 12, 1), day, timestamp);
}
function subDays(uint256 timestamp, uint256 numDays) internal pure returns (uint256 result) {
result = timestamp - numDays * 86400;
}
function subHours(uint256 timestamp, uint256 numHours) internal pure returns (uint256 result) {
result = timestamp - numHours * 3600;
}
function subMinutes(uint256 timestamp, uint256 numMinutes)
internal
pure
returns (uint256 result)
{
result = timestamp - numMinutes * 60;
}
function subSeconds(uint256 timestamp, uint256 numSeconds)
internal
pure
returns (uint256 result)
{
result = timestamp - numSeconds;
}
function diffYears(uint256 fromTimestamp, uint256 toTimestamp)
internal
pure
returns (uint256 result)
{
toTimestamp - fromTimestamp;
(uint256 fromYear,,) = epochDayToDate(fromTimestamp / 86400);
(uint256 toYear,,) = epochDayToDate(toTimestamp / 86400);
result = _sub(toYear, fromYear);
}
function diffMonths(uint256 fromTimestamp, uint256 toTimestamp)
internal
pure
returns (uint256 result)
{
toTimestamp - fromTimestamp;
(uint256 fromYear, uint256 fromMonth,) = epochDayToDate(fromTimestamp / 86400);
(uint256 toYear, uint256 toMonth,) = epochDayToDate(toTimestamp / 86400);
result = _sub(_totalMonths(toYear, toMonth), _totalMonths(fromYear, fromMonth));
}
function diffDays(uint256 fromTimestamp, uint256 toTimestamp)
internal
pure
returns (uint256 result)
{
result = (toTimestamp - fromTimestamp) / 86400;
}
function diffHours(uint256 fromTimestamp, uint256 toTimestamp)
internal
pure
returns (uint256 result)
{
result = (toTimestamp - fromTimestamp) / 3600;
}
function diffMinutes(uint256 fromTimestamp, uint256 toTimestamp)
internal
pure
returns (uint256 result)
{
result = (toTimestamp - fromTimestamp) / 60;
}
function diffSeconds(uint256 fromTimestamp, uint256 toTimestamp)
internal
pure
returns (uint256 result)
{
result = toTimestamp - fromTimestamp;
}
function _totalMonths(uint256 numYears, uint256 numMonths)
private
pure
returns (uint256 total)
{
unchecked {
total = numYears * 12 + numMonths;
}
}
function _add(uint256 a, uint256 b) private pure returns (uint256 c) {
unchecked {
c = a + b;
}
}
function _sub(uint256 a, uint256 b) private pure returns (uint256 c) {
unchecked {
c = a - b;
}
}
function _offsetted(uint256 year, uint256 month, uint256 day, uint256 timestamp)
private
pure
returns (uint256 result)
{
uint256 dm = daysInMonth(year, month);
if (day >= dm) {
day = dm;
}
result = dateToEpochDay(year, month, day) * 86400 + (timestamp % 86400);
}
}
文件 5 的 24:DynamicTraits.sol
pragma solidity ^0.8.19;
import {IERC7496} from "./interfaces/IERC7496.sol";
library DynamicTraitsStorage {
struct Layout {
mapping(uint256 tokenId => mapping(bytes32 traitKey => bytes32 traitValue)) _traits;
string _traitMetadataURI;
}
bytes32 internal constant STORAGE_SLOT = keccak256("contracts.storage.erc7496-dynamictraits");
function layout() internal pure returns (Layout storage l) {
bytes32 slot = STORAGE_SLOT;
assembly {
l.slot := slot
}
}
}
contract DynamicTraits is IERC7496 {
using DynamicTraitsStorage for DynamicTraitsStorage.Layout;
function getTraitValue(uint256 tokenId, bytes32 traitKey) public view virtual returns (bytes32 traitValue) {
return DynamicTraitsStorage.layout()._traits[tokenId][traitKey];
}
function getTraitValues(uint256 tokenId, bytes32[] calldata traitKeys)
public
view
virtual
returns (bytes32[] memory traitValues)
{
uint256 length = traitKeys.length;
traitValues = new bytes32[](length);
for (uint256 i = 0; i < length;) {
bytes32 traitKey = traitKeys[i];
traitValues[i] = getTraitValue(tokenId, traitKey);
unchecked {
++i;
}
}
}
function getTraitMetadataURI() external view virtual returns (string memory labelsURI) {
return DynamicTraitsStorage.layout()._traitMetadataURI;
}
function setTrait(uint256 tokenId, bytes32 traitKey, bytes32 newValue) public virtual {
bytes32 existingValue = DynamicTraitsStorage.layout()._traits[tokenId][traitKey];
if (existingValue == newValue) {
revert TraitValueUnchanged();
}
_setTrait(tokenId, traitKey, newValue);
emit TraitUpdated(traitKey, tokenId, newValue);
}
function _setTrait(uint256 tokenId, bytes32 traitKey, bytes32 newValue) internal virtual {
DynamicTraitsStorage.layout()._traits[tokenId][traitKey] = newValue;
}
function _setTraitMetadataURI(string memory uri) internal virtual {
DynamicTraitsStorage.layout()._traitMetadataURI = uri;
emit TraitMetadataURIUpdated();
}
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC7496).interfaceId;
}
}
文件 6 的 24:ECDSA.sol
pragma solidity ^0.8.4;
library ECDSA {
uint256 internal constant N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141;
uint256 private constant _HALF_N_PLUS_1 =
0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1;
error InvalidSignature();
function recover(bytes32 hash, bytes memory signature) internal view returns (address result) {
assembly {
result := 1
let m := mload(0x40)
for {} 1 {} {
mstore(0x00, hash)
mstore(0x40, mload(add(signature, 0x20)))
if eq(mload(signature), 64) {
let vs := mload(add(signature, 0x40))
mstore(0x20, add(shr(255, vs), 27))
mstore(0x60, shr(1, shl(1, vs)))
break
}
if eq(mload(signature), 65) {
mstore(0x20, byte(0, mload(add(signature, 0x60))))
mstore(0x60, mload(add(signature, 0x40)))
break
}
result := 0
break
}
result :=
mload(
staticcall(
gas(),
result,
0x00,
0x80,
0x01,
0x20
)
)
if iszero(returndatasize()) {
mstore(0x00, 0x8baa579f)
revert(0x1c, 0x04)
}
mstore(0x60, 0)
mstore(0x40, m)
}
}
function recoverCalldata(bytes32 hash, bytes calldata signature)
internal
view
returns (address result)
{
assembly {
result := 1
let m := mload(0x40)
mstore(0x00, hash)
for {} 1 {} {
if eq(signature.length, 64) {
let vs := calldataload(add(signature.offset, 0x20))
mstore(0x20, add(shr(255, vs), 27))
mstore(0x40, calldataload(signature.offset))
mstore(0x60, shr(1, shl(1, vs)))
break
}
if eq(signature.length, 65) {
mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40))))
calldatacopy(0x40, signature.offset, 0x40)
break
}
result := 0
break
}
result :=
mload(
staticcall(
gas(),
result,
0x00,
0x80,
0x01,
0x20
)
)
if iszero(returndatasize()) {
mstore(0x00, 0x8baa579f)
revert(0x1c, 0x04)
}
mstore(0x60, 0)
mstore(0x40, m)
}
}
function recover(bytes32 hash, bytes32 r, bytes32 vs) internal view returns (address result) {
assembly {
let m := mload(0x40)
mstore(0x00, hash)
mstore(0x20, add(shr(255, vs), 27))
mstore(0x40, r)
mstore(0x60, shr(1, shl(1, vs)))
result :=
mload(
staticcall(
gas(),
1,
0x00,
0x80,
0x01,
0x20
)
)
if iszero(returndatasize()) {
mstore(0x00, 0x8baa579f)
revert(0x1c, 0x04)
}
mstore(0x60, 0)
mstore(0x40, m)
}
}
function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s)
internal
view
returns (address result)
{
assembly {
let m := mload(0x40)
mstore(0x00, hash)
mstore(0x20, and(v, 0xff))
mstore(0x40, r)
mstore(0x60, s)
result :=
mload(
staticcall(
gas(),
1,
0x00,
0x80,
0x01,
0x20
)
)
if iszero(returndatasize()) {
mstore(0x00, 0x8baa579f)
revert(0x1c, 0x04)
}
mstore(0x60, 0)
mstore(0x40, m)
}
}
function tryRecover(bytes32 hash, bytes memory signature)
internal
view
returns (address result)
{
assembly {
result := 1
let m := mload(0x40)
for {} 1 {} {
mstore(0x00, hash)
mstore(0x40, mload(add(signature, 0x20)))
if eq(mload(signature), 64) {
let vs := mload(add(signature, 0x40))
mstore(0x20, add(shr(255, vs), 27))
mstore(0x60, shr(1, shl(1, vs)))
break
}
if eq(mload(signature), 65) {
mstore(0x20, byte(0, mload(add(signature, 0x60))))
mstore(0x60, mload(add(signature, 0x40)))
break
}
result := 0
break
}
pop(
staticcall(
gas(),
result,
0x00,
0x80,
0x40,
0x20
)
)
mstore(0x60, 0)
result := mload(xor(0x60, returndatasize()))
mstore(0x40, m)
}
}
function tryRecoverCalldata(bytes32 hash, bytes calldata signature)
internal
view
returns (address result)
{
assembly {
result := 1
let m := mload(0x40)
mstore(0x00, hash)
for {} 1 {} {
if eq(signature.length, 64) {
let vs := calldataload(add(signature.offset, 0x20))
mstore(0x20, add(shr(255, vs), 27))
mstore(0x40, calldataload(signature.offset))
mstore(0x60, shr(1, shl(1, vs)))
break
}
if eq(signature.length, 65) {
mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40))))
calldatacopy(0x40, signature.offset, 0x40)
break
}
result := 0
break
}
pop(
staticcall(
gas(),
result,
0x00,
0x80,
0x40,
0x20
)
)
mstore(0x60, 0)
result := mload(xor(0x60, returndatasize()))
mstore(0x40, m)
}
}
function tryRecover(bytes32 hash, bytes32 r, bytes32 vs)
internal
view
returns (address result)
{
assembly {
let m := mload(0x40)
mstore(0x00, hash)
mstore(0x20, add(shr(255, vs), 27))
mstore(0x40, r)
mstore(0x60, shr(1, shl(1, vs)))
pop(
staticcall(
gas(),
1,
0x00,
0x80,
0x40,
0x20
)
)
mstore(0x60, 0)
result := mload(xor(0x60, returndatasize()))
mstore(0x40, m)
}
}
function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s)
internal
view
returns (address result)
{
assembly {
let m := mload(0x40)
mstore(0x00, hash)
mstore(0x20, and(v, 0xff))
mstore(0x40, r)
mstore(0x60, s)
pop(
staticcall(
gas(),
1,
0x00,
0x80,
0x40,
0x20
)
)
mstore(0x60, 0)
result := mload(xor(0x60, returndatasize()))
mstore(0x40, m)
}
}
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 result) {
assembly {
mstore(0x20, hash)
mstore(0x00, "\x00\x00\x00\x00\x19Ethereum Signed Message:\n32")
result := keccak256(0x04, 0x3c)
}
}
function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32 result) {
assembly {
let sLength := mload(s)
let o := 0x20
mstore(o, "\x19Ethereum Signed Message:\n")
mstore(0x00, 0x00)
for { let temp := sLength } 1 {} {
o := sub(o, 1)
mstore8(o, add(48, mod(temp, 10)))
temp := div(temp, 10)
if iszero(temp) { break }
}
let n := sub(0x3a, o)
returndatacopy(returndatasize(), returndatasize(), gt(n, 0x20))
mstore(s, or(mload(0x00), mload(n)))
result := keccak256(add(s, sub(0x20, n)), add(n, sLength))
mstore(s, sLength)
}
}
function canonicalHash(bytes memory signature) internal pure returns (bytes32 result) {
assembly {
let l := mload(signature)
for {} 1 {} {
mstore(0x00, mload(add(signature, 0x20)))
let s := mload(add(signature, 0x40))
let v := mload(add(signature, 0x41))
if eq(l, 64) {
v := add(shr(255, s), 27)
s := shr(1, shl(1, s))
}
if iszero(lt(s, _HALF_N_PLUS_1)) {
v := xor(v, 7)
s := sub(N, s)
}
mstore(0x21, v)
mstore(0x20, s)
result := keccak256(0x00, 0x41)
mstore(0x21, 0)
break
}
if iszero(lt(sub(l, 64), 2)) {
result := xor(keccak256(add(signature, 0x20), l), 0xd62f1ab2)
}
}
}
function canonicalHashCalldata(bytes calldata signature)
internal
pure
returns (bytes32 result)
{
assembly {
let l := signature.length
for {} 1 {} {
mstore(0x00, calldataload(signature.offset))
let s := calldataload(add(signature.offset, 0x20))
let v := calldataload(add(signature.offset, 0x21))
if eq(l, 64) {
v := add(shr(255, s), 27)
s := shr(1, shl(1, s))
}
if iszero(lt(s, _HALF_N_PLUS_1)) {
v := xor(v, 7)
s := sub(N, s)
}
mstore(0x21, v)
mstore(0x20, s)
result := keccak256(0x00, 0x41)
mstore(0x21, 0)
break
}
if iszero(lt(sub(l, 64), 2)) {
calldatacopy(mload(0x40), signature.offset, l)
result := xor(keccak256(mload(0x40), l), 0xd62f1ab2)
}
}
}
function canonicalHash(bytes32 r, bytes32 vs) internal pure returns (bytes32 result) {
assembly {
mstore(0x00, r)
let v := add(shr(255, vs), 27)
let s := shr(1, shl(1, vs))
mstore(0x21, v)
mstore(0x20, s)
result := keccak256(0x00, 0x41)
mstore(0x21, 0)
}
}
function canonicalHash(uint8 v, bytes32 r, bytes32 s) internal pure returns (bytes32 result) {
assembly {
mstore(0x00, r)
if iszero(lt(s, _HALF_N_PLUS_1)) {
v := xor(v, 7)
s := sub(N, s)
}
mstore(0x21, v)
mstore(0x20, s)
result := keccak256(0x00, 0x41)
mstore(0x21, 0)
}
}
function emptySignature() internal pure returns (bytes calldata signature) {
assembly {
signature.length := 0
}
}
}
文件 7 的 24:ERC721.sol
pragma solidity ^0.8.4;
abstract contract ERC721 {
uint256 internal constant _MAX_ACCOUNT_BALANCE = 0xffffffff;
error NotOwnerNorApproved();
error TokenDoesNotExist();
error TokenAlreadyExists();
error BalanceQueryForZeroAddress();
error TransferToZeroAddress();
error TransferFromIncorrectOwner();
error AccountBalanceOverflow();
error TransferToNonERC721ReceiverImplementer();
event Transfer(address indexed from, address indexed to, uint256 indexed id);
event Approval(address indexed owner, address indexed account, uint256 indexed id);
event ApprovalForAll(address indexed owner, address indexed operator, bool isApproved);
uint256 private constant _TRANSFER_EVENT_SIGNATURE =
0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;
uint256 private constant _APPROVAL_EVENT_SIGNATURE =
0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925;
uint256 private constant _APPROVAL_FOR_ALL_EVENT_SIGNATURE =
0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31;
uint256 private constant _ERC721_MASTER_SLOT_SEED = 0x7d8825530a5a2e7a << 192;
uint256 private constant _ERC721_MASTER_SLOT_SEED_MASKED = 0x0a5a2e7a00000000;
function name() public view virtual returns (string memory);
function symbol() public view virtual returns (string memory);
function tokenURI(uint256 id) public view virtual returns (string memory);
function ownerOf(uint256 id) public view virtual returns (address result) {
result = _ownerOf(id);
assembly {
if iszero(result) {
mstore(0x00, 0xceea21b6)
revert(0x1c, 0x04)
}
}
}
function balanceOf(address owner) public view virtual returns (uint256 result) {
assembly {
if iszero(owner) {
mstore(0x00, 0x8f4eb604)
revert(0x1c, 0x04)
}
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
mstore(0x00, owner)
result := and(sload(keccak256(0x0c, 0x1c)), _MAX_ACCOUNT_BALANCE)
}
}
function getApproved(uint256 id) public view virtual returns (address result) {
assembly {
mstore(0x00, id)
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
if iszero(shl(96, sload(ownershipSlot))) {
mstore(0x00, 0xceea21b6)
revert(0x1c, 0x04)
}
result := sload(add(1, ownershipSlot))
}
}
function approve(address account, uint256 id) public payable virtual {
_approve(msg.sender, account, id);
}
function isApprovedForAll(address owner, address operator)
public
view
virtual
returns (bool result)
{
assembly {
mstore(0x1c, operator)
mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED)
mstore(0x00, owner)
result := sload(keccak256(0x0c, 0x30))
}
}
function setApprovalForAll(address operator, bool isApproved) public virtual {
assembly {
isApproved := iszero(iszero(isApproved))
mstore(0x1c, operator)
mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED)
mstore(0x00, caller())
sstore(keccak256(0x0c, 0x30), isApproved)
mstore(0x00, isApproved)
log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, caller(), shr(96, shl(96, operator)))
}
}
function transferFrom(address from, address to, uint256 id) public payable virtual {
_beforeTokenTransfer(from, to, id);
assembly {
let bitmaskAddress := shr(96, not(0))
from := and(bitmaskAddress, from)
to := and(bitmaskAddress, to)
mstore(0x00, id)
mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, caller()))
let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
let ownershipPacked := sload(ownershipSlot)
let owner := and(bitmaskAddress, ownershipPacked)
if iszero(mul(owner, eq(owner, from))) {
mstore(shl(2, iszero(owner)), 0xceea21b6a1148100)
revert(0x1c, 0x04)
}
{
mstore(0x00, from)
let approvedAddress := sload(add(1, ownershipSlot))
if iszero(or(eq(caller(), from), eq(caller(), approvedAddress))) {
if iszero(sload(keccak256(0x0c, 0x30))) {
mstore(0x00, 0x4b6e7f18)
revert(0x1c, 0x04)
}
}
if approvedAddress { sstore(add(1, ownershipSlot), 0) }
}
sstore(ownershipSlot, xor(ownershipPacked, xor(from, to)))
{
let fromBalanceSlot := keccak256(0x0c, 0x1c)
sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1))
}
{
mstore(0x00, to)
let toBalanceSlot := keccak256(0x0c, 0x1c)
let toBalanceSlotPacked := add(sload(toBalanceSlot), 1)
if iszero(mul(to, and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE))) {
mstore(shl(2, iszero(to)), 0xea553b3401336cea)
revert(0x1c, 0x04)
}
sstore(toBalanceSlot, toBalanceSlotPacked)
}
log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id)
}
_afterTokenTransfer(from, to, id);
}
function safeTransferFrom(address from, address to, uint256 id) public payable virtual {
transferFrom(from, to, id);
if (_hasCode(to)) _checkOnERC721Received(from, to, id, "");
}
function safeTransferFrom(address from, address to, uint256 id, bytes calldata data)
public
payable
virtual
{
transferFrom(from, to, id);
if (_hasCode(to)) _checkOnERC721Received(from, to, id, data);
}
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) {
assembly {
let s := shr(224, interfaceId)
result := or(or(eq(s, 0x01ffc9a7), eq(s, 0x80ac58cd)), eq(s, 0x5b5e139f))
}
}
function _exists(uint256 id) internal view virtual returns (bool result) {
assembly {
mstore(0x00, id)
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
result := iszero(iszero(shl(96, sload(add(id, add(id, keccak256(0x00, 0x20)))))))
}
}
function _ownerOf(uint256 id) internal view virtual returns (address result) {
assembly {
mstore(0x00, id)
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
result := shr(96, shl(96, sload(add(id, add(id, keccak256(0x00, 0x20))))))
}
}
function _getAux(address owner) internal view virtual returns (uint224 result) {
assembly {
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
mstore(0x00, owner)
result := shr(32, sload(keccak256(0x0c, 0x1c)))
}
}
function _setAux(address owner, uint224 value) internal virtual {
assembly {
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
mstore(0x00, owner)
let balanceSlot := keccak256(0x0c, 0x1c)
let packed := sload(balanceSlot)
sstore(balanceSlot, xor(packed, shl(32, xor(value, shr(32, packed)))))
}
}
function _getExtraData(uint256 id) internal view virtual returns (uint96 result) {
assembly {
mstore(0x00, id)
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
result := shr(160, sload(add(id, add(id, keccak256(0x00, 0x20)))))
}
}
function _setExtraData(uint256 id, uint96 value) internal virtual {
assembly {
mstore(0x00, id)
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
let packed := sload(ownershipSlot)
sstore(ownershipSlot, xor(packed, shl(160, xor(value, shr(160, packed)))))
}
}
function _mint(address to, uint256 id) internal virtual {
_beforeTokenTransfer(address(0), to, id);
assembly {
to := shr(96, shl(96, to))
mstore(0x00, id)
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
let ownershipPacked := sload(ownershipSlot)
if shl(96, ownershipPacked) {
mstore(0x00, 0xc991cbb1)
revert(0x1c, 0x04)
}
sstore(ownershipSlot, or(ownershipPacked, to))
{
mstore(0x00, to)
let balanceSlot := keccak256(0x0c, 0x1c)
let balanceSlotPacked := add(sload(balanceSlot), 1)
if iszero(mul(to, and(balanceSlotPacked, _MAX_ACCOUNT_BALANCE))) {
mstore(shl(2, iszero(to)), 0xea553b3401336cea)
revert(0x1c, 0x04)
}
sstore(balanceSlot, balanceSlotPacked)
}
log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, 0, to, id)
}
_afterTokenTransfer(address(0), to, id);
}
function _mintAndSetExtraDataUnchecked(address to, uint256 id, uint96 value) internal virtual {
_beforeTokenTransfer(address(0), to, id);
assembly {
to := shr(96, shl(96, to))
mstore(0x00, id)
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
sstore(add(id, add(id, keccak256(0x00, 0x20))), or(shl(160, value), to))
{
mstore(0x00, to)
let balanceSlot := keccak256(0x0c, 0x1c)
let balanceSlotPacked := add(sload(balanceSlot), 1)
if iszero(mul(to, and(balanceSlotPacked, _MAX_ACCOUNT_BALANCE))) {
mstore(shl(2, iszero(to)), 0xea553b3401336cea)
revert(0x1c, 0x04)
}
sstore(balanceSlot, balanceSlotPacked)
}
log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, 0, to, id)
}
_afterTokenTransfer(address(0), to, id);
}
function _safeMint(address to, uint256 id) internal virtual {
_safeMint(to, id, "");
}
function _safeMint(address to, uint256 id, bytes memory data) internal virtual {
_mint(to, id);
if (_hasCode(to)) _checkOnERC721Received(address(0), to, id, data);
}
function _burn(uint256 id) internal virtual {
_burn(address(0), id);
}
function _burn(address by, uint256 id) internal virtual {
address owner = ownerOf(id);
_beforeTokenTransfer(owner, address(0), id);
assembly {
by := shr(96, shl(96, by))
mstore(0x00, id)
mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by))
let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
let ownershipPacked := sload(ownershipSlot)
owner := shr(96, shl(96, ownershipPacked))
if iszero(owner) {
mstore(0x00, 0xceea21b6)
revert(0x1c, 0x04)
}
{
mstore(0x00, owner)
let approvedAddress := sload(add(1, ownershipSlot))
if iszero(or(iszero(by), or(eq(by, owner), eq(by, approvedAddress)))) {
if iszero(sload(keccak256(0x0c, 0x30))) {
mstore(0x00, 0x4b6e7f18)
revert(0x1c, 0x04)
}
}
if approvedAddress { sstore(add(1, ownershipSlot), 0) }
}
sstore(ownershipSlot, xor(ownershipPacked, owner))
{
let balanceSlot := keccak256(0x0c, 0x1c)
sstore(balanceSlot, sub(sload(balanceSlot), 1))
}
log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, owner, 0, id)
}
_afterTokenTransfer(owner, address(0), id);
}
function _isApprovedOrOwner(address account, uint256 id)
internal
view
virtual
returns (bool result)
{
assembly {
result := 1
account := shr(96, shl(96, account))
mstore(0x00, id)
mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, account))
let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
let owner := shr(96, shl(96, sload(ownershipSlot)))
if iszero(owner) {
mstore(0x00, 0xceea21b6)
revert(0x1c, 0x04)
}
if iszero(eq(account, owner)) {
mstore(0x00, owner)
if iszero(sload(keccak256(0x0c, 0x30))) {
result := eq(account, sload(add(1, ownershipSlot)))
}
}
}
}
function _getApproved(uint256 id) internal view virtual returns (address result) {
assembly {
mstore(0x00, id)
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
result := sload(add(1, add(id, add(id, keccak256(0x00, 0x20)))))
}
}
function _approve(address account, uint256 id) internal virtual {
_approve(address(0), account, id);
}
function _approve(address by, address account, uint256 id) internal virtual {
assembly {
let bitmaskAddress := shr(96, not(0))
account := and(bitmaskAddress, account)
by := and(bitmaskAddress, by)
mstore(0x00, id)
mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by))
let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
let owner := and(bitmaskAddress, sload(ownershipSlot))
if iszero(owner) {
mstore(0x00, 0xceea21b6)
revert(0x1c, 0x04)
}
if iszero(or(iszero(by), eq(by, owner))) {
mstore(0x00, owner)
if iszero(sload(keccak256(0x0c, 0x30))) {
mstore(0x00, 0x4b6e7f18)
revert(0x1c, 0x04)
}
}
sstore(add(1, ownershipSlot), account)
log4(codesize(), 0x00, _APPROVAL_EVENT_SIGNATURE, owner, account, id)
}
}
function _setApprovalForAll(address by, address operator, bool isApproved) internal virtual {
assembly {
by := shr(96, shl(96, by))
operator := shr(96, shl(96, operator))
isApproved := iszero(iszero(isApproved))
mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator))
mstore(0x00, by)
sstore(keccak256(0x0c, 0x30), isApproved)
mstore(0x00, isApproved)
log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, by, operator)
}
}
function _transfer(address from, address to, uint256 id) internal virtual {
_transfer(address(0), from, to, id);
}
function _transfer(address by, address from, address to, uint256 id) internal virtual {
_beforeTokenTransfer(from, to, id);
assembly {
let bitmaskAddress := shr(96, not(0))
from := and(bitmaskAddress, from)
to := and(bitmaskAddress, to)
by := and(bitmaskAddress, by)
mstore(0x00, id)
mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by))
let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
let ownershipPacked := sload(ownershipSlot)
let owner := and(bitmaskAddress, ownershipPacked)
if iszero(mul(owner, eq(owner, from))) {
mstore(shl(2, iszero(owner)), 0xceea21b6a1148100)
revert(0x1c, 0x04)
}
{
mstore(0x00, from)
let approvedAddress := sload(add(1, ownershipSlot))
if iszero(or(iszero(by), or(eq(by, from), eq(by, approvedAddress)))) {
if iszero(sload(keccak256(0x0c, 0x30))) {
mstore(0x00, 0x4b6e7f18)
revert(0x1c, 0x04)
}
}
if approvedAddress { sstore(add(1, ownershipSlot), 0) }
}
sstore(ownershipSlot, xor(ownershipPacked, xor(from, to)))
{
let fromBalanceSlot := keccak256(0x0c, 0x1c)
sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1))
}
{
mstore(0x00, to)
let toBalanceSlot := keccak256(0x0c, 0x1c)
let toBalanceSlotPacked := add(sload(toBalanceSlot), 1)
if iszero(mul(to, and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE))) {
mstore(shl(2, iszero(to)), 0xea553b3401336cea)
revert(0x1c, 0x04)
}
sstore(toBalanceSlot, toBalanceSlotPacked)
}
log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id)
}
_afterTokenTransfer(from, to, id);
}
function _safeTransfer(address from, address to, uint256 id) internal virtual {
_safeTransfer(from, to, id, "");
}
function _safeTransfer(address from, address to, uint256 id, bytes memory data)
internal
virtual
{
_transfer(address(0), from, to, id);
if (_hasCode(to)) _checkOnERC721Received(from, to, id, data);
}
function _safeTransfer(address by, address from, address to, uint256 id) internal virtual {
_safeTransfer(by, from, to, id, "");
}
function _safeTransfer(address by, address from, address to, uint256 id, bytes memory data)
internal
virtual
{
_transfer(by, from, to, id);
if (_hasCode(to)) _checkOnERC721Received(from, to, id, data);
}
function _beforeTokenTransfer(address from, address to, uint256 id) internal virtual {}
function _afterTokenTransfer(address from, address to, uint256 id) internal virtual {}
function _hasCode(address a) private view returns (bool result) {
assembly {
result := extcodesize(a)
}
}
function _checkOnERC721Received(address from, address to, uint256 id, bytes memory data)
private
{
assembly {
let m := mload(0x40)
let onERC721ReceivedSelector := 0x150b7a02
mstore(m, onERC721ReceivedSelector)
mstore(add(m, 0x20), caller())
mstore(add(m, 0x40), shr(96, shl(96, from)))
mstore(add(m, 0x60), id)
mstore(add(m, 0x80), 0x80)
let n := mload(data)
mstore(add(m, 0xa0), n)
if n { pop(staticcall(gas(), 4, add(data, 0x20), n, add(m, 0xc0), n)) }
if iszero(call(gas(), to, 0, add(m, 0x1c), add(n, 0xa4), m, 0x20)) {
if returndatasize() {
returndatacopy(m, 0x00, returndatasize())
revert(m, returndatasize())
}
}
if iszero(eq(mload(m), shl(224, onERC721ReceivedSelector))) {
mstore(0x00, 0xd1a57ed6)
revert(0x1c, 0x04)
}
}
}
}
文件 8 的 24:ERC721ConduitPreapproved_Solady.sol
pragma solidity ^0.8.17;
import {ERC721} from "solady/tokens/ERC721.sol";
import {
CONDUIT, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, SOLADY_ERC721_MASTER_SLOT_SEED_MASKED
} from "../../lib/Constants.sol";
import {IPreapprovalForAll} from "../../interfaces/IPreapprovalForAll.sol";
abstract contract ERC721ConduitPreapproved_Solady is ERC721, IPreapprovalForAll {
constructor() {
emit PreapprovalForAll(CONDUIT, true);
}
function transferFrom(address from, address to, uint256 id) public payable virtual override {
_transfer(_by(from), from, to, id);
}
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
bool approved = super.isApprovedForAll(owner, operator);
return (operator == CONDUIT) ? !approved : approved;
}
function setApprovalForAll(address operator, bool isApproved) public virtual override {
assembly {
isApproved := iszero(iszero(isApproved))
let isConduit := eq(operator, CONDUIT)
let storedValue :=
or(
and(isConduit, iszero(isApproved)),
and(iszero(isConduit), isApproved)
)
mstore(0x1c, operator)
mstore(0x08, SOLADY_ERC721_MASTER_SLOT_SEED_MASKED)
mstore(0x00, caller())
sstore(keccak256(0x0c, 0x30), storedValue)
mstore(0x00, isApproved)
log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, caller(), shr(96, shl(96, operator)))
}
}
function _by(address from) internal view virtual returns (address result) {
if (msg.sender == CONDUIT) {
if (isApprovedForAll(from, CONDUIT)) {
return address(0);
}
}
return msg.sender;
}
}
文件 9 的 24:EnumerableSet.sol
pragma solidity ^0.8.20;
library EnumerableSet {
struct Set {
bytes32[] _values;
mapping(bytes32 value => uint256) _positions;
}
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
set._positions[value] = set._values.length;
return true;
} else {
return false;
}
}
function _remove(Set storage set, bytes32 value) private returns (bool) {
uint256 position = set._positions[value];
if (position != 0) {
uint256 valueIndex = position - 1;
uint256 lastIndex = set._values.length - 1;
if (valueIndex != lastIndex) {
bytes32 lastValue = set._values[lastIndex];
set._values[valueIndex] = lastValue;
set._positions[lastValue] = position;
}
set._values.pop();
delete set._positions[value];
return true;
} else {
return false;
}
}
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._positions[value] != 0;
}
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
struct Bytes32Set {
Set _inner;
}
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
assembly {
result := store
}
return result;
}
struct AddressSet {
Set _inner;
}
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
assembly {
result := store
}
return result;
}
struct UintSet {
Set _inner;
}
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
assembly {
result := store
}
return result;
}
}
文件 10 的 24:IERC5192.sol
pragma solidity ^0.8.17;
interface IERC5192 {
event Locked(uint256 tokenId);
event Unlocked(uint256 tokenId);
function locked(uint256 tokenId) external view returns (bool);
}
文件 11 的 24:IERC7496.sol
pragma solidity ^0.8.19;
interface IERC7496 {
event TraitUpdated(bytes32 indexed traitKey, uint256 tokenId, bytes32 traitValue);
event TraitUpdatedRange(bytes32 indexed traitKey, uint256 fromTokenId, uint256 toTokenId);
event TraitUpdatedRangeUniformValue(
bytes32 indexed traitKey, uint256 fromTokenId, uint256 toTokenId, bytes32 traitValue
);
event TraitUpdatedList(bytes32 indexed traitKey, uint256[] tokenIds);
event TraitUpdatedListUniformValue(bytes32 indexed traitKey, uint256[] tokenIds, bytes32 traitValue);
event TraitMetadataURIUpdated();
function getTraitValue(uint256 tokenId, bytes32 traitKey) external view returns (bytes32 traitValue);
function getTraitValues(uint256 tokenId, bytes32[] calldata traitKeys)
external
view
returns (bytes32[] memory traitValues);
function getTraitMetadataURI() external view returns (string memory uri);
function setTrait(uint256 tokenId, bytes32 traitKey, bytes32 traitValue) external;
error TraitValueUnchanged();
}
文件 12 的 24:IPreapprovalForAll.sol
pragma solidity ^0.8.17;
interface IPreapprovalForAll {
event PreapprovalForAll(address indexed operator, bool indexed approved);
}
文件 13 的 24:LibString.sol
pragma solidity ^0.8.4;
library LibString {
error HexLengthInsufficient();
error TooBigForSmallString();
error StringNot7BitASCII();
uint256 internal constant NOT_FOUND = type(uint256).max;
uint128 internal constant ALPHANUMERIC_7_BIT_ASCII = 0x7fffffe07fffffe03ff000000000000;
uint128 internal constant LETTERS_7_BIT_ASCII = 0x7fffffe07fffffe0000000000000000;
uint128 internal constant LOWERCASE_7_BIT_ASCII = 0x7fffffe000000000000000000000000;
uint128 internal constant UPPERCASE_7_BIT_ASCII = 0x7fffffe0000000000000000;
uint128 internal constant DIGITS_7_BIT_ASCII = 0x3ff000000000000;
uint128 internal constant HEXDIGITS_7_BIT_ASCII = 0x7e0000007e03ff000000000000;
uint128 internal constant OCTDIGITS_7_BIT_ASCII = 0xff000000000000;
uint128 internal constant PRINTABLE_7_BIT_ASCII = 0x7fffffffffffffffffffffff00003e00;
uint128 internal constant PUNCTUATION_7_BIT_ASCII = 0x78000001f8000001fc00fffe00000000;
uint128 internal constant WHITESPACE_7_BIT_ASCII = 0x100003e00;
function toString(uint256 value) internal pure returns (string memory result) {
assembly {
result := add(mload(0x40), 0x80)
mstore(0x40, add(result, 0x20))
mstore(result, 0)
let end := result
let w := not(0)
for { let temp := value } 1 {} {
result := add(result, w)
mstore8(result, add(48, mod(temp, 10)))
temp := div(temp, 10)
if iszero(temp) { break }
}
let n := sub(end, result)
result := sub(result, 0x20)
mstore(result, n)
}
}
function toString(int256 value) internal pure returns (string memory result) {
if (value >= 0) return toString(uint256(value));
unchecked {
result = toString(~uint256(value) + 1);
}
assembly {
let n := mload(result)
mstore(result, 0x2d)
result := sub(result, 1)
mstore(result, add(n, 1))
}
}
function toHexString(uint256 value, uint256 length)
internal
pure
returns (string memory result)
{
result = toHexStringNoPrefix(value, length);
assembly {
let n := add(mload(result), 2)
mstore(result, 0x3078)
result := sub(result, 2)
mstore(result, n)
}
}
function toHexStringNoPrefix(uint256 value, uint256 length)
internal
pure
returns (string memory result)
{
assembly {
result := add(mload(0x40), and(add(shl(1, length), 0x42), not(0x1f)))
mstore(0x40, add(result, 0x20))
mstore(result, 0)
let end := result
mstore(0x0f, 0x30313233343536373839616263646566)
let start := sub(result, add(length, length))
let w := not(1)
let temp := value
for {} 1 {} {
result := add(result, w)
mstore8(add(result, 1), mload(and(temp, 15)))
mstore8(result, mload(and(shr(4, temp), 15)))
temp := shr(8, temp)
if iszero(xor(result, start)) { break }
}
if temp {
mstore(0x00, 0x2194895a)
revert(0x1c, 0x04)
}
let n := sub(end, result)
result := sub(result, 0x20)
mstore(result, n)
}
}
function toHexString(uint256 value) internal pure returns (string memory result) {
result = toHexStringNoPrefix(value);
assembly {
let n := add(mload(result), 2)
mstore(result, 0x3078)
result := sub(result, 2)
mstore(result, n)
}
}
function toMinimalHexString(uint256 value) internal pure returns (string memory result) {
result = toHexStringNoPrefix(value);
assembly {
let o := eq(byte(0, mload(add(result, 0x20))), 0x30)
let n := add(mload(result), 2)
mstore(add(result, o), 0x3078)
result := sub(add(result, o), 2)
mstore(result, sub(n, o))
}
}
function toMinimalHexStringNoPrefix(uint256 value)
internal
pure
returns (string memory result)
{
result = toHexStringNoPrefix(value);
assembly {
let o := eq(byte(0, mload(add(result, 0x20))), 0x30)
let n := mload(result)
result := add(result, o)
mstore(result, sub(n, o))
}
}
function toHexStringNoPrefix(uint256 value) internal pure returns (string memory result) {
assembly {
result := add(mload(0x40), 0x80)
mstore(0x40, add(result, 0x20))
mstore(result, 0)
let end := result
mstore(0x0f, 0x30313233343536373839616263646566)
let w := not(1)
for { let temp := value } 1 {} {
result := add(result, w)
mstore8(add(result, 1), mload(and(temp, 15)))
mstore8(result, mload(and(shr(4, temp), 15)))
temp := shr(8, temp)
if iszero(temp) { break }
}
let n := sub(end, result)
result := sub(result, 0x20)
mstore(result, n)
}
}
function toHexStringChecksummed(address value) internal pure returns (string memory result) {
result = toHexString(value);
assembly {
let mask := shl(6, div(not(0), 255))
let o := add(result, 0x22)
let hashed := and(keccak256(o, 40), mul(34, mask))
let t := shl(240, 136)
for { let i := 0 } 1 {} {
mstore(add(i, i), mul(t, byte(i, hashed)))
i := add(i, 1)
if eq(i, 20) { break }
}
mstore(o, xor(mload(o), shr(1, and(mload(0x00), and(mload(o), mask)))))
o := add(o, 0x20)
mstore(o, xor(mload(o), shr(1, and(mload(0x20), and(mload(o), mask)))))
}
}
function toHexString(address value) internal pure returns (string memory result) {
result = toHexStringNoPrefix(value);
assembly {
let n := add(mload(result), 2)
mstore(result, 0x3078)
result := sub(result, 2)
mstore(result, n)
}
}
function toHexStringNoPrefix(address value) internal pure returns (string memory result) {
assembly {
result := mload(0x40)
mstore(0x40, add(result, 0x80))
mstore(0x0f, 0x30313233343536373839616263646566)
result := add(result, 2)
mstore(result, 40)
let o := add(result, 0x20)
mstore(add(o, 40), 0)
value := shl(96, value)
for { let i := 0 } 1 {} {
let p := add(o, add(i, i))
let temp := byte(i, value)
mstore8(add(p, 1), mload(and(temp, 15)))
mstore8(p, mload(shr(4, temp)))
i := add(i, 1)
if eq(i, 20) { break }
}
}
}
function toHexString(bytes memory raw) internal pure returns (string memory result) {
result = toHexStringNoPrefix(raw);
assembly {
let n := add(mload(result), 2)
mstore(result, 0x3078)
result := sub(result, 2)
mstore(result, n)
}
}
function toHexStringNoPrefix(bytes memory raw) internal pure returns (string memory result) {
assembly {
let n := mload(raw)
result := add(mload(0x40), 2)
mstore(result, add(n, n))
mstore(0x0f, 0x30313233343536373839616263646566)
let o := add(result, 0x20)
let end := add(raw, n)
for {} iszero(eq(raw, end)) {} {
raw := add(raw, 1)
mstore8(add(o, 1), mload(and(mload(raw), 15)))
mstore8(o, mload(and(shr(4, mload(raw)), 15)))
o := add(o, 2)
}
mstore(o, 0)
mstore(0x40, add(o, 0x20))
}
}
function runeCount(string memory s) internal pure returns (uint256 result) {
assembly {
if mload(s) {
mstore(0x00, div(not(0), 255))
mstore(0x20, 0x0202020202020202020202020202020202020202020202020303030304040506)
let o := add(s, 0x20)
let end := add(o, mload(s))
for { result := 1 } 1 { result := add(result, 1) } {
o := add(o, byte(0, mload(shr(250, mload(o)))))
if iszero(lt(o, end)) { break }
}
}
}
}
function is7BitASCII(string memory s) internal pure returns (bool result) {
assembly {
result := 1
let mask := shl(7, div(not(0), 255))
let n := mload(s)
if n {
let o := add(s, 0x20)
let end := add(o, n)
let last := mload(end)
mstore(end, 0)
for {} 1 {} {
if and(mask, mload(o)) {
result := 0
break
}
o := add(o, 0x20)
if iszero(lt(o, end)) { break }
}
mstore(end, last)
}
}
}
function is7BitASCII(string memory s, uint128 allowed) internal pure returns (bool result) {
assembly {
result := 1
if mload(s) {
let allowed_ := shr(128, shl(128, allowed))
let o := add(s, 0x20)
for { let end := add(o, mload(s)) } 1 {} {
result := and(result, shr(byte(0, mload(o)), allowed_))
o := add(o, 1)
if iszero(and(result, lt(o, end))) { break }
}
}
}
}
function to7BitASCIIAllowedLookup(string memory s) internal pure returns (uint128 result) {
assembly {
if mload(s) {
let o := add(s, 0x20)
for { let end := add(o, mload(s)) } 1 {} {
result := or(result, shl(byte(0, mload(o)), 1))
o := add(o, 1)
if iszero(lt(o, end)) { break }
}
if shr(128, result) {
mstore(0x00, 0xc9807e0d)
revert(0x1c, 0x04)
}
}
}
}
function replace(string memory subject, string memory needle, string memory replacement)
internal
pure
returns (string memory result)
{
assembly {
result := mload(0x40)
let needleLen := mload(needle)
let replacementLen := mload(replacement)
let d := sub(result, subject)
let i := add(subject, 0x20)
let end := add(i, mload(subject))
if iszero(gt(needleLen, mload(subject))) {
let subjectSearchEnd := add(sub(end, needleLen), 1)
let h := 0
if iszero(lt(needleLen, 0x20)) { h := keccak256(add(needle, 0x20), needleLen) }
let s := mload(add(needle, 0x20))
for { let m := shl(3, sub(0x20, and(needleLen, 0x1f))) } 1 {} {
let t := mload(i)
if iszero(shr(m, xor(t, s))) {
if h {
if iszero(eq(keccak256(i, needleLen), h)) {
mstore(add(i, d), t)
i := add(i, 1)
if iszero(lt(i, subjectSearchEnd)) { break }
continue
}
}
for { let j := 0 } 1 {} {
mstore(add(add(i, d), j), mload(add(add(replacement, 0x20), j)))
j := add(j, 0x20)
if iszero(lt(j, replacementLen)) { break }
}
d := sub(add(d, replacementLen), needleLen)
if needleLen {
i := add(i, needleLen)
if iszero(lt(i, subjectSearchEnd)) { break }
continue
}
}
mstore(add(i, d), t)
i := add(i, 1)
if iszero(lt(i, subjectSearchEnd)) { break }
}
}
let n := add(sub(d, add(result, 0x20)), end)
for {} lt(i, end) { i := add(i, 0x20) } { mstore(add(i, d), mload(i)) }
let o := add(i, d)
mstore(o, 0)
mstore(0x40, add(o, 0x20))
mstore(result, n)
}
}
function indexOf(string memory subject, string memory needle, uint256 from)
internal
pure
returns (uint256 result)
{
assembly {
result := not(0)
for { let subjectLen := mload(subject) } 1 {} {
if iszero(mload(needle)) {
result := from
if iszero(gt(from, subjectLen)) { break }
result := subjectLen
break
}
let needleLen := mload(needle)
let subjectStart := add(subject, 0x20)
subject := add(subjectStart, from)
let end := add(sub(add(subjectStart, subjectLen), needleLen), 1)
let m := shl(3, sub(0x20, and(needleLen, 0x1f)))
let s := mload(add(needle, 0x20))
if iszero(and(lt(subject, end), lt(from, subjectLen))) { break }
if iszero(lt(needleLen, 0x20)) {
for { let h := keccak256(add(needle, 0x20), needleLen) } 1 {} {
if iszero(shr(m, xor(mload(subject), s))) {
if eq(keccak256(subject, needleLen), h) {
result := sub(subject, subjectStart)
break
}
}
subject := add(subject, 1)
if iszero(lt(subject, end)) { break }
}
break
}
for {} 1 {} {
if iszero(shr(m, xor(mload(subject), s))) {
result := sub(subject, subjectStart)
break
}
subject := add(subject, 1)
if iszero(lt(subject, end)) { break }
}
break
}
}
}
function indexOf(string memory subject, string memory needle)
internal
pure
returns (uint256 result)
{
result = indexOf(subject, needle, 0);
}
function lastIndexOf(string memory subject, string memory needle, uint256 from)
internal
pure
returns (uint256 result)
{
assembly {
for {} 1 {} {
result := not(0)
let needleLen := mload(needle)
if gt(needleLen, mload(subject)) { break }
let w := result
let fromMax := sub(mload(subject), needleLen)
if iszero(gt(fromMax, from)) { from := fromMax }
let end := add(add(subject, 0x20), w)
subject := add(add(subject, 0x20), from)
if iszero(gt(subject, end)) { break }
for { let h := keccak256(add(needle, 0x20), needleLen) } 1 {} {
if eq(keccak256(subject, needleLen), h) {
result := sub(subject, add(end, 1))
break
}
subject := add(subject, w)
if iszero(gt(subject, end)) { break }
}
break
}
}
}
function lastIndexOf(string memory subject, string memory needle)
internal
pure
returns (uint256 result)
{
result = lastIndexOf(subject, needle, type(uint256).max);
}
function contains(string memory subject, string memory needle) internal pure returns (bool) {
return indexOf(subject, needle) != NOT_FOUND;
}
function startsWith(string memory subject, string memory needle)
internal
pure
returns (bool result)
{
assembly {
let needleLen := mload(needle)
result := and(
iszero(gt(needleLen, mload(subject))),
eq(
keccak256(add(subject, 0x20), needleLen),
keccak256(add(needle, 0x20), needleLen)
)
)
}
}
function endsWith(string memory subject, string memory needle)
internal
pure
returns (bool result)
{
assembly {
let needleLen := mload(needle)
let inRange := iszero(gt(needleLen, mload(subject)))
result := and(
eq(
keccak256(
add(add(subject, 0x20), mul(inRange, sub(mload(subject), needleLen))),
needleLen
),
keccak256(add(needle, 0x20), needleLen)
),
inRange
)
}
}
function repeat(string memory subject, uint256 times)
internal
pure
returns (string memory result)
{
assembly {
let subjectLen := mload(subject)
if iszero(or(iszero(times), iszero(subjectLen))) {
result := mload(0x40)
subject := add(subject, 0x20)
let o := add(result, 0x20)
for {} 1 {} {
for { let j := 0 } 1 {} {
mstore(add(o, j), mload(add(subject, j)))
j := add(j, 0x20)
if iszero(lt(j, subjectLen)) { break }
}
o := add(o, subjectLen)
times := sub(times, 1)
if iszero(times) { break }
}
mstore(o, 0)
mstore(0x40, add(o, 0x20))
mstore(result, sub(o, add(result, 0x20)))
}
}
}
function slice(string memory subject, uint256 start, uint256 end)
internal
pure
returns (string memory result)
{
assembly {
let subjectLen := mload(subject)
if iszero(gt(subjectLen, end)) { end := subjectLen }
if iszero(gt(subjectLen, start)) { start := subjectLen }
if lt(start, end) {
result := mload(0x40)
let n := sub(end, start)
let i := add(subject, start)
let w := not(0x1f)
for { let j := and(add(n, 0x1f), w) } 1 {} {
mstore(add(result, j), mload(add(i, j)))
j := add(j, w)
if iszero(j) { break }
}
let o := add(add(result, 0x20), n)
mstore(o, 0)
mstore(0x40, add(o, 0x20))
mstore(result, n)
}
}
}
function slice(string memory subject, uint256 start)
internal
pure
returns (string memory result)
{
result = slice(subject, start, type(uint256).max);
}
function indicesOf(string memory subject, string memory needle)
internal
pure
returns (uint256[] memory result)
{
assembly {
let searchLen := mload(needle)
if iszero(gt(searchLen, mload(subject))) {
result := mload(0x40)
let i := add(subject, 0x20)
let o := add(result, 0x20)
let subjectSearchEnd := add(sub(add(i, mload(subject)), searchLen), 1)
let h := 0
if iszero(lt(searchLen, 0x20)) { h := keccak256(add(needle, 0x20), searchLen) }
let s := mload(add(needle, 0x20))
for { let m := shl(3, sub(0x20, and(searchLen, 0x1f))) } 1 {} {
let t := mload(i)
if iszero(shr(m, xor(t, s))) {
if h {
if iszero(eq(keccak256(i, searchLen), h)) {
i := add(i, 1)
if iszero(lt(i, subjectSearchEnd)) { break }
continue
}
}
mstore(o, sub(i, add(subject, 0x20)))
o := add(o, 0x20)
i := add(i, searchLen)
if searchLen {
if iszero(lt(i, subjectSearchEnd)) { break }
continue
}
}
i := add(i, 1)
if iszero(lt(i, subjectSearchEnd)) { break }
}
mstore(result, shr(5, sub(o, add(result, 0x20))))
mstore(0x40, add(o, 0x20))
}
}
}
function split(string memory subject, string memory delimiter)
internal
pure
returns (string[] memory result)
{
uint256[] memory indices = indicesOf(subject, delimiter);
assembly {
let w := not(0x1f)
let indexPtr := add(indices, 0x20)
let indicesEnd := add(indexPtr, shl(5, add(mload(indices), 1)))
mstore(add(indicesEnd, w), mload(subject))
mstore(indices, add(mload(indices), 1))
for { let prevIndex := 0 } 1 {} {
let index := mload(indexPtr)
mstore(indexPtr, 0x60)
if iszero(eq(index, prevIndex)) {
let element := mload(0x40)
let l := sub(index, prevIndex)
mstore(element, l)
for { let o := and(add(l, 0x1f), w) } 1 {} {
mstore(add(element, o), mload(add(add(subject, prevIndex), o)))
o := add(o, w)
if iszero(o) { break }
}
mstore(add(add(element, 0x20), l), 0)
mstore(0x40, add(element, and(add(l, 0x3f), w)))
mstore(indexPtr, element)
}
prevIndex := add(index, mload(delimiter))
indexPtr := add(indexPtr, 0x20)
if iszero(lt(indexPtr, indicesEnd)) { break }
}
result := indices
if iszero(mload(delimiter)) {
result := add(indices, 0x20)
mstore(result, sub(mload(indices), 2))
}
}
}
function concat(string memory a, string memory b)
internal
pure
returns (string memory result)
{
assembly {
result := mload(0x40)
let w := not(0x1f)
let aLen := mload(a)
for { let o := and(add(aLen, 0x20), w) } 1 {} {
mstore(add(result, o), mload(add(a, o)))
o := add(o, w)
if iszero(o) { break }
}
let bLen := mload(b)
let output := add(result, aLen)
for { let o := and(add(bLen, 0x20), w) } 1 {} {
mstore(add(output, o), mload(add(b, o)))
o := add(o, w)
if iszero(o) { break }
}
let totalLen := add(aLen, bLen)
let last := add(add(result, 0x20), totalLen)
mstore(last, 0)
mstore(result, totalLen)
mstore(0x40, add(last, 0x20))
}
}
function toCase(string memory subject, bool toUpper)
internal
pure
returns (string memory result)
{
assembly {
let n := mload(subject)
if n {
result := mload(0x40)
let o := add(result, 0x20)
let d := sub(subject, result)
let flags := shl(add(70, shl(5, toUpper)), 0x3ffffff)
for { let end := add(o, n) } 1 {} {
let b := byte(0, mload(add(d, o)))
mstore8(o, xor(and(shr(b, flags), 0x20), b))
o := add(o, 1)
if eq(o, end) { break }
}
mstore(result, n)
mstore(o, 0)
mstore(0x40, add(o, 0x20))
}
}
}
function fromSmallString(bytes32 s) internal pure returns (string memory result) {
assembly {
result := mload(0x40)
let n := 0
for {} byte(n, s) { n := add(n, 1) } {}
mstore(result, n)
let o := add(result, 0x20)
mstore(o, s)
mstore(add(o, n), 0)
mstore(0x40, add(result, 0x40))
}
}
function normalizeSmallString(bytes32 s) internal pure returns (bytes32 result) {
assembly {
for {} byte(result, s) { result := add(result, 1) } {}
mstore(0x00, s)
mstore(result, 0x00)
result := mload(0x00)
}
}
function toSmallString(string memory s) internal pure returns (bytes32 result) {
assembly {
result := mload(s)
if iszero(lt(result, 33)) {
mstore(0x00, 0xec92f9a3)
revert(0x1c, 0x04)
}
result := shl(shl(3, sub(32, result)), mload(add(s, result)))
}
}
function lower(string memory subject) internal pure returns (string memory result) {
result = toCase(subject, false);
}
function upper(string memory subject) internal pure returns (string memory result) {
result = toCase(subject, true);
}
function escapeHTML(string memory s) internal pure returns (string memory result) {
assembly {
result := mload(0x40)
let end := add(s, mload(s))
let o := add(result, 0x20)
mstore(0x1f, 0x900094)
mstore(0x08, 0xc0000000a6ab)
mstore(0x00, shl(64, 0x2671756f743b26616d703b262333393b266c743b2667743b))
for {} iszero(eq(s, end)) {} {
s := add(s, 1)
let c := and(mload(s), 0xff)
if iszero(and(shl(c, 1), 0x500000c400000000)) {
mstore8(o, c)
o := add(o, 1)
continue
}
let t := shr(248, mload(c))
mstore(o, mload(and(t, 0x1f)))
o := add(o, shr(5, t))
}
mstore(o, 0)
mstore(result, sub(o, add(result, 0x20)))
mstore(0x40, add(o, 0x20))
}
}
function escapeJSON(string memory s, bool addDoubleQuotes)
internal
pure
returns (string memory result)
{
assembly {
result := mload(0x40)
let o := add(result, 0x20)
if addDoubleQuotes {
mstore8(o, 34)
o := add(1, o)
}
mstore(0x15, 0x5c75303030303031323334353637383961626364656662746e006672)
let e := or(shl(0x22, 1), shl(0x5c, 1))
for { let end := add(s, mload(s)) } iszero(eq(s, end)) {} {
s := add(s, 1)
let c := and(mload(s), 0xff)
if iszero(lt(c, 0x20)) {
if iszero(and(shl(c, 1), e)) {
mstore8(o, c)
o := add(o, 1)
continue
}
mstore8(o, 0x5c)
mstore8(add(o, 1), c)
o := add(o, 2)
continue
}
if iszero(and(shl(c, 1), 0x3700)) {
mstore8(0x1d, mload(shr(4, c)))
mstore8(0x1e, mload(and(c, 15)))
mstore(o, mload(0x19))
o := add(o, 6)
continue
}
mstore8(o, 0x5c)
mstore8(add(o, 1), mload(add(c, 8)))
o := add(o, 2)
}
if addDoubleQuotes {
mstore8(o, 34)
o := add(1, o)
}
mstore(o, 0)
mstore(result, sub(o, add(result, 0x20)))
mstore(0x40, add(o, 0x20))
}
}
function escapeJSON(string memory s) internal pure returns (string memory result) {
result = escapeJSON(s, false);
}
function encodeURIComponent(string memory s) internal pure returns (string memory result) {
assembly {
result := mload(0x40)
mstore(0x0f, 0x30313233343536373839414243444546)
let o := add(result, 0x20)
for { let end := add(s, mload(s)) } iszero(eq(s, end)) {} {
s := add(s, 1)
let c := and(mload(s), 0xff)
if iszero(and(1, shr(c, 0x47fffffe87fffffe03ff678200000000))) {
mstore8(o, 0x25)
mstore8(add(o, 1), mload(and(shr(4, c), 15)))
mstore8(add(o, 2), mload(and(c, 15)))
o := add(o, 3)
continue
}
mstore8(o, c)
o := add(o, 1)
}
mstore(result, sub(o, add(result, 0x20)))
mstore(o, 0)
mstore(0x40, add(o, 0x20))
}
}
function eq(string memory a, string memory b) internal pure returns (bool result) {
assembly {
result := eq(keccak256(add(a, 0x20), mload(a)), keccak256(add(b, 0x20), mload(b)))
}
}
function eqs(string memory a, bytes32 b) internal pure returns (bool result) {
assembly {
let m := not(shl(7, div(not(iszero(b)), 255)))
let x := not(or(m, or(b, add(m, and(b, m)))))
let r := shl(7, iszero(iszero(shr(128, x))))
r := or(r, shl(6, iszero(iszero(shr(64, shr(r, x))))))
r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
r := or(r, shl(4, lt(0xffff, shr(r, x))))
r := or(r, shl(3, lt(0xff, shr(r, x))))
result := gt(eq(mload(a), add(iszero(x), xor(31, shr(3, r)))),
xor(shr(add(8, r), b), shr(add(8, r), mload(add(a, 0x20)))))
}
}
function packOne(string memory a) internal pure returns (bytes32 result) {
assembly {
result :=
mul(
mload(add(a, 0x1f)),
lt(sub(mload(a), 1), 0x1f)
)
}
}
function unpackOne(bytes32 packed) internal pure returns (string memory result) {
assembly {
result := mload(0x40)
mstore(0x40, add(result, 0x40))
mstore(result, 0)
mstore(add(result, 0x1f), packed)
mstore(add(add(result, 0x20), mload(result)), 0)
}
}
function packTwo(string memory a, string memory b) internal pure returns (bytes32 result) {
assembly {
let aLen := mload(a)
result :=
mul(
or(
shl(shl(3, sub(0x1f, aLen)), mload(add(a, aLen))), mload(sub(add(b, 0x1e), aLen))),
lt(sub(add(aLen, mload(b)), 1), 0x1e)
)
}
}
function unpackTwo(bytes32 packed)
internal
pure
returns (string memory resultA, string memory resultB)
{
assembly {
resultA := mload(0x40)
resultB := add(resultA, 0x40)
mstore(0x40, add(resultB, 0x40))
mstore(resultA, 0)
mstore(resultB, 0)
mstore(add(resultA, 0x1f), packed)
mstore(add(resultB, 0x1f), mload(add(add(resultA, 0x20), mload(resultA))))
mstore(add(add(resultA, 0x20), mload(resultA)), 0)
mstore(add(add(resultB, 0x20), mload(resultB)), 0)
}
}
function directReturn(string memory a) internal pure {
assembly {
let retStart := sub(a, 0x20)
let retUnpaddedSize := add(mload(a), 0x40)
mstore(add(retStart, retUnpaddedSize), 0)
mstore(retStart, 0x20)
return(retStart, and(not(0x1f), add(0x1f, retUnpaddedSize)))
}
}
}
文件 14 的 24:Metadata.sol
pragma solidity ^0.8.17;
import {json} from "./json.sol";
import {LibString} from "solady/utils/LibString.sol";
import {Solarray} from "solarray/Solarray.sol";
import {Base64} from "solady/utils/Base64.sol";
enum DisplayType {
String,
Number,
Date,
BoostPercent,
BoostNumber,
Hidden
}
library Metadata {
string private constant NULL = "";
using LibString for string;
function attribute(string memory traitType, string memory value) internal pure returns (string memory) {
return json.objectOf(Solarray.strings(json.property("trait_type", traitType), json.property("value", value)));
}
function attribute(string memory traitType, string memory value, DisplayType displayType)
internal
pure
returns (string memory)
{
return json.objectOf(
Solarray.strings(
json.property("trait_type", traitType),
json.property("value", value),
json.property("display_type", toString(displayType))
)
);
}
function toString(DisplayType displayType) internal pure returns (string memory) {
if (displayType == DisplayType.String) {
return "string";
} else if (displayType == DisplayType.Number) {
return "number";
} else if (displayType == DisplayType.Date) {
return "date";
} else if (displayType == DisplayType.BoostNumber) {
return "boost_number";
} else if (displayType == DisplayType.BoostPercent) {
return "boost_percent";
} else {
return "hidden";
}
}
function dataURI(string memory dataType, string memory encoding, string memory content)
internal
pure
returns (string memory)
{
return string.concat(
"data:", dataType, ";", bytes(encoding).length > 0 ? string.concat(encoding, ",") : NULL, content
);
}
function dataURI(string memory dataType, string memory content) internal pure returns (string memory) {
return dataURI(dataType, NULL, content);
}
function jsonDataURI(string memory content, string memory encoding) internal pure returns (string memory) {
return dataURI("application/json", encoding, content);
}
function jsonDataURI(string memory content) internal pure returns (string memory) {
return jsonDataURI(content, NULL);
}
function base64JsonDataURI(string memory content) internal pure returns (string memory) {
return jsonDataURI(Base64.encode(bytes(content)), "base64");
}
function svgDataURI(string memory content, string memory encoding, bool escape)
internal
pure
returns (string memory)
{
string memory uri = dataURI("image/svg+xml", encoding, content);
if (escape) {
return uri.escapeJSON();
} else {
return uri;
}
}
function svgDataURI(string memory content) internal pure returns (string memory) {
return svgDataURI(content, "utf8", true);
}
function base64SvgDataURI(string memory content) internal pure returns (string memory) {
return svgDataURI(Base64.encode(bytes(content)), "base64", false);
}
}
文件 15 的 24:OnchainTraits.sol
pragma solidity ^0.8.17;
import {DynamicTraits} from "./DynamicTraits.sol";
import {Metadata} from "../onchain/Metadata.sol";
import {Ownable} from "solady/auth/Ownable.sol";
import {SSTORE2} from "solady/utils/SSTORE2.sol";
import {EnumerableSet} from "openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol";
import {
TraitLabelStorage,
TraitLabelStorageLib,
TraitLabel,
TraitLabelLib,
Editors,
StoredTraitLabel,
AllowedEditor,
EditorsLib,
StoredTraitLabelLib
} from "./lib/TraitLabelLib.sol";
library OnchainTraitsStorage {
struct Layout {
EnumerableSet.Bytes32Set _traitKeys;
mapping(bytes32 traitKey => TraitLabelStorage traitLabelStorage) _traitLabelStorage;
EnumerableSet.AddressSet _customEditors;
}
bytes32 internal constant STORAGE_SLOT = keccak256("contracts.storage.erc7496-dynamictraits.onchaintraits");
function layout() internal pure returns (Layout storage l) {
bytes32 slot = STORAGE_SLOT;
assembly {
l.slot := slot
}
}
}
abstract contract OnchainTraits is Ownable, DynamicTraits {
using OnchainTraitsStorage for OnchainTraitsStorage.Layout;
using EnumerableSet for EnumerableSet.Bytes32Set;
using EnumerableSet for EnumerableSet.AddressSet;
error InsufficientPrivilege();
error TraitDoesNotExist(bytes32 traitKey);
constructor() {
_initializeOwner(msg.sender);
}
function _isOwnerOrApproved(uint256 tokenId, address addr) internal view virtual returns (bool);
function isCustomEditor(address editor) external view returns (bool) {
return OnchainTraitsStorage.layout()._customEditors.contains(editor);
}
function updateCustomEditor(address editor, bool insert) external onlyOwner {
if (insert) {
OnchainTraitsStorage.layout()._customEditors.add(editor);
} else {
OnchainTraitsStorage.layout()._customEditors.remove(editor);
}
}
function getCustomEditors() external view returns (address[] memory) {
return OnchainTraitsStorage.layout()._customEditors.values();
}
function getCustomEditorsLength() external view returns (uint256) {
return OnchainTraitsStorage.layout()._customEditors.length();
}
function getCustomEditorAt(uint256 index) external view returns (address) {
return OnchainTraitsStorage.layout()._customEditors.at(index);
}
function getTraitMetadataURI() external view virtual override returns (string memory) {
return Metadata.jsonDataURI(_getTraitMetadataJson());
}
function _getTraitMetadataJson() internal view returns (string memory) {
bytes32[] memory keys = OnchainTraitsStorage.layout()._traitKeys.values();
return TraitLabelStorageLib.toLabelJson(OnchainTraitsStorage.layout()._traitLabelStorage, keys);
}
function traitLabelStorage(bytes32 traitKey) external view returns (TraitLabelStorage memory) {
return OnchainTraitsStorage.layout()._traitLabelStorage[traitKey];
}
function setTrait(uint256 tokenId, bytes32 traitKey, bytes32 newValue) public virtual override {
TraitLabelStorage memory labelStorage = OnchainTraitsStorage.layout()._traitLabelStorage[traitKey];
StoredTraitLabel storedTraitLabel = labelStorage.storedLabel;
if (!StoredTraitLabelLib.exists(storedTraitLabel)) {
revert TraitDoesNotExist(traitKey);
}
_verifySetterPrivilege(labelStorage.allowedEditors, tokenId);
if (labelStorage.valuesRequireValidation) {
TraitLabelLib.validateAcceptableValue(StoredTraitLabelLib.load(storedTraitLabel), traitKey, newValue);
}
DynamicTraits.setTrait(tokenId, traitKey, newValue);
}
function setTraitLabel(bytes32 traitKey, TraitLabel calldata _traitLabel) external virtual onlyOwner {
_setTraitLabel(traitKey, _traitLabel);
}
function _setTraitLabel(bytes32 traitKey, TraitLabel memory _traitLabel) internal virtual {
OnchainTraitsStorage.layout()._traitKeys.add(traitKey);
OnchainTraitsStorage.layout()._traitLabelStorage[traitKey] = TraitLabelStorage({
allowedEditors: _traitLabel.editors,
required: _traitLabel.required,
valuesRequireValidation: _traitLabel.acceptableValues.length > 0,
storedLabel: TraitLabelLib.store(_traitLabel)
});
}
function _verifySetterPrivilege(Editors editors, uint256 tokenId) internal view {
if (EditorsLib.contains(editors, AllowedEditor.Anyone)) {
return;
}
if (EditorsLib.contains(editors, AllowedEditor.TokenOwner)) {
if (_isOwnerOrApproved(tokenId, msg.sender)) {
return;
}
}
if (EditorsLib.contains(editors, AllowedEditor.Custom)) {
if (OnchainTraitsStorage.layout()._customEditors.contains(msg.sender)) {
return;
}
}
if (EditorsLib.contains(editors, AllowedEditor.ContractOwner)) {
if (owner() == msg.sender) {
return;
}
}
if (EditorsLib.contains(editors, AllowedEditor.Self)) {
if (address(this) == msg.sender) {
return;
}
}
revert InsufficientPrivilege();
}
function _dynamicAttributes(uint256 tokenId) internal view virtual returns (string[] memory) {
bytes32[] memory keys = OnchainTraitsStorage.layout()._traitKeys.values();
uint256 keysLength = keys.length;
string[] memory attributes = new string[](keysLength);
uint256 num;
for (uint256 i = 0; i < keysLength;) {
bytes32 key = keys[i];
bytes32 trait = getTraitValue(tokenId, key);
if (trait != bytes32(0)) {
attributes[num] =
TraitLabelStorageLib.toAttributeJson(OnchainTraitsStorage.layout()._traitLabelStorage, key, trait);
unchecked {
++num;
}
}
unchecked {
++i;
}
}
assembly {
mstore(attributes, num)
}
return attributes;
}
}
文件 16 的 24:Ownable.sol
pragma solidity ^0.8.4;
abstract contract Ownable {
error Unauthorized();
error NewOwnerIsZeroAddress();
error NoHandoverRequest();
error AlreadyInitialized();
event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);
event OwnershipHandoverRequested(address indexed pendingOwner);
event OwnershipHandoverCanceled(address indexed pendingOwner);
uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =
0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;
uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =
0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;
uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =
0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;
bytes32 internal constant _OWNER_SLOT =
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927;
uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;
function _guardInitializeOwner() internal pure virtual returns (bool guard) {}
function _initializeOwner(address newOwner) internal virtual {
if (_guardInitializeOwner()) {
assembly {
let ownerSlot := _OWNER_SLOT
if sload(ownerSlot) {
mstore(0x00, 0x0dc149f0)
revert(0x1c, 0x04)
}
newOwner := shr(96, shl(96, newOwner))
sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
}
} else {
assembly {
newOwner := shr(96, shl(96, newOwner))
sstore(_OWNER_SLOT, newOwner)
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
}
}
}
function _setOwner(address newOwner) internal virtual {
if (_guardInitializeOwner()) {
assembly {
let ownerSlot := _OWNER_SLOT
newOwner := shr(96, shl(96, newOwner))
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
}
} else {
assembly {
let ownerSlot := _OWNER_SLOT
newOwner := shr(96, shl(96, newOwner))
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
sstore(ownerSlot, newOwner)
}
}
}
function _checkOwner() internal view virtual {
assembly {
if iszero(eq(caller(), sload(_OWNER_SLOT))) {
mstore(0x00, 0x82b42900)
revert(0x1c, 0x04)
}
}
}
function _ownershipHandoverValidFor() internal view virtual returns (uint64) {
return 48 * 3600;
}
function transferOwnership(address newOwner) public payable virtual onlyOwner {
assembly {
if iszero(shl(96, newOwner)) {
mstore(0x00, 0x7448fbae)
revert(0x1c, 0x04)
}
}
_setOwner(newOwner);
}
function renounceOwnership() public payable virtual onlyOwner {
_setOwner(address(0));
}
function requestOwnershipHandover() public payable virtual {
unchecked {
uint256 expires = block.timestamp + _ownershipHandoverValidFor();
assembly {
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, caller())
sstore(keccak256(0x0c, 0x20), expires)
log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())
}
}
}
function cancelOwnershipHandover() public payable virtual {
assembly {
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, caller())
sstore(keccak256(0x0c, 0x20), 0)
log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())
}
}
function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {
assembly {
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, pendingOwner)
let handoverSlot := keccak256(0x0c, 0x20)
if gt(timestamp(), sload(handoverSlot)) {
mstore(0x00, 0x6f5e8818)
revert(0x1c, 0x04)
}
sstore(handoverSlot, 0)
}
_setOwner(pendingOwner);
}
function owner() public view virtual returns (address result) {
assembly {
result := sload(_OWNER_SLOT)
}
}
function ownershipHandoverExpiresAt(address pendingOwner)
public
view
virtual
returns (uint256 result)
{
assembly {
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, pendingOwner)
result := sload(keccak256(0x0c, 0x20))
}
}
modifier onlyOwner() virtual {
_checkOwner();
_;
}
}
文件 17 的 24:ReentrancyGuard.sol
pragma solidity ^0.8.4;
abstract contract ReentrancyGuard {
error Reentrancy();
uint256 private constant _REENTRANCY_GUARD_SLOT = 0x929eee149b4bd21268;
modifier nonReentrant() virtual {
assembly {
if eq(sload(_REENTRANCY_GUARD_SLOT), address()) {
mstore(0x00, 0xab143c06)
revert(0x1c, 0x04)
}
sstore(_REENTRANCY_GUARD_SLOT, address())
}
_;
assembly {
sstore(_REENTRANCY_GUARD_SLOT, codesize())
}
}
modifier nonReadReentrant() virtual {
assembly {
if eq(sload(_REENTRANCY_GUARD_SLOT), address()) {
mstore(0x00, 0xab143c06)
revert(0x1c, 0x04)
}
}
_;
}
}
文件 18 的 24:SSTORE2.sol
pragma solidity ^0.8.4;
library SSTORE2 {
uint256 private constant _CREATE3_PROXY_INITCODE = 0x67363d3d37363d34f03d5260086018f3;
bytes32 internal constant CREATE3_PROXY_INITCODE_HASH =
0x21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f;
error DeploymentFailed();
function write(bytes memory data) internal returns (address pointer) {
assembly {
let n := mload(data)
mstore(add(data, gt(n, 0xfffe)), add(0xfe61000180600a3d393df300, shl(0x40, n)))
pointer := create(0, add(data, 0x15), add(n, 0xb))
if iszero(pointer) {
mstore(0x00, 0x30116425)
revert(0x1c, 0x04)
}
mstore(data, n)
}
}
function writeCounterfactual(bytes memory data, bytes32 salt)
internal
returns (address pointer)
{
assembly {
let n := mload(data)
mstore(add(data, gt(n, 0xfffe)), add(0xfe61000180600a3d393df300, shl(0x40, n)))
pointer := create2(0, add(data, 0x15), add(n, 0xb), salt)
if iszero(pointer) {
mstore(0x00, 0x30116425)
revert(0x1c, 0x04)
}
mstore(data, n)
}
}
function writeDeterministic(bytes memory data, bytes32 salt)
internal
returns (address pointer)
{
assembly {
let n := mload(data)
mstore(0x00, _CREATE3_PROXY_INITCODE)
let proxy := create2(0, 0x10, 0x10, salt)
if iszero(proxy) {
mstore(0x00, 0x30116425)
revert(0x1c, 0x04)
}
mstore(0x14, proxy)
mstore(0x00, 0xd694)
mstore8(0x34, 0x01)
pointer := keccak256(0x1e, 0x17)
mstore(add(data, gt(n, 0xfffe)), add(0xfe61000180600a3d393df300, shl(0x40, n)))
if iszero(
mul(
extcodesize(pointer),
call(gas(), proxy, 0, add(data, 0x15), add(n, 0xb), codesize(), 0x00)
)
) {
mstore(0x00, 0x30116425)
revert(0x1c, 0x04)
}
mstore(data, n)
}
}
function initCodeHash(bytes memory data) internal pure returns (bytes32 hash) {
assembly {
let n := mload(data)
returndatacopy(returndatasize(), returndatasize(), gt(n, 0xfffe))
mstore(data, add(0x61000180600a3d393df300, shl(0x40, n)))
hash := keccak256(add(data, 0x15), add(n, 0xb))
mstore(data, n)
}
}
function predictCounterfactualAddress(bytes memory data, bytes32 salt)
internal
view
returns (address pointer)
{
pointer = predictCounterfactualAddress(data, salt, address(this));
}
function predictCounterfactualAddress(bytes memory data, bytes32 salt, address deployer)
internal
pure
returns (address predicted)
{
bytes32 hash = initCodeHash(data);
assembly {
mstore8(0x00, 0xff)
mstore(0x35, hash)
mstore(0x01, shl(96, deployer))
mstore(0x15, salt)
predicted := keccak256(0x00, 0x55)
mstore(0x35, 0)
}
}
function predictDeterministicAddress(bytes32 salt) internal view returns (address pointer) {
pointer = predictDeterministicAddress(salt, address(this));
}
function predictDeterministicAddress(bytes32 salt, address deployer)
internal
pure
returns (address pointer)
{
assembly {
let m := mload(0x40)
mstore(0x00, deployer)
mstore8(0x0b, 0xff)
mstore(0x20, salt)
mstore(0x40, CREATE3_PROXY_INITCODE_HASH)
mstore(0x14, keccak256(0x0b, 0x55))
mstore(0x40, m)
mstore(0x00, 0xd694)
mstore8(0x34, 0x01)
pointer := keccak256(0x1e, 0x17)
}
}
function read(address pointer) internal view returns (bytes memory data) {
assembly {
data := mload(0x40)
let n := and(sub(extcodesize(pointer), 0x01), 0xffffffffff)
extcodecopy(pointer, add(data, 0x1f), 0x00, add(n, 0x21))
mstore(data, n)
mstore(0x40, add(n, add(data, 0x40)))
}
}
function read(address pointer, uint256 start) internal view returns (bytes memory data) {
assembly {
data := mload(0x40)
let n := and(sub(extcodesize(pointer), 0x01), 0xffffffffff)
extcodecopy(pointer, add(data, 0x1f), start, add(n, 0x21))
mstore(data, mul(sub(n, start), lt(start, n)))
mstore(0x40, add(data, add(0x40, mload(data))))
}
}
function read(address pointer, uint256 start, uint256 end)
internal
view
returns (bytes memory data)
{
assembly {
data := mload(0x40)
if iszero(lt(end, 0xffff)) { end := 0xffff }
let d := mul(sub(end, start), lt(start, end))
extcodecopy(pointer, add(data, 0x1f), start, add(d, 0x01))
if iszero(and(0xff, mload(add(data, d)))) {
let n := sub(extcodesize(pointer), 0x01)
returndatacopy(returndatasize(), returndatasize(), shr(64, n))
d := mul(gt(n, start), sub(d, mul(gt(end, n), sub(end, n))))
}
mstore(data, d)
mstore(add(add(data, 0x20), d), 0)
mstore(0x40, add(add(data, 0x40), d))
}
}
}
文件 19 的 24:SafeTransferLib.sol
pragma solidity ^0.8.4;
library SafeTransferLib {
error ETHTransferFailed();
error TransferFromFailed();
error TransferFailed();
error ApproveFailed();
error Permit2Failed();
error Permit2AmountOverflow();
uint256 internal constant GAS_STIPEND_NO_STORAGE_WRITES = 2300;
uint256 internal constant GAS_STIPEND_NO_GRIEF = 100000;
bytes32 internal constant DAI_DOMAIN_SEPARATOR =
0xdbb8cf42e1ecb028be3f3dbc922e1d878b963f411dc388ced501601c60f7c6f7;
address internal constant WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address internal constant PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;
function safeTransferETH(address to, uint256 amount) internal {
assembly {
if iszero(call(gas(), to, amount, codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, 0xb12d13eb)
revert(0x1c, 0x04)
}
}
}
function safeTransferAllETH(address to) internal {
assembly {
if iszero(call(gas(), to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, 0xb12d13eb)
revert(0x1c, 0x04)
}
}
}
function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal {
assembly {
if lt(selfbalance(), amount) {
mstore(0x00, 0xb12d13eb)
revert(0x1c, 0x04)
}
if iszero(call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to)
mstore8(0x0b, 0x73)
mstore8(0x20, 0xff)
if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) }
}
}
}
function forceSafeTransferAllETH(address to, uint256 gasStipend) internal {
assembly {
if iszero(call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to)
mstore8(0x0b, 0x73)
mstore8(0x20, 0xff)
if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) }
}
}
}
function forceSafeTransferETH(address to, uint256 amount) internal {
assembly {
if lt(selfbalance(), amount) {
mstore(0x00, 0xb12d13eb)
revert(0x1c, 0x04)
}
if iszero(call(GAS_STIPEND_NO_GRIEF, to, amount, codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to)
mstore8(0x0b, 0x73)
mstore8(0x20, 0xff)
if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) }
}
}
}
function forceSafeTransferAllETH(address to) internal {
assembly {
if iszero(call(GAS_STIPEND_NO_GRIEF, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to)
mstore8(0x0b, 0x73)
mstore8(0x20, 0xff)
if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) }
}
}
}
function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)
internal
returns (bool success)
{
assembly {
success := call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)
}
}
function trySafeTransferAllETH(address to, uint256 gasStipend)
internal
returns (bool success)
{
assembly {
success := call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)
}
}
function safeTransferFrom(address token, address from, address to, uint256 amount) internal {
assembly {
let m := mload(0x40)
mstore(0x60, amount)
mstore(0x40, to)
mstore(0x2c, shl(96, from))
mstore(0x0c, 0x23b872dd000000000000000000000000)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
)
) {
mstore(0x00, 0x7939f424)
revert(0x1c, 0x04)
}
mstore(0x60, 0)
mstore(0x40, m)
}
}
function trySafeTransferFrom(address token, address from, address to, uint256 amount)
internal
returns (bool success)
{
assembly {
let m := mload(0x40)
mstore(0x60, amount)
mstore(0x40, to)
mstore(0x2c, shl(96, from))
mstore(0x0c, 0x23b872dd000000000000000000000000)
success :=
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
)
mstore(0x60, 0)
mstore(0x40, m)
}
}
function safeTransferAllFrom(address token, address from, address to)
internal
returns (uint256 amount)
{
assembly {
let m := mload(0x40)
mstore(0x40, to)
mstore(0x2c, shl(96, from))
mstore(0x0c, 0x70a08231000000000000000000000000)
if iszero(
and(
gt(returndatasize(), 0x1f),
staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)
)
) {
mstore(0x00, 0x7939f424)
revert(0x1c, 0x04)
}
mstore(0x00, 0x23b872dd)
amount := mload(0x60)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
)
) {
mstore(0x00, 0x7939f424)
revert(0x1c, 0x04)
}
mstore(0x60, 0)
mstore(0x40, m)
}
}
function safeTransfer(address token, address to, uint256 amount) internal {
assembly {
mstore(0x14, to)
mstore(0x34, amount)
mstore(0x00, 0xa9059cbb000000000000000000000000)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x00, 0x90b8ec18)
revert(0x1c, 0x04)
}
mstore(0x34, 0)
}
}
function safeTransferAll(address token, address to) internal returns (uint256 amount) {
assembly {
mstore(0x00, 0x70a08231)
mstore(0x20, address())
if iszero(
and(
gt(returndatasize(), 0x1f),
staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20)
)
) {
mstore(0x00, 0x90b8ec18)
revert(0x1c, 0x04)
}
mstore(0x14, to)
amount := mload(0x34)
mstore(0x00, 0xa9059cbb000000000000000000000000)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x00, 0x90b8ec18)
revert(0x1c, 0x04)
}
mstore(0x34, 0)
}
}
function safeApprove(address token, address to, uint256 amount) internal {
assembly {
mstore(0x14, to)
mstore(0x34, amount)
mstore(0x00, 0x095ea7b3000000000000000000000000)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x00, 0x3e3f8f73)
revert(0x1c, 0x04)
}
mstore(0x34, 0)
}
}
function safeApproveWithRetry(address token, address to, uint256 amount) internal {
assembly {
mstore(0x14, to)
mstore(0x34, amount)
mstore(0x00, 0x095ea7b3000000000000000000000000)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x34, 0)
mstore(0x00, 0x095ea7b3000000000000000000000000)
pop(call(gas(), token, 0, 0x10, 0x44, codesize(), 0x00))
mstore(0x34, amount)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x00, 0x3e3f8f73)
revert(0x1c, 0x04)
}
}
mstore(0x34, 0)
}
}
function balanceOf(address token, address account) internal view returns (uint256 amount) {
assembly {
mstore(0x14, account)
mstore(0x00, 0x70a08231000000000000000000000000)
amount :=
mul(
mload(0x20),
and(
gt(returndatasize(), 0x1f),
staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)
)
)
}
}
function safeTransferFrom2(address token, address from, address to, uint256 amount) internal {
if (!trySafeTransferFrom(token, from, to, amount)) {
permit2TransferFrom(token, from, to, amount);
}
}
function permit2TransferFrom(address token, address from, address to, uint256 amount)
internal
{
assembly {
let m := mload(0x40)
mstore(add(m, 0x74), shr(96, shl(96, token)))
mstore(add(m, 0x54), amount)
mstore(add(m, 0x34), to)
mstore(add(m, 0x20), shl(96, from))
mstore(m, 0x36c78516000000000000000000000000)
let p := PERMIT2
let exists := eq(chainid(), 1)
if iszero(exists) { exists := iszero(iszero(extcodesize(p))) }
if iszero(and(call(gas(), p, 0, add(m, 0x10), 0x84, codesize(), 0x00), exists)) {
mstore(0x00, 0x7939f4248757f0fd)
revert(add(0x18, shl(2, iszero(iszero(shr(160, amount))))), 0x04)
}
}
}
function permit2(
address token,
address owner,
address spender,
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
bool success;
assembly {
for {} shl(96, xor(token, WETH9)) {} {
mstore(0x00, 0x3644e515)
if iszero(
and(
lt(iszero(mload(0x00)), eq(returndatasize(), 0x20)),
staticcall(5000, token, 0x1c, 0x04, 0x00, 0x20)
)
) { break }
let m := mload(0x40)
mstore(add(m, 0x34), spender)
mstore(add(m, 0x20), shl(96, owner))
mstore(add(m, 0x74), deadline)
if eq(mload(0x00), DAI_DOMAIN_SEPARATOR) {
mstore(0x14, owner)
mstore(0x00, 0x7ecebe00000000000000000000000000)
mstore(add(m, 0x94), staticcall(gas(), token, 0x10, 0x24, add(m, 0x54), 0x20))
mstore(m, 0x8fcbaf0c000000000000000000000000)
mstore(add(m, 0xb4), and(0xff, v))
mstore(add(m, 0xd4), r)
mstore(add(m, 0xf4), s)
success := call(gas(), token, 0, add(m, 0x10), 0x104, codesize(), 0x00)
break
}
mstore(m, 0xd505accf000000000000000000000000)
mstore(add(m, 0x54), amount)
mstore(add(m, 0x94), and(0xff, v))
mstore(add(m, 0xb4), r)
mstore(add(m, 0xd4), s)
success := call(gas(), token, 0, add(m, 0x10), 0xe4, codesize(), 0x00)
break
}
}
if (!success) simplePermit2(token, owner, spender, amount, deadline, v, r, s);
}
function simplePermit2(
address token,
address owner,
address spender,
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
assembly {
let m := mload(0x40)
mstore(m, 0x927da105)
{
let addressMask := shr(96, not(0))
mstore(add(m, 0x20), and(addressMask, owner))
mstore(add(m, 0x40), and(addressMask, token))
mstore(add(m, 0x60), and(addressMask, spender))
mstore(add(m, 0xc0), and(addressMask, spender))
}
let p := mul(PERMIT2, iszero(shr(160, amount)))
if iszero(
and(
gt(returndatasize(), 0x5f),
staticcall(gas(), p, add(m, 0x1c), 0x64, add(m, 0x60), 0x60)
)
) {
mstore(0x00, 0x6b836e6b8757f0fd)
revert(add(0x18, shl(2, iszero(p))), 0x04)
}
mstore(m, 0x2b67b570)
mstore(add(m, 0x60), amount)
mstore(add(m, 0x80), 0xffffffffffff)
mstore(add(m, 0xe0), deadline)
mstore(add(m, 0x100), 0x100)
mstore(add(m, 0x120), 0x41)
mstore(add(m, 0x140), r)
mstore(add(m, 0x160), s)
mstore(add(m, 0x180), shl(248, v))
if iszero(call(gas(), p, 0, add(m, 0x1c), 0x184, codesize(), 0x00)) {
mstore(0x00, 0x6b836e6b)
revert(0x1c, 0x04)
}
}
}
}
文件 20 的 24:Solarray.sol
pragma solidity >=0.6.2 <0.9.0;
library Solarray {
function uint8s(uint8 a) internal pure returns (uint8[] memory) {
uint8[] memory arr = new uint8[](1);
arr[0] = a;
return arr;
}
function uint8s(uint8 a,uint8 b) internal pure returns (uint8[] memory) {
uint8[] memory arr = new uint8[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function uint8s(uint8 a,uint8 b,uint8 c) internal pure returns (uint8[] memory) {
uint8[] memory arr = new uint8[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function uint8s(uint8 a,uint8 b,uint8 c,uint8 d) internal pure returns (uint8[] memory) {
uint8[] memory arr = new uint8[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function uint8s(uint8 a,uint8 b,uint8 c,uint8 d,uint8 e) internal pure returns (uint8[] memory) {
uint8[] memory arr = new uint8[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function uint8s(uint8 a,uint8 b,uint8 c,uint8 d,uint8 e,uint8 f) internal pure returns (uint8[] memory) {
uint8[] memory arr = new uint8[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function uint8s(uint8 a,uint8 b,uint8 c,uint8 d,uint8 e,uint8 f,uint8 g) internal pure returns (uint8[] memory) {
uint8[] memory arr = new uint8[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function uint16s(uint16 a) internal pure returns (uint16[] memory) {
uint16[] memory arr = new uint16[](1);
arr[0] = a;
return arr;
}
function uint16s(uint16 a,uint16 b) internal pure returns (uint16[] memory) {
uint16[] memory arr = new uint16[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function uint16s(uint16 a,uint16 b,uint16 c) internal pure returns (uint16[] memory) {
uint16[] memory arr = new uint16[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function uint16s(uint16 a,uint16 b,uint16 c,uint16 d) internal pure returns (uint16[] memory) {
uint16[] memory arr = new uint16[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function uint16s(uint16 a,uint16 b,uint16 c,uint16 d,uint16 e) internal pure returns (uint16[] memory) {
uint16[] memory arr = new uint16[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function uint16s(uint16 a,uint16 b,uint16 c,uint16 d,uint16 e,uint16 f) internal pure returns (uint16[] memory) {
uint16[] memory arr = new uint16[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function uint16s(uint16 a,uint16 b,uint16 c,uint16 d,uint16 e,uint16 f,uint16 g) internal pure returns (uint16[] memory) {
uint16[] memory arr = new uint16[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function uint32s(uint32 a) internal pure returns (uint32[] memory) {
uint32[] memory arr = new uint32[](1);
arr[0] = a;
return arr;
}
function uint32s(uint32 a,uint32 b) internal pure returns (uint32[] memory) {
uint32[] memory arr = new uint32[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function uint32s(uint32 a,uint32 b,uint32 c) internal pure returns (uint32[] memory) {
uint32[] memory arr = new uint32[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function uint32s(uint32 a,uint32 b,uint32 c,uint32 d) internal pure returns (uint32[] memory) {
uint32[] memory arr = new uint32[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function uint32s(uint32 a,uint32 b,uint32 c,uint32 d,uint32 e) internal pure returns (uint32[] memory) {
uint32[] memory arr = new uint32[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function uint32s(uint32 a,uint32 b,uint32 c,uint32 d,uint32 e,uint32 f) internal pure returns (uint32[] memory) {
uint32[] memory arr = new uint32[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function uint32s(uint32 a,uint32 b,uint32 c,uint32 d,uint32 e,uint32 f,uint32 g) internal pure returns (uint32[] memory) {
uint32[] memory arr = new uint32[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function uint40s(uint40 a) internal pure returns (uint40[] memory) {
uint40[] memory arr = new uint40[](1);
arr[0] = a;
return arr;
}
function uint40s(uint40 a,uint40 b) internal pure returns (uint40[] memory) {
uint40[] memory arr = new uint40[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function uint40s(uint40 a,uint40 b,uint40 c) internal pure returns (uint40[] memory) {
uint40[] memory arr = new uint40[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function uint40s(uint40 a,uint40 b,uint40 c,uint40 d) internal pure returns (uint40[] memory) {
uint40[] memory arr = new uint40[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function uint40s(uint40 a,uint40 b,uint40 c,uint40 d,uint40 e) internal pure returns (uint40[] memory) {
uint40[] memory arr = new uint40[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function uint40s(uint40 a,uint40 b,uint40 c,uint40 d,uint40 e,uint40 f) internal pure returns (uint40[] memory) {
uint40[] memory arr = new uint40[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function uint40s(uint40 a,uint40 b,uint40 c,uint40 d,uint40 e,uint40 f,uint40 g) internal pure returns (uint40[] memory) {
uint40[] memory arr = new uint40[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function uint64s(uint64 a) internal pure returns (uint64[] memory) {
uint64[] memory arr = new uint64[](1);
arr[0] = a;
return arr;
}
function uint64s(uint64 a,uint64 b) internal pure returns (uint64[] memory) {
uint64[] memory arr = new uint64[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function uint64s(uint64 a,uint64 b,uint64 c) internal pure returns (uint64[] memory) {
uint64[] memory arr = new uint64[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function uint64s(uint64 a,uint64 b,uint64 c,uint64 d) internal pure returns (uint64[] memory) {
uint64[] memory arr = new uint64[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function uint64s(uint64 a,uint64 b,uint64 c,uint64 d,uint64 e) internal pure returns (uint64[] memory) {
uint64[] memory arr = new uint64[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function uint64s(uint64 a,uint64 b,uint64 c,uint64 d,uint64 e,uint64 f) internal pure returns (uint64[] memory) {
uint64[] memory arr = new uint64[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function uint64s(uint64 a,uint64 b,uint64 c,uint64 d,uint64 e,uint64 f,uint64 g) internal pure returns (uint64[] memory) {
uint64[] memory arr = new uint64[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function uint128s(uint128 a) internal pure returns (uint128[] memory) {
uint128[] memory arr = new uint128[](1);
arr[0] = a;
return arr;
}
function uint128s(uint128 a,uint128 b) internal pure returns (uint128[] memory) {
uint128[] memory arr = new uint128[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function uint128s(uint128 a,uint128 b,uint128 c) internal pure returns (uint128[] memory) {
uint128[] memory arr = new uint128[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function uint128s(uint128 a,uint128 b,uint128 c,uint128 d) internal pure returns (uint128[] memory) {
uint128[] memory arr = new uint128[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function uint128s(uint128 a,uint128 b,uint128 c,uint128 d,uint128 e) internal pure returns (uint128[] memory) {
uint128[] memory arr = new uint128[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function uint128s(uint128 a,uint128 b,uint128 c,uint128 d,uint128 e,uint128 f) internal pure returns (uint128[] memory) {
uint128[] memory arr = new uint128[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function uint128s(uint128 a,uint128 b,uint128 c,uint128 d,uint128 e,uint128 f,uint128 g) internal pure returns (uint128[] memory) {
uint128[] memory arr = new uint128[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function uint256s(uint256 a) internal pure returns (uint256[] memory) {
uint256[] memory arr = new uint256[](1);
arr[0] = a;
return arr;
}
function uint256s(uint256 a,uint256 b) internal pure returns (uint256[] memory) {
uint256[] memory arr = new uint256[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function uint256s(uint256 a,uint256 b,uint256 c) internal pure returns (uint256[] memory) {
uint256[] memory arr = new uint256[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function uint256s(uint256 a,uint256 b,uint256 c,uint256 d) internal pure returns (uint256[] memory) {
uint256[] memory arr = new uint256[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function uint256s(uint256 a,uint256 b,uint256 c,uint256 d,uint256 e) internal pure returns (uint256[] memory) {
uint256[] memory arr = new uint256[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function uint256s(uint256 a,uint256 b,uint256 c,uint256 d,uint256 e,uint256 f) internal pure returns (uint256[] memory) {
uint256[] memory arr = new uint256[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function uint256s(uint256 a,uint256 b,uint256 c,uint256 d,uint256 e,uint256 f,uint256 g) internal pure returns (uint256[] memory) {
uint256[] memory arr = new uint256[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function int8s(int8 a) internal pure returns (int8[] memory) {
int8[] memory arr = new int8[](1);
arr[0] = a;
return arr;
}
function int8s(int8 a,int8 b) internal pure returns (int8[] memory) {
int8[] memory arr = new int8[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function int8s(int8 a,int8 b,int8 c) internal pure returns (int8[] memory) {
int8[] memory arr = new int8[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function int8s(int8 a,int8 b,int8 c,int8 d) internal pure returns (int8[] memory) {
int8[] memory arr = new int8[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function int8s(int8 a,int8 b,int8 c,int8 d,int8 e) internal pure returns (int8[] memory) {
int8[] memory arr = new int8[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function int8s(int8 a,int8 b,int8 c,int8 d,int8 e,int8 f) internal pure returns (int8[] memory) {
int8[] memory arr = new int8[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function int8s(int8 a,int8 b,int8 c,int8 d,int8 e,int8 f,int8 g) internal pure returns (int8[] memory) {
int8[] memory arr = new int8[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function int16s(int16 a) internal pure returns (int16[] memory) {
int16[] memory arr = new int16[](1);
arr[0] = a;
return arr;
}
function int16s(int16 a,int16 b) internal pure returns (int16[] memory) {
int16[] memory arr = new int16[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function int16s(int16 a,int16 b,int16 c) internal pure returns (int16[] memory) {
int16[] memory arr = new int16[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function int16s(int16 a,int16 b,int16 c,int16 d) internal pure returns (int16[] memory) {
int16[] memory arr = new int16[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function int16s(int16 a,int16 b,int16 c,int16 d,int16 e) internal pure returns (int16[] memory) {
int16[] memory arr = new int16[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function int16s(int16 a,int16 b,int16 c,int16 d,int16 e,int16 f) internal pure returns (int16[] memory) {
int16[] memory arr = new int16[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function int16s(int16 a,int16 b,int16 c,int16 d,int16 e,int16 f,int16 g) internal pure returns (int16[] memory) {
int16[] memory arr = new int16[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function int32s(int32 a) internal pure returns (int32[] memory) {
int32[] memory arr = new int32[](1);
arr[0] = a;
return arr;
}
function int32s(int32 a,int32 b) internal pure returns (int32[] memory) {
int32[] memory arr = new int32[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function int32s(int32 a,int32 b,int32 c) internal pure returns (int32[] memory) {
int32[] memory arr = new int32[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function int32s(int32 a,int32 b,int32 c,int32 d) internal pure returns (int32[] memory) {
int32[] memory arr = new int32[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function int32s(int32 a,int32 b,int32 c,int32 d,int32 e) internal pure returns (int32[] memory) {
int32[] memory arr = new int32[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function int32s(int32 a,int32 b,int32 c,int32 d,int32 e,int32 f) internal pure returns (int32[] memory) {
int32[] memory arr = new int32[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function int32s(int32 a,int32 b,int32 c,int32 d,int32 e,int32 f,int32 g) internal pure returns (int32[] memory) {
int32[] memory arr = new int32[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function int64s(int64 a) internal pure returns (int64[] memory) {
int64[] memory arr = new int64[](1);
arr[0] = a;
return arr;
}
function int64s(int64 a,int64 b) internal pure returns (int64[] memory) {
int64[] memory arr = new int64[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function int64s(int64 a,int64 b,int64 c) internal pure returns (int64[] memory) {
int64[] memory arr = new int64[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function int64s(int64 a,int64 b,int64 c,int64 d) internal pure returns (int64[] memory) {
int64[] memory arr = new int64[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function int64s(int64 a,int64 b,int64 c,int64 d,int64 e) internal pure returns (int64[] memory) {
int64[] memory arr = new int64[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function int64s(int64 a,int64 b,int64 c,int64 d,int64 e,int64 f) internal pure returns (int64[] memory) {
int64[] memory arr = new int64[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function int64s(int64 a,int64 b,int64 c,int64 d,int64 e,int64 f,int64 g) internal pure returns (int64[] memory) {
int64[] memory arr = new int64[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function int128s(int128 a) internal pure returns (int128[] memory) {
int128[] memory arr = new int128[](1);
arr[0] = a;
return arr;
}
function int128s(int128 a,int128 b) internal pure returns (int128[] memory) {
int128[] memory arr = new int128[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function int128s(int128 a,int128 b,int128 c) internal pure returns (int128[] memory) {
int128[] memory arr = new int128[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function int128s(int128 a,int128 b,int128 c,int128 d) internal pure returns (int128[] memory) {
int128[] memory arr = new int128[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function int128s(int128 a,int128 b,int128 c,int128 d,int128 e) internal pure returns (int128[] memory) {
int128[] memory arr = new int128[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function int128s(int128 a,int128 b,int128 c,int128 d,int128 e,int128 f) internal pure returns (int128[] memory) {
int128[] memory arr = new int128[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function int128s(int128 a,int128 b,int128 c,int128 d,int128 e,int128 f,int128 g) internal pure returns (int128[] memory) {
int128[] memory arr = new int128[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function int256s(int256 a) internal pure returns (int256[] memory) {
int256[] memory arr = new int256[](1);
arr[0] = a;
return arr;
}
function int256s(int256 a,int256 b) internal pure returns (int256[] memory) {
int256[] memory arr = new int256[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function int256s(int256 a,int256 b,int256 c) internal pure returns (int256[] memory) {
int256[] memory arr = new int256[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function int256s(int256 a,int256 b,int256 c,int256 d) internal pure returns (int256[] memory) {
int256[] memory arr = new int256[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function int256s(int256 a,int256 b,int256 c,int256 d,int256 e) internal pure returns (int256[] memory) {
int256[] memory arr = new int256[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function int256s(int256 a,int256 b,int256 c,int256 d,int256 e,int256 f) internal pure returns (int256[] memory) {
int256[] memory arr = new int256[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function int256s(int256 a,int256 b,int256 c,int256 d,int256 e,int256 f,int256 g) internal pure returns (int256[] memory) {
int256[] memory arr = new int256[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function bytes1s(bytes1 a) internal pure returns (bytes1[] memory) {
bytes1[] memory arr = new bytes1[](1);
arr[0] = a;
return arr;
}
function bytes1s(bytes1 a,bytes1 b) internal pure returns (bytes1[] memory) {
bytes1[] memory arr = new bytes1[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function bytes1s(bytes1 a,bytes1 b,bytes1 c) internal pure returns (bytes1[] memory) {
bytes1[] memory arr = new bytes1[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function bytes1s(bytes1 a,bytes1 b,bytes1 c,bytes1 d) internal pure returns (bytes1[] memory) {
bytes1[] memory arr = new bytes1[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function bytes1s(bytes1 a,bytes1 b,bytes1 c,bytes1 d,bytes1 e) internal pure returns (bytes1[] memory) {
bytes1[] memory arr = new bytes1[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function bytes1s(bytes1 a,bytes1 b,bytes1 c,bytes1 d,bytes1 e,bytes1 f) internal pure returns (bytes1[] memory) {
bytes1[] memory arr = new bytes1[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function bytes1s(bytes1 a,bytes1 b,bytes1 c,bytes1 d,bytes1 e,bytes1 f,bytes1 g) internal pure returns (bytes1[] memory) {
bytes1[] memory arr = new bytes1[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function bytes8s(bytes8 a) internal pure returns (bytes8[] memory) {
bytes8[] memory arr = new bytes8[](1);
arr[0] = a;
return arr;
}
function bytes8s(bytes8 a,bytes8 b) internal pure returns (bytes8[] memory) {
bytes8[] memory arr = new bytes8[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function bytes8s(bytes8 a,bytes8 b,bytes8 c) internal pure returns (bytes8[] memory) {
bytes8[] memory arr = new bytes8[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function bytes8s(bytes8 a,bytes8 b,bytes8 c,bytes8 d) internal pure returns (bytes8[] memory) {
bytes8[] memory arr = new bytes8[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function bytes8s(bytes8 a,bytes8 b,bytes8 c,bytes8 d,bytes8 e) internal pure returns (bytes8[] memory) {
bytes8[] memory arr = new bytes8[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function bytes8s(bytes8 a,bytes8 b,bytes8 c,bytes8 d,bytes8 e,bytes8 f) internal pure returns (bytes8[] memory) {
bytes8[] memory arr = new bytes8[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function bytes8s(bytes8 a,bytes8 b,bytes8 c,bytes8 d,bytes8 e,bytes8 f,bytes8 g) internal pure returns (bytes8[] memory) {
bytes8[] memory arr = new bytes8[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function bytes16s(bytes16 a) internal pure returns (bytes16[] memory) {
bytes16[] memory arr = new bytes16[](1);
arr[0] = a;
return arr;
}
function bytes16s(bytes16 a,bytes16 b) internal pure returns (bytes16[] memory) {
bytes16[] memory arr = new bytes16[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function bytes16s(bytes16 a,bytes16 b,bytes16 c) internal pure returns (bytes16[] memory) {
bytes16[] memory arr = new bytes16[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function bytes16s(bytes16 a,bytes16 b,bytes16 c,bytes16 d) internal pure returns (bytes16[] memory) {
bytes16[] memory arr = new bytes16[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function bytes16s(bytes16 a,bytes16 b,bytes16 c,bytes16 d,bytes16 e) internal pure returns (bytes16[] memory) {
bytes16[] memory arr = new bytes16[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function bytes16s(bytes16 a,bytes16 b,bytes16 c,bytes16 d,bytes16 e,bytes16 f) internal pure returns (bytes16[] memory) {
bytes16[] memory arr = new bytes16[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function bytes16s(bytes16 a,bytes16 b,bytes16 c,bytes16 d,bytes16 e,bytes16 f,bytes16 g) internal pure returns (bytes16[] memory) {
bytes16[] memory arr = new bytes16[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function bytes20s(bytes20 a) internal pure returns (bytes20[] memory) {
bytes20[] memory arr = new bytes20[](1);
arr[0] = a;
return arr;
}
function bytes20s(bytes20 a,bytes20 b) internal pure returns (bytes20[] memory) {
bytes20[] memory arr = new bytes20[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function bytes20s(bytes20 a,bytes20 b,bytes20 c) internal pure returns (bytes20[] memory) {
bytes20[] memory arr = new bytes20[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function bytes20s(bytes20 a,bytes20 b,bytes20 c,bytes20 d) internal pure returns (bytes20[] memory) {
bytes20[] memory arr = new bytes20[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function bytes20s(bytes20 a,bytes20 b,bytes20 c,bytes20 d,bytes20 e) internal pure returns (bytes20[] memory) {
bytes20[] memory arr = new bytes20[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function bytes20s(bytes20 a,bytes20 b,bytes20 c,bytes20 d,bytes20 e,bytes20 f) internal pure returns (bytes20[] memory) {
bytes20[] memory arr = new bytes20[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function bytes20s(bytes20 a,bytes20 b,bytes20 c,bytes20 d,bytes20 e,bytes20 f,bytes20 g) internal pure returns (bytes20[] memory) {
bytes20[] memory arr = new bytes20[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function bytes32s(bytes32 a) internal pure returns (bytes32[] memory) {
bytes32[] memory arr = new bytes32[](1);
arr[0] = a;
return arr;
}
function bytes32s(bytes32 a,bytes32 b) internal pure returns (bytes32[] memory) {
bytes32[] memory arr = new bytes32[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function bytes32s(bytes32 a,bytes32 b,bytes32 c) internal pure returns (bytes32[] memory) {
bytes32[] memory arr = new bytes32[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function bytes32s(bytes32 a,bytes32 b,bytes32 c,bytes32 d) internal pure returns (bytes32[] memory) {
bytes32[] memory arr = new bytes32[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function bytes32s(bytes32 a,bytes32 b,bytes32 c,bytes32 d,bytes32 e) internal pure returns (bytes32[] memory) {
bytes32[] memory arr = new bytes32[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function bytes32s(bytes32 a,bytes32 b,bytes32 c,bytes32 d,bytes32 e,bytes32 f) internal pure returns (bytes32[] memory) {
bytes32[] memory arr = new bytes32[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function bytes32s(bytes32 a,bytes32 b,bytes32 c,bytes32 d,bytes32 e,bytes32 f,bytes32 g) internal pure returns (bytes32[] memory) {
bytes32[] memory arr = new bytes32[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function bytess(bytes memory a) internal pure returns (bytes[] memory) {
bytes[] memory arr = new bytes[](1);
arr[0] = a;
return arr;
}
function bytess(bytes memory a,bytes memory b) internal pure returns (bytes[] memory) {
bytes[] memory arr = new bytes[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function bytess(bytes memory a,bytes memory b,bytes memory c) internal pure returns (bytes[] memory) {
bytes[] memory arr = new bytes[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function bytess(bytes memory a,bytes memory b,bytes memory c,bytes memory d) internal pure returns (bytes[] memory) {
bytes[] memory arr = new bytes[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function bytess(bytes memory a,bytes memory b,bytes memory c,bytes memory d,bytes memory e) internal pure returns (bytes[] memory) {
bytes[] memory arr = new bytes[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function bytess(bytes memory a,bytes memory b,bytes memory c,bytes memory d,bytes memory e,bytes memory f) internal pure returns (bytes[] memory) {
bytes[] memory arr = new bytes[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function bytess(bytes memory a,bytes memory b,bytes memory c,bytes memory d,bytes memory e,bytes memory f,bytes memory g) internal pure returns (bytes[] memory) {
bytes[] memory arr = new bytes[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function addresses(address a) internal pure returns (address[] memory) {
address[] memory arr = new address[](1);
arr[0] = a;
return arr;
}
function addresses(address a,address b) internal pure returns (address[] memory) {
address[] memory arr = new address[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function addresses(address a,address b,address c) internal pure returns (address[] memory) {
address[] memory arr = new address[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function addresses(address a,address b,address c,address d) internal pure returns (address[] memory) {
address[] memory arr = new address[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function addresses(address a,address b,address c,address d,address e) internal pure returns (address[] memory) {
address[] memory arr = new address[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function addresses(address a,address b,address c,address d,address e,address f) internal pure returns (address[] memory) {
address[] memory arr = new address[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function addresses(address a,address b,address c,address d,address e,address f,address g) internal pure returns (address[] memory) {
address[] memory arr = new address[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function bools(bool a) internal pure returns (bool[] memory) {
bool[] memory arr = new bool[](1);
arr[0] = a;
return arr;
}
function bools(bool a,bool b) internal pure returns (bool[] memory) {
bool[] memory arr = new bool[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function bools(bool a,bool b,bool c) internal pure returns (bool[] memory) {
bool[] memory arr = new bool[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function bools(bool a,bool b,bool c,bool d) internal pure returns (bool[] memory) {
bool[] memory arr = new bool[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function bools(bool a,bool b,bool c,bool d,bool e) internal pure returns (bool[] memory) {
bool[] memory arr = new bool[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function bools(bool a,bool b,bool c,bool d,bool e,bool f) internal pure returns (bool[] memory) {
bool[] memory arr = new bool[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function bools(bool a,bool b,bool c,bool d,bool e,bool f,bool g) internal pure returns (bool[] memory) {
bool[] memory arr = new bool[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
function strings(string memory a) internal pure returns (string[] memory) {
string[] memory arr = new string[](1);
arr[0] = a;
return arr;
}
function strings(string memory a,string memory b) internal pure returns (string[] memory) {
string[] memory arr = new string[](2);
arr[0] = a;
arr[1] = b;
return arr;
}
function strings(string memory a,string memory b,string memory c) internal pure returns (string[] memory) {
string[] memory arr = new string[](3);
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
function strings(string memory a,string memory b,string memory c,string memory d) internal pure returns (string[] memory) {
string[] memory arr = new string[](4);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
return arr;
}
function strings(string memory a,string memory b,string memory c,string memory d,string memory e) internal pure returns (string[] memory) {
string[] memory arr = new string[](5);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr;
}
function strings(string memory a,string memory b,string memory c,string memory d,string memory e,string memory f) internal pure returns (string[] memory) {
string[] memory arr = new string[](6);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
return arr;
}
function strings(string memory a,string memory b,string memory c,string memory d,string memory e,string memory f,string memory g) internal pure returns (string[] memory) {
string[] memory arr = new string[](7);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
arr[5] = f;
arr[6] = g;
return arr;
}
}
文件 21 的 24:StackScore.sol
pragma solidity ^0.8.17;
import {LibString} from "solady/utils/LibString.sol";
import {ReentrancyGuard} from "solady/utils/ReentrancyGuard.sol";
import {SafeTransferLib} from "solady/utils/SafeTransferLib.sol";
import {ECDSA} from "solady/utils/ECDSA.sol";
import {Solarray} from "solarray/Solarray.sol";
import {json} from "./onchain/json.sol";
import {Metadata, DisplayType} from "./onchain/Metadata.sol";
import {TraitLib} from "./dynamic-traits/lib/TraitLabelLib.sol";
import {AbstractNFT} from "./AbstractNFT.sol";
import {StackScoreRenderer} from "./StackScoreRenderer.sol";
import {IERC5192} from "./interfaces/IERC5192.sol";
contract StackScore is AbstractNFT, IERC5192, ReentrancyGuard {
string public constant version = "1";
string internal constant _tokenName = "Stack Score";
string internal constant _tokenDescription = "A dynamic, onchain, soulbound reputation score";
address public signer;
uint256 public mintFee = 0.001 ether;
uint256 public referralBps = 5000;
mapping(address => uint256) public addressToTokenId;
mapping(bytes32 => bool) internal signatures;
uint256 internal currentId;
StackScoreRenderer internal renderer;
address public mintFeeRecipient;
event ScoreUpdated(address account, uint256 tokenId, uint256 oldScore, uint256 newScore);
event Minted(address to, uint256 tokenId);
event ReferralPaid(address referrer, address referred, uint256 amount);
event MintFeeUpdated(uint256 oldFee, uint256 newFee);
event MintFeeRecipientUpdated(address oldRecipient, address newRecipient);
event ReferralBpsUpdated(uint256 oldBps, uint256 newBps);
event RendererUpdated(address oldRenderer, address newRenderer);
event SignerUpdated(address oldSigner, address newSigner);
error TokenLocked(uint256 tokenId);
error InvalidSignature();
error SignatureAlreadyUsed();
error InsufficientFee();
error OnlyTokenOwner();
error TimestampTooOld();
error OneTokenPerAddress();
constructor(address initialOwner) AbstractNFT(_tokenName, "STACK_SCORE") {
_initializeOwner(initialOwner);
}
function mint(address to) payable public nonReentrant returns (uint256) {
_assertSufficientFee();
SafeTransferLib.safeTransferETH(mintFeeRecipient, msg.value);
_mintTo(to);
return currentId;
}
function mintWithReferral(
address to,
address referrer
) payable public nonReentrant returns (uint256) {
_assertSufficientFee();
uint256 referralAmount = _getReferralAmount(msg.value);
SafeTransferLib.safeTransferETH(mintFeeRecipient, msg.value - referralAmount);
emit ReferralPaid(referrer, to, referralAmount);
SafeTransferLib.safeTransferETH(referrer, referralAmount);
_mintTo(to);
return currentId;
}
function mintWithScore(
address to,
uint256 score,
uint256 timestamp,
bytes memory signature
) payable public returns (uint256) {
mint(to);
updateScore(currentId, score, timestamp, signature);
return currentId;
}
function mintWithScoreAndPalette(
address to,
uint256 score,
uint256 timestamp,
uint256 palette,
bytes memory signature
) payable public returns (uint256) {
mint(to);
updateScore(currentId, score, timestamp, signature);
updatePalette(currentId, palette);
return currentId;
}
function mintWithScoreAndReferral(
address to,
uint256 score,
uint256 timestamp,
address referrer,
bytes memory signature
) payable public returns (uint256) {
mintWithReferral(to, referrer);
updateScore(currentId, score, timestamp, signature);
return currentId;
}
function mintWithScoreAndReferralAndPalette(
address to,
uint256 score,
uint256 timestamp,
address referrer,
uint256 palette,
bytes memory signature
) payable public returns (uint256) {
mintWithReferral(to, referrer);
updateScore(currentId, score, timestamp, signature);
updatePalette(currentId, palette);
return currentId;
}
function mintWithReferralAndPalette(
address to,
address referrer,
uint256 palette
) payable public nonReentrant returns (uint256) {
mintWithReferral(to, referrer);
updatePalette(currentId, palette);
return currentId;
}
function mintWithPalette(
address to,
uint256 palette
) payable public nonReentrant returns (uint256) {
mint(to);
updatePalette(currentId, palette);
return currentId;
}
function updateScore(uint256 tokenId, uint256 newScore, uint256 timestamp, bytes memory signature) public {
uint256 oldScore = uint256(getTraitValue(tokenId, "score"));
if (newScore == 0 && oldScore == 0) {
return;
}
address account = ownerOf(tokenId);
_assertValidTimestamp(tokenId, timestamp);
_assertValidScoreSignature(account, newScore, timestamp, signature);
this.setTrait(tokenId, "updatedAt", bytes32(timestamp));
this.setTrait(tokenId, "score", bytes32(newScore));
emit ScoreUpdated(account, tokenId, oldScore, newScore);
}
function updatePalette(uint256 tokenId, uint256 paletteIndex) public {
_assertTokenOwner(tokenId);
this.setTrait(tokenId, "paletteIndex", bytes32(paletteIndex));
}
function locked(uint256 tokenId) public pure override returns (bool) {
return true;
}
function getScore(address account) public view returns (uint256) {
return uint256(getTraitValue(addressToTokenId[account], "score"));
}
function getUpdatedAt(uint256 tokenId) public view returns (uint256) {
return uint256(getTraitValue(tokenId, "updatedAt"));
}
function getScoreAndLastUpdated(address account) public view returns (uint256, uint256) {
uint256 tokenId = addressToTokenId[account];
return (
uint256(getTraitValue(tokenId, "score")),
uint256(getTraitValue(tokenId, "updatedAt"))
);
}
function getPaletteIndex(uint256 tokenId) public view returns (uint256) {
return uint256(getTraitValue(tokenId, "paletteIndex"));
}
function getCurrentId() public view returns (uint256) {
return currentId;
}
function getRenderer() public view returns (address) {
return address(renderer);
}
function setRenderer(address _renderer) public onlyOwner {
address oldRenderer = address(renderer);
renderer = StackScoreRenderer(_renderer);
emit RendererUpdated(oldRenderer, _renderer);
}
function setSigner(address _signer) public onlyOwner {
address oldSigner = signer;
signer = _signer;
emit SignerUpdated(oldSigner, _signer);
}
function setMintFee(uint256 fee) public onlyOwner {
uint256 oldFee = mintFee;
mintFee = fee;
emit MintFeeUpdated(oldFee, mintFee);
}
function setReferralBps(uint256 bps) public onlyOwner {
referralBps = bps;
emit ReferralBpsUpdated(referralBps, bps);
}
function setMintFeeRecipient(address _mintFeeRecipient) public onlyOwner {
address oldFeeRecipient = mintFeeRecipient;
mintFeeRecipient = _mintFeeRecipient;
emit MintFeeRecipientUpdated(oldFeeRecipient, mintFeeRecipient);
}
function _getReferralAmount(uint256 amount) internal view returns (uint256) {
return amount * referralBps / 10000;
}
function _assertOneTokenPerAddress(address to) internal view {
if (balanceOf(to) > 0) {
revert OneTokenPerAddress();
}
}
function _mintTo(address to) internal {
_assertOneTokenPerAddress(to);
unchecked {
_mint(to, ++currentId);
}
addressToTokenId[to] = currentId;
emit Minted(to, currentId);
emit Locked(currentId);
}
function _assertValidScoreSignature(address account, uint256 score, uint256 timestamp, bytes memory signature) internal {
if (signatures[keccak256(signature)]) {
revert SignatureAlreadyUsed();
}
signatures[keccak256(signature)] = true;
bytes32 hash = ECDSA.toEthSignedMessageHash(
keccak256(abi.encodePacked(account, score, timestamp))
);
if (ECDSA.recover(hash, signature) != signer) {
revert InvalidSignature();
}
}
function _assertTokenOwner(uint256 tokenId) internal view {
if (msg.sender != ownerOf(tokenId)) {
revert OnlyTokenOwner();
}
}
function _assertValidTimestamp(uint256 tokenId, uint256 timestamp) internal view {
uint256 lastUpdatedAt = uint256(getTraitValue(tokenId, "updatedAt"));
if (lastUpdatedAt > timestamp) {
revert TimestampTooOld();
}
}
function _assertSufficientFee() internal view {
if (msg.value < mintFee) {
revert InsufficientFee();
}
}
function _stringURI(uint256 tokenId) internal view override returns (string memory) {
return json.objectOf(
Solarray.strings(
json.property("name", _tokenName),
json.property("description", _tokenDescription),
json.property("image", Metadata.base64SvgDataURI(_image(tokenId))),
_attributes(tokenId)
)
);
}
function _staticAttributes(uint256 tokenId) internal view virtual override returns (string[] memory) {
return Solarray.strings(
Metadata.attribute({traitType: "Score Version", value: version})
);
}
function _beforeTokenTransfer(address from, address, uint256 tokenId) internal pure override {
if (from != address(0)) {
revert TokenLocked(tokenId);
}
}
function _image(uint256 tokenId) internal view virtual override returns (string memory) {
address account = ownerOf(tokenId);
uint256 paletteIndex = uint256(getTraitValue(tokenId, "paletteIndex"));
uint256 score = uint256(getTraitValue(tokenId, "score"));
uint256 updatedAt = uint256(getTraitValue(tokenId, "updatedAt"));
return renderer.getSVG(score, account, paletteIndex, updatedAt);
}
function _isOwnerOrApproved(uint256 tokenId, address addr) internal view override returns (bool) {
return addr == ownerOf(tokenId);
}
}
文件 22 的 24:StackScoreRenderer.sol
pragma solidity ^0.8.17;
import {LibString} from "solady/utils/LibString.sol";
import {DateTimeLib} from "solady/utils/DateTimeLib.sol";
contract StackScoreRenderer {
bytes3[3][11] private COLOR_PALETTES = [
[bytes3(0x4F4C42), bytes3(0xACA695), bytes3(0xDBD9D1)],
[bytes3(0x1D3C86), bytes3(0x2960E7), bytes3(0x4DB0F3)],
[bytes3(0x0331A6), bytes3(0x5E83AA), bytes3(0xD2B481)],
[bytes3(0x412C3F), bytes3(0xDA6A87), bytes3(0xDF819A)],
[bytes3(0x0B241A), bytes3(0x5BC793), bytes3(0x5E83AA)],
[bytes3(0xEB90BE), bytes3(0xEC5E3B), bytes3(0xF9D85B)],
[bytes3(0xA13120), bytes3(0xEB5640), bytes3(0xEBDE8F)],
[bytes3(0x0331A6), bytes3(0xB6BEC6), bytes3(0xF6CB82)],
[bytes3(0x3B7BF6), bytes3(0xB7CDCE), bytes3(0xF09ABD)],
[bytes3(0x3579BD), bytes3(0xDEAC91), bytes3(0xEC6C3F)],
[bytes3(0x301C28), bytes3(0xCFA37F), bytes3(0xD7482C)]
];
string[] private MONTHS = [
"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
];
function getColorAsHexString(uint paletteIndex, uint colorIndex) public view returns (string memory) {
return LibString.toHexStringNoPrefix(
uint24(COLOR_PALETTES[paletteIndex][colorIndex]),
3
);
}
function getTimestampString(uint256 timestamp) public view returns (string memory) {
(
uint year,
uint month,
uint day,
uint hour,
uint minute,
) = DateTimeLib.timestampToDateTime(timestamp);
return string(abi.encodePacked(
MONTHS[month - 1], " ",
LibString.toString(day), " ",
LibString.toString(year), " ",
LibString.toString(hour), ":",
LibString.toString(minute), " UTC"
));
}
function generateColors(uint256 paletteIndex) private view returns (string memory) {
return string(
abi.encodePacked(
'<g filter="url(#B)">'
'<path fill="#',
getColorAsHexString(paletteIndex, 0),
'" d="M-230.25-60h900v330h-900z"/>'
'</g>',
'<g style="mix-blend-mode:overlay" class="B">'
'<path d="M391 202.95c-.312 0-.588-.048-.828-.144s-.468-.262-.684-.498-.436-.57-.66-.99c-.112-.212-.21-.374-.294-.486a.89.89 0 0 0-.276-.252.74.74 0 0 0-.366-.084c-.224 0-.404.074-.54.222s-.204.354-.204.63c0 .296.078.532.234.708s.374.286.666.33l-.036.54c-.424-.048-.758-.208-1.002-.48s-.366-.642-.366-1.098c0-.288.052-.536.156-.744a1.09 1.09 0 0 1 .438-.48 1.21 1.21 0 0 1 .642-.168c.22 0 .408.036.564.108s.296.192.432.36.284.398.444.702c.196.372.4.66.612.864s.396.312.564.324v-2.364H391v3zm.096-5.098c0 .308-.088.574-.264.798s-.436.398-.768.522-.732.18-1.188.18-.852-.06-1.188-.18-.594-.298-.774-.522a1.25 1.25 0 0 1-.27-.798c0-.304.09-.568.27-.792s.438-.402.774-.522a3.43 3.43 0 0 1 1.188-.186 3.43 3.43 0 0 1 1.188.186c.332.12.588.292.768.516s.264.49.264.798zm-.504 0c0-.2-.068-.372-.204-.516s-.338-.254-.594-.33a3.29 3.29 0 0 0-.918-.114 3.29 3.29 0 0 0-.918.114c-.26.076-.46.188-.6.336s-.21.314-.21.51.07.368.21.516.34.254.6.33a3.29 3.29 0 0 0 .918.114 3.29 3.29 0 0 0 .918-.114c.256-.076.454-.186.594-.33s.204-.316.204-.516zm-3.264-.6l.024-.48 3.06 1.68-.024.48-3.06-1.68zm3.672-1.497c-.312 0-.588-.048-.828-.144s-.468-.262-.684-.498-.436-.57-.66-.99c-.112-.212-.21-.374-.294-.486a.89.89 0 0 0-.276-.252.74.74 0 0 0-.366-.084c-.224 0-.404.074-.54.222s-.204.354-.204.63c0 .296.078.532.234.708s.374.286.666.33l-.036.54c-.424-.048-.758-.208-1.002-.48s-.366-.642-.366-1.098c0-.288.052-.536.156-.744a1.09 1.09 0 0 1 .438-.48 1.21 1.21 0 0 1 .642-.168c.22 0 .408.036.564.108s.296.192.432.36.284.398.444.702c.196.372.4.66.612.864s.396.312.564.324v-2.364H391v3zm-.924-5.626v2.088h-.468l-2.868-2.052v-.552h2.832v-.516h.504v.516H391v.516h-.924zm-.504 0h-2.04l2.04 1.464v-1.464zm1.428-3.034v.324h-.72v-.72h.636l1.02.378v.3l-.936-.282zm-4.26-5.851v-.72l3.576-1.524h-3.576v-.516H391v.72l-3.576 1.524H391v.516h-4.26zm2.52-4.726l-2.52 1.284v-.588l1.92-.948-1.92-.948v-.588l2.52 1.272H391v.516h-1.74zm1.836-3.861c0 .336-.09.624-.27.864s-.436.416-.768.54-.726.18-1.182.18-.856-.06-1.188-.18-.594-.304-.774-.54-.27-.528-.27-.864a1.35 1.35 0 0 1 .372-.96c.244-.264.586-.44 1.026-.528l.036.552c-.3.068-.53.184-.69.348a.81.81 0 0 0-.24.588c0 .224.068.414.204.57s.328.274.588.354.568.12.936.12.674-.04.93-.12.452-.198.588-.354.198-.346.198-.57c0-.252-.088-.462-.264-.63s-.43-.288-.762-.348l.03-.546c.468.08.836.254 1.104.522a1.37 1.37 0 0 1 .396 1.002zm.318-7.4c0 .132-.072.222-.186.222-.132 0-.198-.066-.342-.066-.312 0-.54.174-.828.45-.714.69-1.056 1.104-2.016 1.104-.672 0-1.326-.486-1.506-1.122-.036-.126-.048-.252-.048-.384 0-.36.132-.738.366-1.038.144-.186.264-.33.264-.414 0-.108-.114-.228-.3-.474-.126-.168-.204-.354-.264-.528a1.35 1.35 0 0 1-.066-.432c0-.858.678-1.482 1.566-1.482.516 0 1.044.234 1.59.78.72.72 1.464 1.962 1.686 2.85a2.35 2.35 0 0 1 .084.534z" fill-opacity=".5"/>'
'</g>'
'<g style="mix-blend-mode:overlay" class="B">'
'<path d="M391.096 417.384c0 .296-.06.562-.18.798s-.296.418-.516.558a1.65 1.65 0 0 1-.762.246l-.036-.54c.212-.028.392-.088.54-.18a.95.95 0 0 0 .336-.366c.076-.152.114-.328.114-.528s-.024-.362-.072-.498-.126-.244-.222-.312a.59.59 0 0 0-.354-.108c-.144 0-.264.032-.36.096s-.194.182-.282.354-.178.416-.27.744c-.088.304-.182.546-.282.726s-.22.306-.36.39-.322.12-.534.12c-.236 0-.446-.056-.63-.168a1.14 1.14 0 0 1-.426-.492c-.104-.216-.156-.468-.156-.756s.058-.53.174-.738a1.32 1.32 0 0 1 .48-.504c.204-.124.438-.202.702-.234l.036.54a1.19 1.19 0 0 0-.462.156.78.78 0 0 0-.312.312c-.076.132-.114.292-.114.48 0 .264.064.474.192.63s.288.234.492.234c.136 0 .246-.028.33-.084s.158-.16.222-.3a5.15 5.15 0 0 0 .216-.636c.1-.352.21-.628.33-.828a1.13 1.13 0 0 1 .42-.444c.164-.092.366-.138.606-.138.22 0 .418.062.594.186s.306.298.402.522a1.89 1.89 0 0 1 .144.762zm-3.864-3.274v1.302h-.492v-3.12h.492v1.302H391v.516h-3.768zm-.492-3.507v-.696l4.26-1.296v.528l-3.792 1.116 3.792 1.116v.528l-4.26-1.296zm2.58.462v-1.62l.492-.18v1.98l-.492-.18zm1.776-4.42c0 .336-.09.624-.27.864s-.436.416-.768.54-.726.18-1.182.18-.856-.06-1.188-.18-.594-.304-.774-.54-.27-.528-.27-.864a1.35 1.35 0 0 1 .372-.96c.244-.264.586-.44 1.026-.528l.036.552c-.3.068-.53.184-.69.348a.81.81 0 0 0-.24.588c0 .224.068.414.204.57s.328.274.588.354.568.12.936.12.674-.04.93-.12.452-.198.588-.354.198-.346.198-.57c0-.252-.088-.462-.264-.63s-.43-.288-.762-.348l.03-.546c.468.08.836.254 1.104.522a1.37 1.37 0 0 1 .396 1.002zm-4.356-2.146v-.516h1.884l-1.884-1.728v-.636l1.788 1.62 2.472-1.74v.636l-2.112 1.464.408.384H391v.516h-4.26zm.492-8.377v1.302h-.492v-3.12h.492v1.302H391v.516h-3.768zm-.492-2.596v-2.592h.492v2.076h1.38v-2.004h.492v2.004h1.404v-2.124H391v2.64h-4.26zm4.356-4.869c0 .336-.09.624-.27.864s-.436.416-.768.54-.726.18-1.182.18-.856-.06-1.188-.18-.594-.304-.774-.54-.27-.528-.27-.864a1.35 1.35 0 0 1 .372-.96c.244-.264.586-.44 1.026-.528l.036.552c-.3.068-.53.184-.69.348a.81.81 0 0 0-.24.588c0 .224.068.414.204.57s.328.274.588.354.568.12.936.12.674-.04.93-.12.452-.198.588-.354.198-.346.198-.57c0-.252-.088-.462-.264-.63s-.43-.288-.762-.348l.03-.546c.468.08.836.254 1.104.522a1.37 1.37 0 0 1 .396 1.002zm-4.356-2.194v-.516h2.07l-.198.264v-2.28l.198.264h-2.07v-.516H391v.516h-2.094l.198-.264v2.28l-.198-.264H391v.516h-4.26zm0-3.61v-.72l3.576-1.524h-3.576v-.516H391v.72l-3.576 1.524H391v.516h-4.26zm4.356-4.977c0 .336-.086.622-.258.858s-.424.41-.756.534-.734.18-1.206.18-.88-.06-1.212-.18-.59-.302-.762-.534-.258-.522-.258-.858a1.39 1.39 0 0 1 .258-.852c.172-.236.426-.414.762-.534s.736-.186 1.212-.186.874.062 1.206.186.584.298.756.534a1.39 1.39 0 0 1 .258.852zm-.504 0a.82.82 0 0 0-.198-.558c-.132-.156-.326-.274-.582-.354s-.568-.12-.936-.12-.68.04-.936.12-.456.198-.588.354-.204.338-.204.558a.83.83 0 0 0 .204.564c.132.152.328.268.588.348s.568.12.936.12.68-.04.936-.12.45-.196.582-.348.198-.344.198-.564zm-3.852-2.398v-.516h4.02l-.252.258v-2.382H391v2.64h-4.26zm4.356-4.798c0 .336-.086.622-.258.858s-.424.41-.756.534-.734.18-1.206.18-.88-.06-1.212-.18-.59-.302-.762-.534-.258-.522-.258-.858a1.39 1.39 0 0 1 .258-.852c.172-.236.426-.414.762-.534s.736-.186 1.212-.186.874.062 1.206.186.584.298.756.534a1.39 1.39 0 0 1 .258.852zm-.504 0a.82.82 0 0 0-.198-.558c-.132-.156-.326-.274-.582-.354s-.568-.12-.936-.12-.68.04-.936.12-.456.198-.588.354-.204.338-.204.558a.83.83 0 0 0 .204.564c.132.152.328.268.588.348s.568.12.936.12.68-.04.936-.12.45-.196.582-.348.198-.344.198-.564zm.504-3.585a1.36 1.36 0 0 1-.252.81c-.172.236-.424.42-.756.552s-.736.198-1.212.198a3.43 3.43 0 0 1-1.188-.186c-.336-.128-.594-.31-.774-.546a1.38 1.38 0 0 1-.27-.852c0-.38.124-.7.372-.96s.58-.438.996-.534l.036.54c-.276.072-.494.188-.654.348a.81.81 0 0 0-.246.606.83.83 0 0 0 .204.564c.132.156.328.276.588.36s.568.12.936.12.674-.042.93-.126.452-.206.588-.366.198-.352.198-.576c0-.192-.054-.362-.162-.51a1.06 1.06 0 0 0-.444-.354 1.66 1.66 0 0 0-.642-.144v1.02h-.492v-1.5H391v.48l-1.008.024.06-.168c.332.096.59.24.774.432s.27.448.27.768zm-.588-2.29v-1.062h-3.276v1.062h-.492v-2.64h.492v1.062h3.276v-1.062H391v2.64h-.492zm-3.768-3.658v-2.592h.492v2.076h1.38v-2.004h.492v2.004h1.404v-2.124H391v2.64h-4.26zm4.356-4.923c0 .296-.06.562-.18.798s-.296.418-.516.558a1.65 1.65 0 0 1-.762.246l-.036-.54c.212-.028.392-.088.54-.18a.95.95 0 0 0 .336-.366c.076-.152.114-.328.114-.528s-.024-.362-.072-.498-.126-.244-.222-.312a.59.59 0 0 0-.354-.108c-.144 0-.264.032-.36.096s-.194.182-.282.354-.178.416-.27.744c-.088.304-.182.546-.282.726s-.22.306-.36.39-.322.12-.534.12c-.236 0-.446-.056-.63-.168a1.14 1.14 0 0 1-.426-.492c-.104-.216-.156-.468-.156-.756s.058-.53.174-.738a1.32 1.32 0 0 1 .48-.504c.204-.124.438-.202.702-.234l.036.54a1.19 1.19 0 0 0-.462.156.78.78 0 0 0-.312.312c-.076.132-.114.292-.114.48 0 .264.064.474.192.63s.288.234.492.234c.136 0 .246-.028.33-.084s.158-.16.222-.3a5.15 5.15 0 0 0 .216-.636c.1-.352.21-.628.33-.828a1.13 1.13 0 0 1 .42-.444c.164-.092.366-.138.606-.138.22 0 .418.062.594.186s.306.298.402.522a1.89 1.89 0 0 1 .144.762zm-.588-5.809v-1.062h-3.276v1.062h-.492v-2.64h.492v1.062h3.276v-1.062H391v2.64h-.492zm-3.768-3.538v-.72l3.576-1.524h-3.576v-.516H391v.72l-3.576 1.524H391v.516h-4.26zm4.356-4.99c0 .336-.09.624-.27.864s-.436.416-.768.54-.726.18-1.182.18-.856-.06-1.188-.18-.594-.304-.774-.54-.27-.528-.27-.864a1.35 1.35 0 0 1 .372-.96c.244-.264.586-.44 1.026-.528l.036.552c-.3.068-.53.184-.69.348a.81.81 0 0 0-.24.588c0 .224.068.414.204.57s.328.274.588.354.568.12.936.12.674-.04.93-.12.452-.198.588-.354.198-.346.198-.57c0-.252-.088-.462-.264-.63s-.43-.288-.762-.348l.03-.546c.468.08.836.254 1.104.522a1.37 1.37 0 0 1 .396 1.002zm-.816-3.225v-.72h.72v.72h-.72z" fill-opacity=".5"/>'
'</g>'
'<g filter="url(#C)">'
'<path fill="#',
getColorAsHexString(paletteIndex, 1),
'" d="M-247.5 195h900v150h-900z"/>'
'</g>'
'<g filter="url(#A)">'
'<path fill="#',
getColorAsHexString(paletteIndex, 2),
'" d="M-230.25 270h900v330.75h-900z"/>'
'</g>'
)
);
}
function getSVG(
uint256 score,
address account,
uint256 paletteIndex,
uint256 lastUpdated
) public view returns (string memory) {
return string(
abi.encodePacked(
'<svg xmlns="http://www.w3.org/2000/svg" width="405" height="540" fill="none" xmlns:v="https://vecta.io/nano">'
'<style><![CDATA[.B{fill:#fff}.C{color-interpolation-filters:sRGB}.D{flood-opacity:0}.E{font-family:"DM Mono", monospace}.F{dominant-baseline:hanging}]]></style>'
'<defs><style>@import url(\'https://fonts.googleapis.com/css2?family=DM+Mono%3Awght@300400&display=swap\');</style></defs>'
'<g clip-path="url(#E)">'
'<rect width="405" height="540" rx="24" fill="color(display-p3 0.0353 0.0392 0.0471)"/>',
generateColors(paletteIndex),
'<g style="mix-blend-mode:overlay" class="B E F">'
'<text x="24" y="24" font-size="7.5" font-weight="300">LAST UPDATED ',
getTimestampString(lastUpdated),
'</text>'
'</g>',
'<g style="mix-blend-mode:overlay" class="B E F">'
'<text x="24" y="175.5" font-size="108" font-weight="300">',
LibString.toString(score),
'</text>'
'</g>'
'<g style="mix-blend-mode:overlay" class="B E F">'
'<text x="24" y="282" font-size="9">',
LibString.toHexString(account),
'</text>'
'</g>'
'<g style="mix-blend-mode:overlay" filter="url(#D)">'
'<rect x="2.625" y="2.625" width="399.75" height="534.75" rx="22.875" stroke="#fff" stroke-width="5.25"/>'
'</g>'
'<g style="mix-blend-mode:overlay" class="B">'
'<path d="M40.32 470.518c-2.592 0-4.864-.48-6.816-1.44-1.952-.992-3.504-2.368-4.656-4.128s-1.824-3.792-2.016-6.096l4.32-.288c.224 1.696.72 3.136 1.488 4.32a7.35 7.35 0 0 0 3.072 2.688c1.312.608 2.88.912 4.704.912 2.4 0 4.256-.464 5.568-1.392s1.968-2.256 1.968-3.984c0-1.12-.256-2.08-.768-2.88s-1.472-1.536-2.88-2.208-3.44-1.344-6.096-2.016c-2.688-.672-4.8-1.408-6.336-2.208-1.504-.8-2.608-1.76-3.312-2.88-.672-1.152-1.008-2.592-1.008-4.32 0-1.888.448-3.568 1.344-5.04.928-1.472 2.24-2.608 3.936-3.408 1.728-.832 3.744-1.248 6.048-1.248 2.432 0 4.544.464 6.336 1.392 1.824.928 3.264 2.208 4.32 3.84 1.088 1.632 1.76 3.504 2.016 5.616l-4.32.288c-.192-1.408-.64-2.64-1.344-3.696-.704-1.088-1.648-1.92-2.832-2.496-1.184-.608-2.608-.912-4.272-.912-2.112 0-3.792.512-5.04 1.536-1.248.992-1.872 2.304-1.872 3.936 0 1.088.24 1.968.72 2.64.512.672 1.376 1.28 2.592 1.824 1.248.512 3.12 1.072 5.616 1.68 2.816.704 5.056 1.536 6.72 2.496 1.696.96 2.912 2.08 3.648 3.36.736 1.248 1.104 2.72 1.104 4.416 0 1.952-.512 3.664-1.536 5.136-1.024 1.44-2.448 2.56-4.272 3.36-1.792.8-3.84 1.2-6.144 1.2zm26.035-.768c-2.304 0-4.016-.528-5.136-1.584-1.088-1.056-1.632-2.704-1.632-4.944v-24.864h4.032v24.768c0 1.12.24 1.92.72 2.4.512.448 1.312.672 2.4.672h3.648v3.552h-4.032zm-10.512-25.44h14.544v3.552H55.843v-3.552zm27.146 26.016c-2.656 0-4.752-.608-6.288-1.824s-2.304-2.912-2.304-5.088.64-3.888 1.92-5.136 3.312-2.128 6.096-2.64l9.024-1.68c0-2.144-.512-3.744-1.536-4.8-.992-1.056-2.496-1.584-4.512-1.584-1.728 0-3.12.384-4.176 1.152-1.024.768-1.728 1.904-2.112 3.408l-4.272-.336c.48-2.464 1.648-4.416 3.504-5.856 1.888-1.472 4.24-2.208 7.056-2.208 3.232 0 5.712.912 7.44 2.736 1.76 1.824 2.64 4.368 2.64 7.632v10.512c0 .576.096.992.288 1.248.224.224.576.336 1.056.336h1.008v3.552c-.192.032-.416.048-.672.048-.256.032-.544.048-.864.048-1.76 0-3.008-.416-3.744-1.248s-1.104-2.208-1.104-4.128l.48.096c-.32 1.632-1.344 3.008-3.072 4.128-1.728 1.088-3.68 1.632-5.856 1.632zm.384-3.552c1.664 0 3.104-.32 4.32-.96 1.216-.672 2.144-1.568 2.784-2.688.64-1.152.96-2.432.96-3.84v-1.824l-8.256 1.536c-1.664.288-2.848.768-3.552 1.44-.672.64-1.008 1.504-1.008 2.592 0 1.184.416 2.112 1.248 2.784.832.64 2 .96 3.504.96zm29.594 3.552c-2.336 0-4.384-.544-6.144-1.632s-3.12-2.64-4.08-4.656-1.44-4.352-1.44-7.008.48-4.992 1.44-7.008 2.32-3.568 4.08-4.656 3.808-1.632 6.144-1.632c1.952 0 3.68.352 5.184 1.056a8.89 8.89 0 0 1 3.744 3.024c.96 1.312 1.584 2.896 1.872 4.752l-4.224.288c-.288-1.664-1.024-2.96-2.208-3.888-1.152-.928-2.608-1.392-4.368-1.392-2.336 0-4.16.832-5.472 2.496s-1.968 3.984-1.968 6.96.656 5.296 1.968 6.96 3.136 2.496 5.472 2.496c1.76 0 3.216-.48 4.368-1.44 1.184-.992 1.92-2.432 2.208-4.32l4.224.288c-.288 1.888-.912 3.536-1.872 4.944-.96 1.376-2.208 2.448-3.744 3.216s-3.264 1.152-5.184 1.152zm16.17-34.656h4.032v22.32l12.384-13.68h5.376l-10.032 10.8 10.464 14.64h-4.896l-8.304-11.904-4.992 5.28v6.624h-4.032v-34.08zM40.32 513.518c-2.592 0-4.864-.48-6.816-1.44-1.952-.992-3.504-2.368-4.656-4.128s-1.824-3.792-2.016-6.096l4.32-.288c.224 1.696.72 3.136 1.488 4.32a7.35 7.35 0 0 0 3.072 2.688c1.312.608 2.88.912 4.704.912 2.4 0 4.256-.464 5.568-1.392s1.968-2.256 1.968-3.984c0-1.12-.256-2.08-.768-2.88s-1.472-1.536-2.88-2.208-3.44-1.344-6.096-2.016c-2.688-.672-4.8-1.408-6.336-2.208-1.504-.8-2.608-1.76-3.312-2.88-.672-1.152-1.008-2.592-1.008-4.32 0-1.888.448-3.568 1.344-5.04.928-1.472 2.24-2.608 3.936-3.408 1.728-.832 3.744-1.248 6.048-1.248 2.432 0 4.544.464 6.336 1.392 1.824.928 3.264 2.208 4.32 3.84 1.088 1.632 1.76 3.504 2.016 5.616l-4.32.288c-.192-1.408-.64-2.64-1.344-3.696-.704-1.088-1.648-1.92-2.832-2.496-1.184-.608-2.608-.912-4.272-.912-2.112 0-3.792.512-5.04 1.536-1.248.992-1.872 2.304-1.872 3.936 0 1.088.24 1.968.72 2.64.512.672 1.376 1.28 2.592 1.824 1.248.512 3.12 1.072 5.616 1.68 2.816.704 5.056 1.536 6.72 2.496 1.696.96 2.912 2.08 3.648 3.36.736 1.248 1.104 2.72 1.104 4.416 0 1.952-.512 3.664-1.536 5.136-1.024 1.44-2.448 2.56-4.272 3.36-1.792.8-3.84 1.2-6.144 1.2zm28.725-.192c-2.336 0-4.384-.544-6.144-1.632s-3.12-2.64-4.08-4.656-1.44-4.352-1.44-7.008.48-4.992 1.44-7.008 2.32-3.568 4.08-4.656 3.808-1.632 6.144-1.632c1.952 0 3.68.352 5.184 1.056a8.89 8.89 0 0 1 3.744 3.024c.96 1.312 1.584 2.896 1.872 4.752l-4.224.288c-.288-1.664-1.024-2.96-2.208-3.888-1.152-.928-2.608-1.392-4.368-1.392-2.336 0-4.16.832-5.472 2.496s-1.968 3.984-1.968 6.96.656 5.296 1.968 6.96 3.136 2.496 5.472 2.496c1.76 0 3.216-.48 4.368-1.44 1.184-.992 1.92-2.432 2.208-4.32l4.224.288c-.288 1.888-.912 3.536-1.872 4.944-.96 1.376-2.208 2.448-3.744 3.216s-3.264 1.152-5.184 1.152zm26.25 0c-2.336 0-4.384-.544-6.144-1.632s-3.12-2.624-4.08-4.608c-.96-2.016-1.44-4.368-1.44-7.056s.48-5.024 1.44-7.008c.96-2.016 2.32-3.568 4.08-4.656s3.808-1.632 6.144-1.632c2.304 0 4.336.544 6.096 1.632s3.12 2.64 4.08 4.656c.96 1.984 1.44 4.32 1.44 7.008s-.48 5.04-1.44 7.056c-.96 1.984-2.32 3.52-4.08 4.608s-3.792 1.632-6.096 1.632zm0-3.84c2.336 0 4.144-.832 5.424-2.496 1.312-1.696 1.968-4.016 1.968-6.96s-.656-5.248-1.968-6.912c-1.28-1.696-3.088-2.544-5.424-2.544s-4.16.832-5.472 2.496-1.968 3.984-1.968 6.96.656 5.296 1.968 6.96 3.136 2.496 5.472 2.496zm17.483-22.176h3.552l.192 6.432-.384-.144c.32-2.144 1.008-3.728 2.064-4.752s2.496-1.536 4.32-1.536h2.496v3.84h-2.448c-1.28 0-2.352.24-3.216.72-.832.448-1.472 1.136-1.92 2.064-.416.928-.624 2.08-.624 3.456v15.36h-4.032v-25.44zm26.955 26.016c-2.368 0-4.432-.544-6.192-1.632s-3.12-2.624-4.08-4.608c-.928-2.016-1.392-4.368-1.392-7.056 0-2.656.464-4.992 1.392-7.008.96-2.016 2.304-3.568 4.032-4.656s3.744-1.632 6.048-1.632c2.208 0 4.16.528 5.856 1.584 1.696 1.024 3.008 2.544 3.936 4.56.96 2.016 1.44 4.416 1.44 7.2v1.2h-18.48c.128 2.688.832 4.736 2.112 6.144 1.312 1.376 3.088 2.064 5.328 2.064 1.632 0 2.976-.368 4.032-1.104 1.088-.768 1.856-1.824 2.304-3.168l4.32.336c-.672 2.336-1.968 4.224-3.888 5.664-1.888 1.408-4.144 2.112-6.768 2.112zm6.624-15.6c-.192-2.368-.896-4.144-2.112-5.328-1.184-1.216-2.752-1.824-4.704-1.824-1.984 0-3.616.608-4.896 1.824-1.248 1.216-2.032 2.992-2.352 5.328h14.064z"/>'
'</g>'
'<g style="mix-blend-mode:overlay" class="B">'
'<path fill-rule="evenodd" d="M347.842 474c-4.883 0-8.842 3.959-8.842 8.842v24.316c0 4.883 3.959 8.842 8.842 8.842h24.316c4.883 0 8.842-3.959 8.842-8.842v-24.316c0-4.883-3.959-8.842-8.842-8.842h-24.316zm13.069 16.799a2.33 2.33 0 0 0-.911 1.85v16.059a1.46 1.46 0 0 0 1.458 1.458h12.25a1.46 1.46 0 0 0 1.459-1.458v-27.69c0-.484-.556-.758-.939-.463l-13.317 10.244z"/>'
'</g>'
'<g style="mix-blend-mode:overlay">'
'<rect x="6.375" y="6.375" width="392.25" height="527.25" rx="17.625" stroke="#fff" stroke-width=".75"/>'
'</g>'
'<g style="mix-blend-mode:overlay">'
'<path stroke="#fff" stroke-width=".75" d="M24 269.625h357"/>'
'</g>'
'</g>'
'<defs>'
'<filter id="A" x="-356.25" y="144" width="1152" height="582.75" filterUnits="userSpaceOnUse" class="C"><feFlood class="D"/><feBlend in="SourceGraphic"/><feGaussianBlur stdDeviation="63"/></filter>'
'<filter id="B" x="-356.25" y="-186" width="1152" height="582" filterUnits="userSpaceOnUse" class="C"><feFlood class="D"/><feBlend in="SourceGraphic"/><feGaussianBlur stdDeviation="63"/></filter>'
'<filter id="C" x="-373.5" y="69" width="1152" height="402" filterUnits="userSpaceOnUse" class="C"><feFlood class="D"/><feBlend in="SourceGraphic"/><feGaussianBlur stdDeviation="63"/></filter>'
'<filter id="D" x="-3" y="-3" width="411" height="546" filterUnits="userSpaceOnUse" class="C"><feFlood class="D"/><feBlend in="SourceGraphic"/><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="E">'
'<rect width="405" height="540" rx="24" fill-opacity="1" class="B"/>'
'</clipPath></defs></svg>'
)
);
}
}
文件 23 的 24:TraitLabelLib.sol
pragma solidity ^0.8.17;
import {DisplayType, Metadata} from "../../onchain/Metadata.sol";
import {json} from "../../onchain/json.sol";
import {Solarray} from "solarray/Solarray.sol";
import {LibString} from "solady/utils/LibString.sol";
import {SSTORE2} from "solady/utils/SSTORE2.sol";
type Editors is uint8;
type StoredTraitLabel is address;
enum AllowedEditor {
Anyone,
Self,
TokenOwner,
Custom,
ContractOwner
}
struct FullTraitValue {
bytes32 traitValue;
string fullTraitValue;
}
struct TraitLabel {
string fullTraitKey;
string traitLabel;
string[] acceptableValues;
FullTraitValue[] fullTraitValues;
DisplayType displayType;
Editors editors;
bool required;
}
struct TraitLabelStorage {
Editors allowedEditors;
bool required;
bool valuesRequireValidation;
StoredTraitLabel storedLabel;
}
library TraitLabelStorageLib {
function toTraitLabel(TraitLabelStorage memory labelStorage) internal view returns (TraitLabel memory) {
return StoredTraitLabelLib.load(labelStorage.storedLabel);
}
function toAttributeJson(
mapping(bytes32 traitKey => TraitLabelStorage traitLabelStorage) storage traitLabelStorage,
bytes32 traitKey,
bytes32 traitValue
) internal view returns (string memory) {
TraitLabelStorage storage labelStorage = traitLabelStorage[traitKey];
TraitLabel memory traitLabel = toTraitLabel(labelStorage);
string memory actualTraitValue;
if (traitLabel.fullTraitValues.length != 0) {
uint256 length = traitLabel.fullTraitValues.length;
for (uint256 i = 0; i < length;) {
FullTraitValue memory fullTraitValue = traitLabel.fullTraitValues[i];
if (fullTraitValue.traitValue == traitValue) {
actualTraitValue = fullTraitValue.fullTraitValue;
break;
}
unchecked {
++i;
}
}
}
if (bytes(actualTraitValue).length == 0) {
actualTraitValue = TraitLib.toString(traitValue, traitLabel.displayType);
}
return Metadata.attribute({
traitType: traitLabel.traitLabel,
value: actualTraitValue,
displayType: traitLabel.displayType
});
}
function toLabelJson(mapping(bytes32 => TraitLabelStorage) storage traitLabelStorage, bytes32[] memory keys)
internal
view
returns (string memory)
{
string[] memory result = new string[](keys.length);
uint256 i;
for (i; i < keys.length;) {
bytes32 key = keys[i];
TraitLabel memory traitLabel = TraitLabelStorageLib.toTraitLabel(traitLabelStorage[key]);
result[i] = TraitLabelLib.toLabelJson(traitLabel, key);
unchecked {
++i;
}
}
return json.arrayOf(result);
}
}
library FullTraitValueLib {
function toJson(FullTraitValue memory fullTraitValue) internal pure returns (string memory) {
return json.objectOf(
Solarray.strings(
json.property("traitValue", LibString.toHexString(uint256(fullTraitValue.traitValue))),
json.property("fullTraitValue", fullTraitValue.fullTraitValue)
)
);
}
function toJson(FullTraitValue[] memory fullTraitValues) internal pure returns (string memory) {
string[] memory result = new string[](fullTraitValues.length);
for (uint256 i = 0; i < fullTraitValues.length;) {
result[i] = toJson(fullTraitValues[i]);
unchecked {
++i;
}
}
return json.arrayOf(result);
}
}
library TraitLabelLib {
error InvalidTraitValue(bytes32 traitKey, bytes32 traitValue);
function store(TraitLabel memory self) internal returns (StoredTraitLabel) {
return StoredTraitLabel.wrap(SSTORE2.write(abi.encode(self)));
}
function validateAcceptableValue(TraitLabel memory label, bytes32 traitKey, bytes32 traitValue) internal pure {
string[] memory acceptableValues = label.acceptableValues;
uint256 length = acceptableValues.length;
DisplayType displayType = label.displayType;
if (length != 0) {
string memory stringValue = TraitLib.toString(traitValue, displayType);
bytes32 hashedValue = keccak256(abi.encodePacked(stringValue));
for (uint256 i = 0; i < length;) {
if (hashedValue == keccak256(abi.encodePacked(acceptableValues[i]))) {
return;
}
unchecked {
++i;
}
}
revert InvalidTraitValue(traitKey, traitValue);
}
}
function toLabelJson(TraitLabel memory label, bytes32 traitKey) internal pure returns (string memory) {
return json.objectOf(
Solarray.strings(
json.property("traitKey", TraitLib.asString(traitKey)),
json.property(
"fullTraitKey",
bytes(label.fullTraitKey).length == 0 ? TraitLib.asString(traitKey) : label.fullTraitKey
),
json.property("traitLabel", label.traitLabel),
json.rawProperty("acceptableValues", TraitLib.toJson(label.acceptableValues)),
json.rawProperty("fullTraitValues", FullTraitValueLib.toJson(label.fullTraitValues)),
json.property("displayType", Metadata.toString(label.displayType)),
json.rawProperty("editors", EditorsLib.toJson(label.editors))
)
);
}
}
library TraitLib {
function toString(bytes32 key, DisplayType displayType) internal pure returns (string memory) {
if (
displayType == DisplayType.Number || displayType == DisplayType.BoostNumber
|| displayType == DisplayType.BoostPercent
) {
return LibString.toString(uint256(key));
} else {
return asString(key);
}
}
function asString(bytes32 key) internal pure returns (string memory) {
uint256 len = _bytes32StringLength(key);
string memory result;
assembly {
result := mload(0x40)
mstore(0x40, add(0x40, result))
mstore(result, len)
mstore(add(result, 0x20), key)
}
return result;
}
function _bytes32StringLength(bytes32 str) internal pure returns (uint256) {
for (uint256 i; i < 32;) {
if (str[i] == 0) {
return i;
}
unchecked {
++i;
}
}
return 32;
}
function toJson(string[] memory acceptableValues) internal pure returns (string memory) {
return json.arrayOf(json.quote(acceptableValues));
}
}
library EditorsLib {
function aggregate(AllowedEditor[] memory editors) internal pure returns (Editors) {
uint256 editorsLength = editors.length;
uint256 result;
for (uint256 i = 0; i < editorsLength;) {
result |= 1 << uint8(editors[i]);
unchecked {
++i;
}
}
return Editors.wrap(uint8(result));
}
function expand(Editors editors) internal pure returns (AllowedEditor[] memory allowedEditors) {
uint8 _editors = Editors.unwrap(editors);
if (_editors & 1 == 1) {
allowedEditors = new AllowedEditor[](1);
allowedEditors[0] = AllowedEditor.Anyone;
return allowedEditors;
}
AllowedEditor[] memory result = new AllowedEditor[](4);
uint256 num;
for (uint256 i = 1; i < 5;) {
bool set = _editors & (1 << i) != 0;
if (set) {
result[num] = AllowedEditor(i);
unchecked {
++num;
}
}
unchecked {
++i;
}
}
assembly {
mstore(result, num)
}
return result;
}
function toBitMap(AllowedEditor editor) internal pure returns (uint8) {
return uint8(1 << uint256(editor));
}
function contains(Editors self, AllowedEditor editor) internal pure returns (bool) {
return Editors.unwrap(self) & toBitMap(editor) != 0;
}
function toJson(Editors editors) internal pure returns (string memory) {
return toJson(expand(editors));
}
function toJson(AllowedEditor[] memory editors) internal pure returns (string memory) {
string[] memory result = new string[](editors.length);
for (uint256 i = 0; i < editors.length;) {
result[i] = LibString.toString(uint8(editors[i]));
unchecked {
++i;
}
}
return json.arrayOf(result);
}
}
library StoredTraitLabelLib {
function exists(StoredTraitLabel storedTraitLabel) internal pure returns (bool) {
return StoredTraitLabel.unwrap(storedTraitLabel) != address(0);
}
function load(StoredTraitLabel storedTraitLabel) internal view returns (TraitLabel memory) {
bytes memory data = SSTORE2.read(StoredTraitLabel.unwrap(storedTraitLabel));
return abi.decode(data, (TraitLabel));
}
}
using EditorsLib for Editors global;
using StoredTraitLabelLib for StoredTraitLabel global;
文件 24 的 24:json.sol
pragma solidity ^0.8.4;
import {LibString} from "solady/utils/LibString.sol";
library json {
string private constant NULL = "";
using LibString for string;
function object(string memory value) internal pure returns (string memory) {
return string.concat("{", value, "}");
}
function array(string memory value) internal pure returns (string memory) {
return string.concat("[", value, "]");
}
function property(string memory name, string memory value) internal pure returns (string memory) {
return string.concat('"', name.escapeJSON(), '":"', value.escapeJSON(), '"');
}
function rawProperty(string memory name, string memory rawValue) internal pure returns (string memory) {
return string.concat('"', name.escapeJSON(), '":', rawValue);
}
function objectOf(string[] memory properties) internal pure returns (string memory) {
return object(_commaJoin(properties));
}
function arrayOf(string[] memory values) internal pure returns (string memory) {
return array(_commaJoin(values));
}
function arrayOf(string[] memory values1, string[] memory values2) internal pure returns (string memory) {
if (values1.length == 0) {
return arrayOf(values2);
} else if (values2.length == 0) {
return arrayOf(values1);
}
return array(string.concat(_commaJoin(values1), ",", _commaJoin(values2)));
}
function quote(string memory str) internal pure returns (string memory) {
return string.concat('"', str.escapeJSON(), '"');
}
function quote(string[] memory strs) internal pure returns (string[] memory) {
string[] memory result = new string[](strs.length);
for (uint256 i = 0; i < strs.length;) {
result[i] = quote(strs[i]);
unchecked {
++i;
}
}
return result;
}
function _commaJoin(string[] memory values) internal pure returns (string memory) {
return _join(values, ",");
}
function _commaJoin(string memory value1, string memory value2) internal pure returns (string memory) {
return string.concat(value1, ",", value2);
}
function _join(string[] memory values, string memory separator) internal pure returns (string memory) {
if (values.length == 0) {
return NULL;
}
string memory result = values[0];
for (uint256 i = 1; i < values.length; ++i) {
result = string.concat(result, separator, values[i]);
}
return result;
}
}
{
"compilationTarget": {
"src/StackScore.sol": "StackScore"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
":ds-test/=lib/solarray/lib/forge-std/lib/ds-test/src/",
":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
":forge-std/=lib/forge-std/src/",
":openzeppelin-contracts/=lib/openzeppelin-contracts/",
":solady/=lib/solady/src/",
":solarray/=lib/solarray/src/"
]
}
[{"inputs":[{"internalType":"address","name":"initialOwner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccountBalanceOverflow","type":"error"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"InsufficientFee","type":"error"},{"inputs":[],"name":"InsufficientPrivilege","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[{"internalType":"bytes32","name":"traitKey","type":"bytes32"},{"internalType":"bytes32","name":"traitValue","type":"bytes32"}],"name":"InvalidTraitValue","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"NotOwnerNorApproved","type":"error"},{"inputs":[],"name":"OneTokenPerAddress","type":"error"},{"inputs":[],"name":"OnlyTokenOwner","type":"error"},{"inputs":[],"name":"Reentrancy","type":"error"},{"inputs":[],"name":"SignatureAlreadyUsed","type":"error"},{"inputs":[],"name":"TimestampTooOld","type":"error"},{"inputs":[],"name":"TokenAlreadyExists","type":"error"},{"inputs":[],"name":"TokenDoesNotExist","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"TokenLocked","type":"error"},{"inputs":[{"internalType":"bytes32","name":"traitKey","type":"bytes32"}],"name":"TraitDoesNotExist","type":"error"},{"inputs":[],"name":"TraitValueUnchanged","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","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":"isApproved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Locked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldRecipient","type":"address"},{"indexed":false,"internalType":"address","name":"newRecipient","type":"address"}],"name":"MintFeeRecipientUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"MintFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"bool","name":"approved","type":"bool"}],"name":"PreapprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldBps","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBps","type":"uint256"}],"name":"ReferralBpsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"referrer","type":"address"},{"indexed":false,"internalType":"address","name":"referred","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReferralPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldRenderer","type":"address"},{"indexed":false,"internalType":"address","name":"newRenderer","type":"address"}],"name":"RendererUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldScore","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newScore","type":"uint256"}],"name":"ScoreUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldSigner","type":"address"},{"indexed":false,"internalType":"address","name":"newSigner","type":"address"}],"name":"SignerUpdated","type":"event"},{"anonymous":false,"inputs":[],"name":"TraitMetadataURIUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"traitKey","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"traitValue","type":"bytes32"}],"name":"TraitUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"traitKey","type":"bytes32"},{"indexed":false,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"TraitUpdatedList","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"traitKey","type":"bytes32"},{"indexed":false,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"indexed":false,"internalType":"bytes32","name":"traitValue","type":"bytes32"}],"name":"TraitUpdatedListUniformValue","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"traitKey","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"}],"name":"TraitUpdatedRange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"traitKey","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"traitValue","type":"bytes32"}],"name":"TraitUpdatedRangeUniformValue","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":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Unlocked","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressToTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getCustomEditorAt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCustomEditors","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCustomEditorsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPaletteIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRenderer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getScore","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getScoreAndLastUpdated","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTraitMetadataURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes32","name":"traitKey","type":"bytes32"}],"name":"getTraitValue","outputs":[{"internalType":"bytes32","name":"traitValue","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes32[]","name":"traitKeys","type":"bytes32[]"}],"name":"getTraitValues","outputs":[{"internalType":"bytes32[]","name":"traitValues","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getUpdatedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[{"internalType":"address","name":"editor","type":"address"}],"name":"isCustomEditor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"locked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintFeeRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"palette","type":"uint256"}],"name":"mintWithPalette","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"referrer","type":"address"}],"name":"mintWithReferral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"uint256","name":"palette","type":"uint256"}],"name":"mintWithReferralAndPalette","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"score","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"mintWithScore","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"score","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"palette","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"mintWithScoreAndPalette","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"score","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"mintWithScoreAndReferral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"score","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"uint256","name":"palette","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"mintWithScoreAndReferralAndPalette","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"referralBps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"isApproved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"setMintFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_mintFeeRecipient","type":"address"}],"name":"setMintFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"bps","type":"uint256"}],"name":"setReferralBps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_renderer","type":"address"}],"name":"setRenderer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes32","name":"traitKey","type":"bytes32"},{"internalType":"bytes32","name":"newValue","type":"bytes32"}],"name":"setTrait","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"traitKey","type":"bytes32"},{"components":[{"internalType":"string","name":"fullTraitKey","type":"string"},{"internalType":"string","name":"traitLabel","type":"string"},{"internalType":"string[]","name":"acceptableValues","type":"string[]"},{"components":[{"internalType":"bytes32","name":"traitValue","type":"bytes32"},{"internalType":"string","name":"fullTraitValue","type":"string"}],"internalType":"struct FullTraitValue[]","name":"fullTraitValues","type":"tuple[]"},{"internalType":"enum DisplayType","name":"displayType","type":"uint8"},{"internalType":"Editors","name":"editors","type":"uint8"},{"internalType":"bool","name":"required","type":"bool"}],"internalType":"struct TraitLabel","name":"_traitLabel","type":"tuple"}],"name":"setTraitLabel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":"bytes32","name":"traitKey","type":"bytes32"}],"name":"traitLabelStorage","outputs":[{"components":[{"internalType":"Editors","name":"allowedEditors","type":"uint8"},{"internalType":"bool","name":"required","type":"bool"},{"internalType":"bool","name":"valuesRequireValidation","type":"bool"},{"internalType":"StoredTraitLabel","name":"storedLabel","type":"address"}],"internalType":"struct TraitLabelStorage","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"editor","type":"address"},{"internalType":"bool","name":"insert","type":"bool"}],"name":"updateCustomEditor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"paletteIndex","type":"uint256"}],"name":"updatePalette","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"newScore","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"updateScore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]