编译器
0.8.18+commit.87f61d96
文件 1 的 11:Base64.sol
pragma solidity ^0.8.17;
library Base64 {
bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
function encode(bytes memory data) internal pure returns (string memory) {
uint256 len = data.length;
if (len == 0) return "";
uint256 encodedLen = 4 * ((len + 2) / 3);
bytes memory result = new bytes(encodedLen + 32);
bytes memory table = TABLE;
assembly {
let tablePtr := add(table, 1)
let resultPtr := add(result, 32)
for {
let i := 0
} lt(i, len) {
} {
i := add(i, 3)
let input := and(mload(add(data, i)), 0xffffff)
let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
out := shl(8, out)
out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF))
out := shl(8, out)
out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF))
out := shl(8, out)
out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF))
out := shl(224, out)
mstore(resultPtr, out)
resultPtr := add(resultPtr, 4)
}
switch mod(len, 3)
case 1 {
mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
}
case 2 {
mstore(sub(resultPtr, 1), shl(248, 0x3d))
}
mstore(result, encodedLen)
}
return string(result);
}
}
文件 2 的 11:Create2.sol
pragma solidity ^0.8.0;
library Create2 {
function deploy(
uint256 amount,
bytes32 salt,
bytes memory bytecode
) internal returns (address addr) {
require(address(this).balance >= amount, "Create2: insufficient balance");
require(bytecode.length != 0, "Create2: bytecode length is zero");
assembly {
addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
}
require(addr != address(0), "Create2: Failed on deploy");
}
function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {
return computeAddress(salt, bytecodeHash, address(this));
}
function computeAddress(
bytes32 salt,
bytes32 bytecodeHash,
address deployer
) internal pure returns (address addr) {
assembly {
let ptr := mload(0x40)
mstore(add(ptr, 0x40), bytecodeHash)
mstore(add(ptr, 0x20), salt)
mstore(ptr, deployer)
let start := add(ptr, 0x0b)
mstore8(start, 0xff)
addr := keccak256(start, 85)
}
}
}
文件 3 的 11:GIF32.sol
pragma solidity ^0.8.17;
library GIF32 {
bytes6 constant private HEADER = 0x474946383961;
bytes1 constant private FOOTER = 0x3b;
bytes8 constant private TRANSPARENT = 0x21f9040100000000;
bytes19 constant private ANIMATION = 0x21FF0B4E45545343415045322E300301000000;
bytes3 constant private GCE_PREFIX = 0x21f904;
function gce10x (bool disposeClear, uint8 delay, uint8 transparentColorIndex) internal pure returns (bytes memory) {
uint d = uint256(delay) * 10;
uint8 delay1 = uint8(d & 255);
uint8 delay2 = uint8((d >> 8) & 255);
return abi.encodePacked(GCE_PREFIX,
uint8(disposeClear ? 9 : 5),
uint8(delay1),
uint8(delay2),
transparentColorIndex,
uint8(0));
}
function gce (bool disposeClear, uint8 delay, uint8 transparentColorIndex) internal pure returns (bytes memory) {
return abi.encodePacked(GCE_PREFIX,
uint8(disposeClear ? 9 : 5),
uint8(delay),
uint8(0),
transparentColorIndex,
uint8(0));
}
function gce (bool disposeClear, uint8 delay) internal pure returns (bytes memory) {
return abi.encodePacked(GCE_PREFIX,
uint8(disposeClear ? 8 : 4),
uint8(delay),
uint24(0));
}
function _frame (uint8 x, uint8 y, uint8 w, uint8 h, uint8 mcs, bytes memory lct_data, bytes memory chunks) private pure returns (bytes memory) {
return abi.encodePacked(uint8(0x2c),
x, uint8(0),
y, uint8(0),
w, uint8(0),
h, uint8(0),
lct_data,
mcs,
chunks,
uint8(0));
}
function frame (uint8 x, uint8 y, uint8 w, uint8 h, uint8 mcs, bytes memory chunks) internal pure returns (bytes memory) {
return _frame(x, y, w, h, mcs, abi.encodePacked(uint8(0)), chunks);
}
function frame (uint8 x, uint8 y, uint8 w, uint8 h, uint8 mcs, bytes memory chunks, bytes memory lct) internal pure returns (bytes memory) {
return _frame(x, y, w, h, mcs, abi.encodePacked(uint8(240 + mcs - 1), lct), chunks);
}
function _assembleStatic (uint8 width, uint8 height, bool transparency, bytes memory frames, bytes memory gct_data) private pure returns (bytes memory) {
bytes memory transparent = transparency ? abi.encodePacked(TRANSPARENT) : bytes("");
return abi.encodePacked(HEADER,
width, uint8(0),
height, uint8(0),
gct_data,
transparent,
frames,
FOOTER);
}
function assembleStatic (uint8 width, uint8 height, bool transparency, bytes memory frames) internal pure returns (bytes memory) {
return _assembleStatic(width, height, transparency, frames, abi.encodePacked(uint24(0)));
}
function assembleStatic (uint8 width, uint8 height, bool transparency, bytes memory frames, uint8 mcs, bytes memory gct) internal pure returns (bytes memory) {
return _assembleStatic(width, height, transparency, frames, abi.encodePacked(uint8(240 + mcs - 1), uint16(0), gct));
}
function _assembleAnimated (uint8 width, uint8 height, bytes memory framedata, bytes memory gct_data) private pure returns (bytes memory) {
return abi.encodePacked(HEADER,
width, uint8(0),
height, uint8(0),
gct_data,
ANIMATION,
framedata,
FOOTER);
}
function assembleAnimated (uint8 width, uint8 height, bytes memory framedata) internal pure returns (bytes memory) {
return _assembleAnimated(width, height, framedata, abi.encodePacked(uint24(0)));
}
function assembleAnimated (uint8 width, uint8 height, bytes memory framedata, uint8 mcs, bytes memory gct) internal pure returns (bytes memory) {
return _assembleAnimated(width, height, framedata, abi.encodePacked(uint8(240 + mcs - 1), uint16(0), gct));
}
}
文件 4 的 11:IERC721Receiver.sol
pragma solidity ^0.8.0;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 5 的 11:ItemStorage.sol
pragma solidity ^0.8.17;
import "solmate/src/utils/SSTORE2.sol";
library ItemStorage {
struct Block {
uint48 total;
uint48 count;
address pointer;
}
struct Store {
Block[] blocks;
}
function total (Store storage store) internal view returns (uint48) {
uint len = store.blocks.length;
if (len == 0) {
return 0;
} else {
return store.blocks[len - 1].total;
}
}
function upload (Store storage store, uint48 count, bytes memory data) internal {
require(data.length < 65536, "Too large");
address pointer = SSTORE2.write(data);
store.blocks.push(Block(uint48(total(store) + count), count, pointer));
}
function sideload (Store storage store, uint48 count, address pointer) internal {
store.blocks.push(Block(uint48(total(store)) + count, count, pointer));
}
function bget (Store storage store, uint id) internal view returns (bytes memory) {
require(id < total(store), "Out of bounds");
uint last = store.blocks.length - 1;
uint cursor = last / 2;
Block storage b = store.blocks[cursor];
while (true) {
if (id >= b.total) {
cursor = (last - cursor + 1) / 2 + cursor;
} else if (id < (b.total - b.count)) {
uint temp = cursor;
last = cursor;
cursor = temp / 2;
} else {
cursor = b.count - (b.total - id);
break;
}
b = store.blocks[cursor];
}
address pointer = b.pointer;
uint pos = cursor * 2;
uint dataStart = uint16(bytes2(SSTORE2.read(pointer, pos, pos + 2)));
uint dataEnd = uint16(bytes2(SSTORE2.read(pointer, pos + 2, pos + 4)));
return SSTORE2.read(pointer, dataStart, dataEnd);
}
function lget (Store storage store, uint id) internal view returns (bytes memory) {
require(id < total(store), "Out of bounds");
uint cursor = 0;
Block storage b = store.blocks[cursor];
while (true) {
if (id < b.total) {
cursor = b.count - (b.total - id);
break;
}
b = store.blocks[++cursor];
}
address pointer = b.pointer;
uint pos = cursor * 2;
uint dataStart = uint16(bytes2(SSTORE2.read(pointer, pos, pos + 2)));
uint dataEnd = uint16(bytes2(SSTORE2.read(pointer, pos + 2, pos + 4)));
return SSTORE2.read(pointer, dataStart, dataEnd);
}
}
文件 6 的 11:Lawless.sol
pragma solidity ^0.8.17;
import "./lib/LawlessGIF.sol";
import "../lib/TokenizedContract.sol";
import "@openzeppelin/contracts/utils/Create2.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
interface IDelegationRegistry {
function checkDelegateForContract(address delegate, address vault, address contract_) external view returns(bool);
function checkDelegateForToken(address delegate, address vault, address contract_, uint256 tokenId) external view returns (bool);
}
interface ICustomAttributes {
function getCustomAttributes () external view returns (bytes memory);
}
interface ILawlessMetadata {
function generateTokenURI (LawlessData memory) external view returns (string memory);
function setB64EncodeURI (bool value) external;
function addMetadataMod (address addr) external;
}
type Ex is uint256;
struct Record {
address owner;
uint16 index;
uint16 version;
uint16 style;
uint48 details;
}
struct LawlessData {
uint id;
uint modelId;
uint paletteId;
address owner;
uint16 version;
uint48 details;
}
contract Lawless is TokenizedContract, LawlessGIF {
string public name = "lawless";
string public symbol = unicode"🏴";
constructor (uint256 tokenId) TokenizedContract(tokenId) {
addRole(owner(), Role.Uploader);
addRole(owner(), Role.Curator);
addRole(owner(), Role.Pauser);
addRole(0xEBFEFB02CaD474D35CabADEbddF0b32D287BE1bd, Role.CodeLawless);
}
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
uint256 internal constant maxSupply = 8192;
uint256 internal constant maxSupplyMod = 8191;
uint256 public totalSupply = 0;
Record[maxSupply] internal Records;
mapping (address => uint16[maxSupply+1]) internal TokensByOwner;
modifier validLawlessId (uint id) {
require(id < totalSupply, "unrecognized lawless");
_;
}
IDelegationRegistry constant dc = IDelegationRegistry(0x00000000000076A84feF008CDAbe6409d2FE638B);
bool public delegationEnabled = true;
function smashFlask () public onlyBy(Role.Ponderware) {
delegationEnabled = false;
}
function uploadModels (uint48 count, bytes memory data) public onlyBy(Role.Uploader) {
_uploadModels(count, data);
}
function uploadPalettes (uint48 count, bytes memory data) public onlyBy(Role.Uploader) {
_uploadPalettes(count, data);
}
ILawlessMetadata Metadata;
function setMetadata (bytes calldata metadata) public onlyBy(Role.Curator) {
removeRole(address(Metadata), Role.Metadata);
Metadata = ILawlessMetadata(Create2.deploy(0, 0, abi.encodePacked(metadata, abi.encode(address(this), CodexAddress))));
addRole(address(Metadata), Role.Metadata);
}
function setB64EncodeURI (bool value) public onlyBy(Role.Curator) {
Metadata.setB64EncodeURI(value);
}
function addMetadataMod (address addr) public onlyBy(Role.Curator) {
Metadata.addMetadataMod(addr);
}
function getModel (uint id) public view onlyBy(Role.Metadata) returns (Model memory) {
return _getModel(id);
}
function getPalette (uint id) public view onlyBy(Role.Metadata) returns (bytes memory) {
return _getPalette(id);
}
function staticGIF (Model memory model, bytes memory palette) public view onlyBy(Role.Metadata) returns (string memory) {
return _staticGIF(model, palette);
}
function animatedGIF (Model memory model, bytes memory palette) public view onlyBy(Role.Metadata) returns (string memory) {
return _animatedGIF(model, palette);
}
function getModelAndPaletteIds (uint style) internal pure returns (uint, uint) {
return (style >> 5, style & 31);
}
function getData (uint id) public view validLawlessId(id) returns (LawlessData memory) {
Record storage record = Records[id];
(uint modelId, uint paletteId) = getModelAndPaletteIds(record.style);
return LawlessData(id, modelId, paletteId, record.owner, record.version, record.details);
}
function tokenURI (Ex tokenId) public view returns (string memory) {
uint id = Ex.unwrap(tokenId) & maxSupplyMod;
require (Ex.unwrap(tokenId) == (id + Records[id].version * maxSupply), "invalid tokenId");
return Metadata.generateTokenURI(getData(id));
}
function getTokenId (uint256 id) external view validLawlessId(id) returns (uint) {
return id + Records[id].version * maxSupply;
}
function getLawlessId (Ex tokenId) external view returns (uint id) {
id = Ex.unwrap(tokenId) & maxSupplyMod;
require (id < totalSupply && Ex.unwrap(tokenId) == (id + Records[id].version * maxSupply), "invalid tokenId");
}
function lawlessGIF (uint256 id, bool base) public view validLawlessId(id) returns (string memory) {
Record storage record = Records[id];
(uint modelId, uint paletteId) = getModelAndPaletteIds(record.style);
uint details = record.details;
if (!base) {
uint morph = details >> 24;
if ((morph & 1024) > 0) {
modelId = 256 + (morph & 1023);
}
uint shift = details >> 12;
if ((shift & 1024) > 0) {
paletteId = 32 + (shift & 1023);
}
}
if (details >= 211106232532992 || modelId > 255) {
return _animatedGIF(_getModel(modelId), _getPalette(paletteId));
} else {
return _staticGIF(_getModel(modelId), _getPalette(paletteId));
}
}
function tokenGIF (Ex tokenId, bool base) external view returns (string memory) {
uint id = Ex.unwrap(tokenId) & maxSupplyMod;
require (Ex.unwrap(tokenId) == (id + Records[id].version * maxSupply), "invalid tokenId");
return lawlessGIF(id, base);
}
function _updateId (uint id, address owner) internal {
uint currentVersion = Records[id].version++;
uint currentExternalId = id + (currentVersion * totalSupply);
uint nextExternalId = currentExternalId + maxSupply;
emit Transfer(owner, address(0), currentExternalId);
emit Transfer(address(0), owner, nextExternalId);
}
function _authorized (uint id, address owner, address operator) internal view returns (bool) {
return (operator == CodexAddress
|| operator == owner
|| TokenApprovals[id] == operator
|| isApprovedForAll(owner, operator)
|| (delegationEnabled
&& (dc.checkDelegateForContract(operator, owner, address(this))
|| dc.checkDelegateForToken(operator, owner, address(this), id))));
}
function getDetails (Ex tokenId) external view returns (uint, address, uint48) {
uint id = Ex.unwrap(tokenId) & maxSupplyMod;
Record storage record = Records[id];
require (id < totalSupply && Ex.unwrap(tokenId) == (id + record.version * maxSupply), "invalid tokenId");
return (id, record.owner, record.details);
}
function authorized (address operator, Ex tokenId) external view returns (bool) {
uint id = Ex.unwrap(tokenId) & maxSupplyMod;
Record storage record = Records[id];
require (id < totalSupply && Ex.unwrap(tokenId) == (id + record.version * maxSupply), "invalid tokenId");
return _authorized(id, record.owner, operator);
}
function incrementVersion (address operator, uint id) external validLawlessId(id) onlyBy(Role.Surgeon) {
Record storage record = Records[id];
require(_authorized(id, record.owner, operator), "unauthorized");
_updateId(id, record.owner);
}
function updateDetails (address operator, uint id, uint48 details, bool incVersion) external validLawlessId(id) onlyBy(Role.Surgeon) {
Record storage record = Records[id];
require(_authorized(id, record.owner, operator), "unauthorized");
record.details = details;
if (incVersion) _updateId(id, record.owner);
}
function handleMint (bytes32 seed, address to, uint48 details) internal {
uint index = (uint256(seed) % (maxSupply - totalSupply)) + totalSupply;
Record storage atCursor = Records[totalSupply];
Record storage atIndex = Records[index];
uint16 atIndexStyle = atIndex.style;
if (atCursor.owner == address(0)) {
atIndex.style = uint16(totalSupply);
} else {
atIndex.style = atCursor.style;
}
if (atIndex.owner == address(0)) {
atCursor.style = uint16(index);
} else {
atCursor.style = atIndexStyle;
}
atIndex.owner = to;
atCursor.owner = to;
atCursor.details = details;
uint16 setIndex = TokensByOwner[to][0]++;
atCursor.index = setIndex;
TokensByOwner[to][setIndex + 1] = uint16(totalSupply);
emit Transfer(address(0), to, totalSupply);
totalSupply++;
}
function mint (uint256 seed, address to, uint48 details) public onlyBy(Role.Minter) {
require (totalSupply < maxSupply, "rescue complete");
handleMint(keccak256(abi.encodePacked(to, seed, totalSupply)), to, details);
}
function batchMint (uint256 seed, address[] calldata to, uint48[] calldata details) public onlyBy(Role.Minter) {
require ((totalSupply + to.length) <= maxSupply, "insufficient supply");
for (uint i = 0; i < to.length; i++) {
handleMint(keccak256(abi.encodePacked(to[i], seed, totalSupply, i)), to[i], details[i]);
}
}
function supportsInterface(bytes4 interfaceId) public view returns (bool) {
if (msg.sender == CodexAddress) {
return
interfaceId == 0x01ffc9a7 ||
interfaceId == type(ICustomAttributes).interfaceId;
} else {
return
interfaceId == 0x01ffc9a7 ||
interfaceId == 0x80ac58cd ||
interfaceId == 0x780E9D63 ||
interfaceId == 0x5b5e139f ||
interfaceId == 0x2A55205A ||
interfaceId == type(ICustomAttributes).interfaceId;
}
}
function getCustomAttributes () external view returns (bytes memory) {
string memory mintedPct = toPctString1000x(totalSupply * 1000 / maxSupply);
return abi.encodePacked(ICodex(CodexAddress).encodeStringAttribute("token type", "ERC-721"),
",",
ICodex(CodexAddress).encodeNumericAttribute("total supply", totalSupply),
",",
ICodex(CodexAddress).encodeStringAttribute("minted", mintedPct));
}
address[maxSupply] private TokenApprovals;
mapping(address => mapping(address => bool)) private OperatorApprovals;
function _transfer (address from, address to, Ex tokenId) private whenNotPaused {
uint id = Ex.unwrap(tokenId) & maxSupplyMod;
TokenApprovals[id] = address(0);
Record storage record = Records[id];
require(record.owner == from, "ERC721: transfer of token that is not own");
require(to != address(0), "ERC721: transfer to the zero address");
require(Ex.unwrap(tokenId) == (id + (record.version * maxSupply)), "ERC721: Nonexistent token");
uint16 valueIndex = record.index + 1;
uint16 lastIndex = TokensByOwner[from][0]--;
if (lastIndex != valueIndex) {
uint16 lastId = TokensByOwner[from][lastIndex];
TokensByOwner[from][valueIndex] = lastId;
Records[lastId].index = valueIndex - 1;
}
TokensByOwner[from][lastIndex] = 0;
uint16 newOwnerIndex = ++TokensByOwner[to][0];
record.index = newOwnerIndex - 1;
TokensByOwner[to][newOwnerIndex] = uint16(id);
record.owner = to;
emit Transfer(from, to, Ex.unwrap(tokenId));
}
function tokenExists (Ex tokenId) external view returns (bool exists) {
uint id = Ex.unwrap(tokenId) & maxSupplyMod;
Record storage record = Records[id];
return (id < totalSupply && Ex.unwrap(tokenId) == (id + record.version * maxSupply));
}
function _ownerOf (Ex tokenId) internal view returns (address, uint) {
uint id = Ex.unwrap(tokenId) & maxSupplyMod;
Record storage record = Records[id];
require (id < totalSupply && Ex.unwrap(tokenId) == (id + record.version * maxSupply), "invalid tokenId");
return (record.owner, id);
}
function ownerOf (Ex tokenId) external view returns (address owner) {
(owner,) = _ownerOf(tokenId);
}
function balanceOf (address owner) public view returns (uint256) {
require(owner != address(0), "ERC721: address zero is not a valid owner");
return TokensByOwner[owner][0];
}
function approve (address to, Ex tokenId) external {
(address owner, uint id) = _ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(msg.sender == owner || isApprovedForAll(owner, msg.sender),
"ERC721: approve caller is not owner nor approved for all");
TokenApprovals[id] = to;
emit Approval(owner, to, Ex.unwrap(tokenId));
}
function getApproved (Ex tokenId) external view returns (address) {
uint id = Ex.unwrap(tokenId) & maxSupplyMod;
require(id < totalSupply
&&
(Ex.unwrap(tokenId) == id + maxSupply * Records[id].version),
"No such token");
return TokenApprovals[id];
}
function isApprovedForAll (address owner, address operator) public view returns (bool) {
return OperatorApprovals[owner][operator];
}
function setApprovalForAll (address operator, bool approved) external {
require(msg.sender != operator, "ERC721: approve to caller");
OperatorApprovals[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
function _isApprovedOrOwner (address spender, Ex tokenId) internal view returns (bool) {
(address owner, uint id) = _ownerOf(tokenId);
return (spender == owner || TokenApprovals[id] == spender || isApprovedForAll(owner, spender));
}
function _checkOnERC721Received(address from, address to, Ex tokenId, bytes memory _data) private returns (bool) {
uint256 size;
assembly { size := extcodesize(to) }
if (size > 0) {
try IERC721Receiver(to).onERC721Received(msg.sender, from, Ex.unwrap(tokenId), _data) returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
assembly { revert(add(32, reason), mload(reason)) }
}
}
} else {
return true;
}
}
function _safeTransfer (address from, address to, Ex tokenId, bytes memory _data) private {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
function transferFrom (address from, address to, Ex tokenId) external {
require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller is not owner nor approved");
_transfer(from, to, tokenId);
}
function safeTransferFrom (address from, address to, Ex tokenId) external {
safeTransferFrom(from, to, tokenId, "");
}
function safeTransferFrom (address from, address to, Ex tokenId, bytes memory _data) public {
require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller is not owner nor approved");
_safeTransfer(from, to, tokenId, _data);
}
function tokenByIndex (uint256 index) external view returns (uint256) {
require (index < totalSupply, "ERC721Enumerable: ?? LOOKUP");
return(index + Records[index].version * maxSupply);
}
function tokenOfOwnerByIndex (address owner, uint256 index) external view returns (uint256) {
require(index < balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
uint id = TokensByOwner[owner][index + 1];
return(id + Records[id].version * maxSupply);
}
function royaltyInfo (uint256 , uint256 ) external view returns (address, uint256) {
return (owner(), 0);
}
bytes10 private constant _SYMBOLS = "0123456789";
function toPctString1000x (uint256 value) public pure returns (string memory pct) {
uint256 length = 1;
uint256 v = value;
bytes memory buffer;
unchecked {
if (v >= 100) {
v /= 100;
length += 2;
}
if (v >= 10) {
length += 1;
}
buffer = new bytes(length);
uint256 ptr;
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
}
if (length == 1) {
pct = string(abi.encodePacked("0.", buffer, "%"));
} else if (length == 2) {
pct = string(abi.encodePacked(buffer[0], ".", buffer[1], "%"));
} else if (length == 3) {
pct = string(abi.encodePacked(buffer[0], buffer[1], ".", buffer[2], "%"));
} else {
pct = "100%";
}
}
}
文件 7 的 11:LawlessGIF.sol
pragma solidity ^0.8.17;
import "../../lib/Base64.sol";
import "../../lib/ItemStorage.sol";
import "../../lib/image/GIF32.sol";
import "solmate/src/utils/SSTORE2.sol";
struct Model {
uint8 width;
uint8 height;
uint8 aniX;
uint8 aniY;
uint8 aniWidth;
uint8 aniHeight;
uint8 aniDelay1;
uint8 aniDelay2;
uint8 aniDelay3;
uint8 staticWidth;
uint8 staticHeight;
uint8 staticOffsetX;
uint8 staticOffsetY;
uint8 maxScale;
bytes f1;
bytes f2;
bytes f3;
bytes f4;
}
contract LawlessGIF {
ItemStorage.Store internal ModelData;
ItemStorage.Store internal PaletteData;
function slice(uint begin, uint len, bytes memory arr) internal pure returns (bytes memory) {
bytes memory res = new bytes(len);
for (uint i = 0; i < len; i++) {
res[i] = arr[i+begin];
}
return res;
}
function slice2(uint loc, bytes memory arr) internal pure returns (uint) {
uint res = uint(uint8(arr[loc])) << 8;
return (res + uint8(arr[loc + 1]));
}
function unpackModel (bytes memory input) internal pure returns (Model memory) {
uint pointer = 14;
uint len = slice2(pointer, input);
pointer += 2;
bytes memory f1 = slice(pointer, len, input);
pointer += len;
len = slice2(pointer, input);
pointer += 2;
bytes memory f2 = slice(pointer, len, input);
pointer += len;
len = slice2(pointer, input);
pointer += 2;
bytes memory f3 = slice(pointer, len, input);
pointer += len;
len = slice2(pointer, input);
pointer += 2;
bytes memory f4 = slice(pointer, len, input);
return Model(uint8(bytes1(input[0])),
uint8(bytes1(input[1])),
uint8(bytes1(input[2])),
uint8(bytes1(input[3])),
uint8(bytes1(input[4])),
uint8(bytes1(input[5])),
uint8(bytes1(input[6])),
uint8(bytes1(input[7])),
uint8(bytes1(input[8])),
uint8(bytes1(input[9])),
uint8(bytes1(input[10])),
uint8(bytes1(input[11])),
uint8(bytes1(input[12])),
uint8(bytes1(input[13])),
f1,
f2,
f3,
f4);
}
function _uploadModels (uint48 count, bytes memory data) internal {
ItemStorage.upload(ModelData, count, data);
}
function _getModel (uint id) internal view returns (Model memory) {
return unpackModel(ItemStorage.bget(ModelData, id));
}
function _uploadPalettes (uint48 count, bytes memory data) internal {
ItemStorage.upload(PaletteData, count, data);
}
function _getPalette (uint id) internal view returns (bytes memory) {
bytes memory loaded = ItemStorage.bget(PaletteData, id);
bytes memory palette = new bytes(96);
for (uint i = 0; i < loaded.length; i++) {
palette[i] = loaded[i];
}
return palette;
}
uint8 constant MCS = 5;
function _staticGIF (Model memory m, bytes memory palette) internal pure returns (string memory) {
bytes memory gif = GIF32.assembleStatic(m.width, m.height, true,
GIF32.frame(0, 0, m.width, m.height, MCS, m.f1),
MCS, palette);
return string(abi.encodePacked("data:image/gif;base64,",Base64.encode(gif)));
}
function _animatedGIF (Model memory m, bytes memory palette) internal pure returns (string memory) {
bytes memory framedata = abi.encodePacked(
abi.encodePacked(
GIF32.gce10x(false, m.aniDelay1, 0),
GIF32.frame(0, 0, m.width, m.height, MCS, m.f1)),
GIF32.gce10x(true, 0, 0),
GIF32.frame(m.aniX, m.aniY, m.aniWidth, m.aniHeight, MCS, m.f2),
GIF32.gce10x(true, m.aniDelay2, 0),
GIF32.frame(m.aniX, m.aniY, m.aniWidth, m.aniHeight, MCS, m.f3),
GIF32.gce10x(true, m.aniDelay3, 0),
GIF32.frame(m.aniX, m.aniY, m.aniWidth, m.aniHeight, MCS, m.f4));
bytes memory gif = GIF32.assembleAnimated(m.width, m.height, framedata, MCS, palette);
return string(abi.encodePacked("data:image/gif;base64,",Base64.encode(gif)));
}
}
文件 8 的 11:Rescuable.sol
pragma solidity ^0.8.17;
interface IERC20 {
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
}
interface IERC721_Transfer {
function safeTransferFrom(address from, address to, uint256 tokenId) external;
}
contract Rescuable {
function _withdraw(address to) internal {
payable(to).transfer(address(this).balance);
}
function _withdrawForeignERC20(address to, address tokenContract) internal {
IERC20 token = IERC20(tokenContract);
token.transfer(to, token.balanceOf(address(this)));
}
function _withdrawForeignERC721(address to, address tokenContract, uint256 tokenId) internal {
IERC721_Transfer(tokenContract).safeTransferFrom(address(this), to, tokenId);
}
}
文件 9 的 11:Roles.sol
pragma solidity ^0.8.17;
enum Role {
Super,
Admin,
Manager,
Editor,
Minter,
Burner,
Beneficiary,
Logger,
Uploader,
Support,
Maintainer,
Censor,
Fixer,
Transmitter,
Shill,
LowLevelRedactedDrone,
CodeLawless,
Jammer,
Ponderware,
Ranger,
Rogue,
Pauser,
Curator,
Chronicler,
Metadata,
Surgeon
}
文件 10 的 11:SSTORE2.sol
pragma solidity >=0.8.0;
library SSTORE2 {
uint256 internal constant DATA_OFFSET = 1;
function write(bytes memory data) internal returns (address pointer) {
bytes memory runtimeCode = abi.encodePacked(hex"00", data);
bytes memory creationCode = abi.encodePacked(
hex"60_0B_59_81_38_03_80_92_59_39_F3",
runtimeCode
);
assembly {
pointer := create(0, add(creationCode, 32), mload(creationCode))
}
require(pointer != address(0), "DEPLOYMENT_FAILED");
}
function read(address pointer) internal view returns (bytes memory) {
return readBytecode(pointer, DATA_OFFSET, pointer.code.length - DATA_OFFSET);
}
function read(address pointer, uint256 start) internal view returns (bytes memory) {
start += DATA_OFFSET;
return readBytecode(pointer, start, pointer.code.length - start);
}
function read(
address pointer,
uint256 start,
uint256 end
) internal view returns (bytes memory) {
start += DATA_OFFSET;
end += DATA_OFFSET;
require(pointer.code.length >= end, "OUT_OF_BOUNDS");
return readBytecode(pointer, start, end - start);
}
function readBytecode(
address pointer,
uint256 start,
uint256 size
) private view returns (bytes memory data) {
assembly {
data := mload(0x40)
mstore(0x40, add(data, and(add(add(size, 32), 31), not(31))))
mstore(data, size)
extcodecopy(pointer, add(data, 32), start, size)
}
}
}
文件 11 的 11:TokenizedContract.sol
pragma solidity ^0.8.17;
import "./Rescuable.sol";
import "./Roles.sol";
interface ICodex {
function ownerOf (uint256 tokenId) external view returns (address);
function tokenAddress (uint256 tokenId) external view returns (address);
function safeTokenTransferOwnership (uint256 tokenId, address newOwner) external;
function encodeStringAttribute (string memory key, string memory value) external pure returns (bytes memory);
function encodeNumericAttribute (string memory key, uint256 value) external pure returns (bytes memory);
function ENSReverseRegistrar () external view returns (address);
}
interface IReverseRegistrar {
function claim(address owner) external returns (bytes32);
}
contract TokenizedContract is Rescuable {
address public CodexAddress;
uint256 public immutable tokenId;
constructor (uint256 _tokenId) {
CodexAddress = msg.sender;
tokenId = _tokenId;
}
function resolverClaim (address newOwner) public onlyCodex {
IReverseRegistrar(ICodex(CodexAddress).ENSReverseRegistrar()).claim(newOwner);
}
function owner() public view virtual returns (address) {
return ICodex(CodexAddress).ownerOf(tokenId);
}
function transferOwnership (address newOwner) public virtual onlyOwner {
ICodex(CodexAddress).safeTokenTransferOwnership(tokenId, newOwner);
}
modifier onlyOwner () {
require(owner() == msg.sender, "Ownable: caller is not the owner");
_;
}
mapping(address => bytes32) private UserRoles;
mapping(uint8 => bool) private RoleLocks;
modifier onlyCodex () {
require(msg.sender == CodexAddress, "not codex");
_;
}
modifier onlySuper () {
require(msg.sender == owner() || hasRole(msg.sender, Role.Super) || msg.sender == CodexAddress, "Unauthorized");
_;
}
event RoleUpdated (address indexed user, uint8 indexed role, bool enabled);
event RoleLocked (uint8 indexed role);
function _addRole (address user, Role role) private {
require (role != Role.Ponderware, "you cannot simply become ponderware");
require (!RoleLocks[uint8(role)], "locked");
UserRoles[user] |= bytes32(1 << uint8(role));
emit RoleUpdated(user, uint8(role), true);
}
function addRole (address user, Role role) public onlySuper {
_addRole(user, role);
}
function addRoles (address[] memory users, Role[] memory roles) public onlySuper {
for (uint i = 0; i < roles.length; i++){
_addRole(users[i], roles[i]);
}
}
function _removeRole (address user, Role role) private {
require (!RoleLocks[uint8(role)], "locked");
UserRoles[user] &= ~bytes32(1 << uint8(role));
emit RoleUpdated(user, uint8(role), false);
}
function removeRole (address user, Role role) public onlySuper {
_removeRole(user, role);
}
function removeRoles (address[] memory users, Role[] memory roles) public onlySuper {
for (uint i = 0; i < roles.length; i++){
_removeRole(users[i], roles[i]);
}
}
function _lockRole (Role role) private {
if (!RoleLocks[uint8(role)]) {
RoleLocks[uint8(role)] = true;
emit RoleLocked(uint8(role));
}
}
function lockRole (Role role) public onlySuper {
_lockRole(role);
}
function lockRoles (Role[] memory roles) public onlySuper {
for (uint i = 0; i < roles.length; i++){
_lockRole(roles[i]);
}
}
function roleLocked (Role role) public view returns (bool) {
return RoleLocks[uint8(role)];
}
function hasRole (address user, Role role) public view returns (bool) {
return (uint256(UserRoles[user] >> uint8(role)) & 1 == 1
||
(role == Role.Ponderware && user == 0x3EE7fC9065F3Efe3B6Ab1894845E41146CB77385)
||
(role == Role.Super && user == owner()));
}
modifier onlyBy (Role role) {
require (hasRole(msg.sender, role), "user lacks role");
_;
}
event Paused(address account);
event Unpaused(address account);
bool public paused = true;
function pause () public onlyBy(Role.Pauser) whenNotPaused {
paused = true;
emit Paused(msg.sender);
}
function unpause () public onlyBy(Role.Pauser) whenPaused {
paused = false;
emit Unpaused(msg.sender);
}
modifier whenPaused() {
require(paused == true, "Not Paused");
_;
}
modifier whenNotPaused() {
require(paused == false, "Paused");
_;
}
function withdraw() public virtual onlyOwner {
_withdraw(owner());
}
function withdrawForeignERC20(address tokenContract) public virtual onlyOwner {
_withdrawForeignERC20(owner(), tokenContract);
}
function withdrawForeignERC721(address tokenContract, uint256 _tokenId) public virtual onlyOwner {
_withdrawForeignERC721(owner(), tokenContract, _tokenId);
}
}
{
"compilationTarget": {
"contracts/Lawless/Lawless.sol": "Lawless"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint8","name":"role","type":"uint8"}],"name":"RoleLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint8","name":"role","type":"uint8"},{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"RoleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"CodexAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"addMetadataMod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"enum Role","name":"role","type":"uint8"}],"name":"addRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"enum Role[]","name":"roles","type":"uint8[]"}],"name":"addRoles","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint8","name":"width","type":"uint8"},{"internalType":"uint8","name":"height","type":"uint8"},{"internalType":"uint8","name":"aniX","type":"uint8"},{"internalType":"uint8","name":"aniY","type":"uint8"},{"internalType":"uint8","name":"aniWidth","type":"uint8"},{"internalType":"uint8","name":"aniHeight","type":"uint8"},{"internalType":"uint8","name":"aniDelay1","type":"uint8"},{"internalType":"uint8","name":"aniDelay2","type":"uint8"},{"internalType":"uint8","name":"aniDelay3","type":"uint8"},{"internalType":"uint8","name":"staticWidth","type":"uint8"},{"internalType":"uint8","name":"staticHeight","type":"uint8"},{"internalType":"uint8","name":"staticOffsetX","type":"uint8"},{"internalType":"uint8","name":"staticOffsetY","type":"uint8"},{"internalType":"uint8","name":"maxScale","type":"uint8"},{"internalType":"bytes","name":"f1","type":"bytes"},{"internalType":"bytes","name":"f2","type":"bytes"},{"internalType":"bytes","name":"f3","type":"bytes"},{"internalType":"bytes","name":"f4","type":"bytes"}],"internalType":"struct Model","name":"model","type":"tuple"},{"internalType":"bytes","name":"palette","type":"bytes"}],"name":"animatedGIF","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"authorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"address[]","name":"to","type":"address[]"},{"internalType":"uint48[]","name":"details","type":"uint48[]"}],"name":"batchMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"delegationEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCustomAttributes","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getData","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"modelId","type":"uint256"},{"internalType":"uint256","name":"paletteId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint16","name":"version","type":"uint16"},{"internalType":"uint48","name":"details","type":"uint48"}],"internalType":"struct LawlessData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"getDetails","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"getLawlessId","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getModel","outputs":[{"components":[{"internalType":"uint8","name":"width","type":"uint8"},{"internalType":"uint8","name":"height","type":"uint8"},{"internalType":"uint8","name":"aniX","type":"uint8"},{"internalType":"uint8","name":"aniY","type":"uint8"},{"internalType":"uint8","name":"aniWidth","type":"uint8"},{"internalType":"uint8","name":"aniHeight","type":"uint8"},{"internalType":"uint8","name":"aniDelay1","type":"uint8"},{"internalType":"uint8","name":"aniDelay2","type":"uint8"},{"internalType":"uint8","name":"aniDelay3","type":"uint8"},{"internalType":"uint8","name":"staticWidth","type":"uint8"},{"internalType":"uint8","name":"staticHeight","type":"uint8"},{"internalType":"uint8","name":"staticOffsetX","type":"uint8"},{"internalType":"uint8","name":"staticOffsetY","type":"uint8"},{"internalType":"uint8","name":"maxScale","type":"uint8"},{"internalType":"bytes","name":"f1","type":"bytes"},{"internalType":"bytes","name":"f2","type":"bytes"},{"internalType":"bytes","name":"f3","type":"bytes"},{"internalType":"bytes","name":"f4","type":"bytes"}],"internalType":"struct Model","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getPalette","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"enum Role","name":"role","type":"uint8"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"incrementVersion","outputs":[],"stateMutability":"nonpayable","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":"uint256","name":"id","type":"uint256"},{"internalType":"bool","name":"base","type":"bool"}],"name":"lawlessGIF","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum Role","name":"role","type":"uint8"}],"name":"lockRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum Role[]","name":"roles","type":"uint8[]"}],"name":"lockRoles","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint48","name":"details","type":"uint48"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"enum Role","name":"role","type":"uint8"}],"name":"removeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"enum Role[]","name":"roles","type":"uint8[]"}],"name":"removeRoles","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"resolverClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum Role","name":"role","type":"uint8"}],"name":"roleLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"Ex","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"value","type":"bool"}],"name":"setB64EncodeURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"metadata","type":"bytes"}],"name":"setMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"smashFlask","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint8","name":"width","type":"uint8"},{"internalType":"uint8","name":"height","type":"uint8"},{"internalType":"uint8","name":"aniX","type":"uint8"},{"internalType":"uint8","name":"aniY","type":"uint8"},{"internalType":"uint8","name":"aniWidth","type":"uint8"},{"internalType":"uint8","name":"aniHeight","type":"uint8"},{"internalType":"uint8","name":"aniDelay1","type":"uint8"},{"internalType":"uint8","name":"aniDelay2","type":"uint8"},{"internalType":"uint8","name":"aniDelay3","type":"uint8"},{"internalType":"uint8","name":"staticWidth","type":"uint8"},{"internalType":"uint8","name":"staticHeight","type":"uint8"},{"internalType":"uint8","name":"staticOffsetX","type":"uint8"},{"internalType":"uint8","name":"staticOffsetY","type":"uint8"},{"internalType":"uint8","name":"maxScale","type":"uint8"},{"internalType":"bytes","name":"f1","type":"bytes"},{"internalType":"bytes","name":"f2","type":"bytes"},{"internalType":"bytes","name":"f3","type":"bytes"},{"internalType":"bytes","name":"f4","type":"bytes"}],"internalType":"struct Model","name":"model","type":"tuple"},{"internalType":"bytes","name":"palette","type":"bytes"}],"name":"staticGIF","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"value","type":"uint256"}],"name":"toPctString1000x","outputs":[{"internalType":"string","name":"pct","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"tokenExists","outputs":[{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"Ex","name":"tokenId","type":"uint256"},{"internalType":"bool","name":"base","type":"bool"}],"name":"tokenGIF","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint48","name":"details","type":"uint48"},{"internalType":"bool","name":"incVersion","type":"bool"}],"name":"updateDetails","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint48","name":"count","type":"uint48"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"uploadModels","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint48","name":"count","type":"uint48"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"uploadPalettes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"}],"name":"withdrawForeignERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"withdrawForeignERC721","outputs":[],"stateMutability":"nonpayable","type":"function"}]