This contract's source code is verified! Compiler
0.8.18+commit.87f61d96
File 1 of 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);
}
}
File 2 of 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 )
}
}
}
File 3 of 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));
}
}
File 4 of 11: IERC721Receiver.sol
pragma solidity ^0.8.0;
interface IERC721Receiver {
function onERC721Received (
address operator,
address from ,
uint256 tokenId,
bytes calldata data
) external returns (bytes4 ) ;
}
File 5 of 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);
}
}
File 6 of 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%" ;
}
}
}
File 7 of 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)));
}
}
File 8 of 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);
}
}
File 9 of 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
}
File 10 of 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)
}
}
}
File 11 of 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"}]