Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 12 internal transactions
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
20085843 | 244 days ago | Contract Creation | 0 ETH | |||
19835442 | 279 days ago | Contract Creation | 0 ETH | |||
17871749 | 554 days ago | Contract Creation | 0 ETH | |||
17871749 | 554 days ago | Contract Creation | 0 ETH | |||
15302872 | 919 days ago | Contract Creation | 0 ETH | |||
15302872 | 919 days ago | Contract Creation | 0 ETH | |||
15302872 | 919 days ago | Contract Creation | 0 ETH | |||
15141364 | 944 days ago | Contract Creation | 0 ETH | |||
15141362 | 944 days ago | Contract Creation | 0 ETH | |||
15141362 | 944 days ago | Contract Creation | 0 ETH | |||
15141362 | 944 days ago | Contract Creation | 0 ETH | |||
15141362 | 944 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
NounsArt
Compiler Version
v0.8.15+commit.e14f2714
Optimization Enabled:
Yes with 10000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0 /// @title The Nouns art storage contract /********************************* * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░█████████░░█████████░░░ * * ░░░░░░██░░░████░░██░░░████░░░ * * ░░██████░░░████████░░░████░░░ * * ░░██░░██░░░████░░██░░░████░░░ * * ░░██░░██░░░████░░██░░░████░░░ * * ░░░░░░█████████░░█████████░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ pragma solidity ^0.8.6; import { INounsArt } from './interfaces/INounsArt.sol'; import { SSTORE2 } from './libs/SSTORE2.sol'; import { IInflator } from './interfaces/IInflator.sol'; contract NounsArt is INounsArt { /// @notice Current Nouns Descriptor address address public override descriptor; /// @notice Current inflator address IInflator public override inflator; /// @notice Noun Backgrounds (Hex Colors) string[] public override backgrounds; /// @notice Noun Color Palettes (Index => Hex Colors, stored as a contract using SSTORE2) mapping(uint8 => address) public palettesPointers; /// @notice Noun Bodies Trait Trait public bodiesTrait; /// @notice Noun Accessories Trait Trait public accessoriesTrait; /// @notice Noun Heads Trait Trait public headsTrait; /// @notice Noun Glasses Trait Trait public glassesTrait; /** * @notice Require that the sender is the descriptor. */ modifier onlyDescriptor() { if (msg.sender != descriptor) { revert SenderIsNotDescriptor(); } _; } constructor(address _descriptor, IInflator _inflator) { descriptor = _descriptor; inflator = _inflator; } /** * @notice Set the descriptor. * @dev This function can only be called by the current descriptor. */ function setDescriptor(address _descriptor) external override onlyDescriptor { address oldDescriptor = descriptor; descriptor = _descriptor; emit DescriptorUpdated(oldDescriptor, descriptor); } /** * @notice Set the inflator. * @dev This function can only be called by the descriptor. */ function setInflator(IInflator _inflator) external override onlyDescriptor { address oldInflator = address(inflator); inflator = _inflator; emit InflatorUpdated(oldInflator, address(_inflator)); } /** * @notice Get the Trait struct for bodies. * @dev This explicit getter is needed because implicit getters for structs aren't fully supported yet: * https://github.com/ethereum/solidity/issues/11826 * @return Trait the struct, including a total image count, and an array of storage pages. */ function getBodiesTrait() external view override returns (Trait memory) { return bodiesTrait; } /** * @notice Get the Trait struct for accessories. * @dev This explicit getter is needed because implicit getters for structs aren't fully supported yet: * https://github.com/ethereum/solidity/issues/11826 * @return Trait the struct, including a total image count, and an array of storage pages. */ function getAccessoriesTrait() external view override returns (Trait memory) { return accessoriesTrait; } /** * @notice Get the Trait struct for heads. * @dev This explicit getter is needed because implicit getters for structs aren't fully supported yet: * https://github.com/ethereum/solidity/issues/11826 * @return Trait the struct, including a total image count, and an array of storage pages. */ function getHeadsTrait() external view override returns (Trait memory) { return headsTrait; } /** * @notice Get the Trait struct for glasses. * @dev This explicit getter is needed because implicit getters for structs aren't fully supported yet: * https://github.com/ethereum/solidity/issues/11826 * @return Trait the struct, including a total image count, and an array of storage pages. */ function getGlassesTrait() external view override returns (Trait memory) { return glassesTrait; } /** * @notice Batch add Noun backgrounds. * @dev This function can only be called by the descriptor. */ function addManyBackgrounds(string[] calldata _backgrounds) external override onlyDescriptor { for (uint256 i = 0; i < _backgrounds.length; i++) { _addBackground(_backgrounds[i]); } emit BackgroundsAdded(_backgrounds.length); } /** * @notice Add a Noun background. * @dev This function can only be called by the descriptor. */ function addBackground(string calldata _background) external override onlyDescriptor { _addBackground(_background); emit BackgroundsAdded(1); } /** * @notice Update a single color palette. This function can be used to * add a new color palette or update an existing palette. * @param paletteIndex the identifier of this palette * @param palette byte array of colors. every 3 bytes represent an RGB color. max length: 256 * 3 = 768 * @dev This function can only be called by the descriptor. */ function setPalette(uint8 paletteIndex, bytes calldata palette) external override onlyDescriptor { if (palette.length == 0) { revert EmptyPalette(); } if (palette.length % 3 != 0 || palette.length > 768) { revert BadPaletteLength(); } palettesPointers[paletteIndex] = SSTORE2.write(palette); emit PaletteSet(paletteIndex); } /** * @notice Add a batch of body images. * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, * and finally compressing it using deflate. * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. * @param imageCount the number of images in this batch; used when searching for images among batches. * @dev This function can only be called by the descriptor. */ function addBodies( bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { addPage(bodiesTrait, encodedCompressed, decompressedLength, imageCount); emit BodiesAdded(imageCount); } /** * @notice Add a batch of accessory images. * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, * and finally compressing it using deflate. * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. * @param imageCount the number of images in this batch; used when searching for images among batches. * @dev This function can only be called by the descriptor. */ function addAccessories( bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { addPage(accessoriesTrait, encodedCompressed, decompressedLength, imageCount); emit AccessoriesAdded(imageCount); } /** * @notice Add a batch of head images. * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, * and finally compressing it using deflate. * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. * @param imageCount the number of images in this batch; used when searching for images among batches. * @dev This function can only be called by the descriptor. */ function addHeads( bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { addPage(headsTrait, encodedCompressed, decompressedLength, imageCount); emit HeadsAdded(imageCount); } /** * @notice Add a batch of glasses images. * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, * and finally compressing it using deflate. * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. * @param imageCount the number of images in this batch; used when searching for images among batches. * @dev This function can only be called by the descriptor. */ function addGlasses( bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { addPage(glassesTrait, encodedCompressed, decompressedLength, imageCount); emit GlassesAdded(imageCount); } /** * @notice Update a single color palette. This function can be used to * add a new color palette or update an existing palette. This function does not check for data length validity * (len <= 768, len % 3 == 0). * @param paletteIndex the identifier of this palette * @param pointer the address of the contract holding the palette bytes. every 3 bytes represent an RGB color. * max length: 256 * 3 = 768. * @dev This function can only be called by the descriptor. */ function setPalettePointer(uint8 paletteIndex, address pointer) external override onlyDescriptor { palettesPointers[paletteIndex] = pointer; emit PaletteSet(paletteIndex); } /** * @notice Add a batch of body images from an existing storage contract. * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data * format is expected to be like {encodedCompressed}: bytes created by taking a string array of * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. * @param imageCount the number of images in this batch; used when searching for images among batches. * @dev This function can only be called by the descriptor. */ function addBodiesFromPointer( address pointer, uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { addPage(bodiesTrait, pointer, decompressedLength, imageCount); emit BodiesAdded(imageCount); } /** * @notice Add a batch of accessory images from an existing storage contract. * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data * format is expected to be like {encodedCompressed}: bytes created by taking a string array of * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. * @param imageCount the number of images in this batch; used when searching for images among batches. * @dev This function can only be called by the descriptor. */ function addAccessoriesFromPointer( address pointer, uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { addPage(accessoriesTrait, pointer, decompressedLength, imageCount); emit AccessoriesAdded(imageCount); } /** * @notice Add a batch of head images from an existing storage contract. * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data * format is expected to be like {encodedCompressed}: bytes created by taking a string array of * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. * @param imageCount the number of images in this batch; used when searching for images among batches * @dev This function can only be called by the descriptor.. */ function addHeadsFromPointer( address pointer, uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { addPage(headsTrait, pointer, decompressedLength, imageCount); emit HeadsAdded(imageCount); } /** * @notice Add a batch of glasses images from an existing storage contract. * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data * format is expected to be like {encodedCompressed}: bytes created by taking a string array of * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. * @param imageCount the number of images in this batch; used when searching for images among batches. * @dev This function can only be called by the descriptor. */ function addGlassesFromPointer( address pointer, uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { addPage(glassesTrait, pointer, decompressedLength, imageCount); emit GlassesAdded(imageCount); } /** * @notice Get the number of available Noun `backgrounds`. */ function backgroundsCount() public view override returns (uint256) { return backgrounds.length; } /** * @notice Get a head image bytes (RLE-encoded). */ function heads(uint256 index) public view override returns (bytes memory) { return imageByIndex(headsTrait, index); } /** * @notice Get a body image bytes (RLE-encoded). */ function bodies(uint256 index) public view override returns (bytes memory) { return imageByIndex(bodiesTrait, index); } /** * @notice Get a accessory image bytes (RLE-encoded). */ function accessories(uint256 index) public view override returns (bytes memory) { return imageByIndex(accessoriesTrait, index); } /** * @notice Get a glasses image bytes (RLE-encoded). */ function glasses(uint256 index) public view override returns (bytes memory) { return imageByIndex(glassesTrait, index); } /** * @notice Get a color palette bytes. */ function palettes(uint8 paletteIndex) public view override returns (bytes memory) { address pointer = palettesPointers[paletteIndex]; if (pointer == address(0)) { revert PaletteNotFound(); } return SSTORE2.read(palettesPointers[paletteIndex]); } function _addBackground(string calldata _background) internal { backgrounds.push(_background); } function addPage( Trait storage trait, bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) internal { if (encodedCompressed.length == 0) { revert EmptyBytes(); } address pointer = SSTORE2.write(encodedCompressed); addPage(trait, pointer, decompressedLength, imageCount); } function addPage( Trait storage trait, address pointer, uint80 decompressedLength, uint16 imageCount ) internal { if (decompressedLength == 0) { revert BadDecompressedLength(); } if (imageCount == 0) { revert BadImageCount(); } trait.storagePages.push( NounArtStoragePage({ pointer: pointer, decompressedLength: decompressedLength, imageCount: imageCount }) ); trait.storedImagesCount += imageCount; } function imageByIndex(INounsArt.Trait storage trait, uint256 index) internal view returns (bytes memory) { (INounsArt.NounArtStoragePage storage page, uint256 indexInPage) = getPage(trait.storagePages, index); bytes[] memory decompressedImages = decompressAndDecode(page); return decompressedImages[indexInPage]; } /** * @dev Given an image index, this function finds the storage page the image is in, and the relative index * inside the page, so the image can be read from storage. * Example: if you have 2 pages with 100 images each, and you want to get image 150, this function would return * the 2nd page, and the 50th index. * @return INounsArt.NounArtStoragePage the page containing the image at index * @return uint256 the index of the image in the page */ function getPage(INounsArt.NounArtStoragePage[] storage pages, uint256 index) internal view returns (INounsArt.NounArtStoragePage storage, uint256) { uint256 len = pages.length; uint256 pageFirstImageIndex = 0; for (uint256 i = 0; i < len; i++) { INounsArt.NounArtStoragePage storage page = pages[i]; if (index < pageFirstImageIndex + page.imageCount) { return (page, index - pageFirstImageIndex); } pageFirstImageIndex += page.imageCount; } revert ImageNotFound(); } function decompressAndDecode(INounsArt.NounArtStoragePage storage page) internal view returns (bytes[] memory) { bytes memory compressedData = SSTORE2.read(page.pointer); (, bytes memory decompressedData) = inflator.puff(compressedData, page.decompressedLength); return abi.decode(decompressedData, (bytes[])); } }
// SPDX-License-Identifier: GPL-3.0 /// @title Interface for NounsArt /********************************* * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░█████████░░█████████░░░ * * ░░░░░░██░░░████░░██░░░████░░░ * * ░░██████░░░████████░░░████░░░ * * ░░██░░██░░░████░░██░░░████░░░ * * ░░██░░██░░░████░░██░░░████░░░ * * ░░░░░░█████████░░█████████░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ pragma solidity ^0.8.6; import { Inflate } from '../libs/Inflate.sol'; import { IInflator } from './IInflator.sol'; interface INounsArt { error SenderIsNotDescriptor(); error EmptyPalette(); error BadPaletteLength(); error EmptyBytes(); error BadDecompressedLength(); error BadImageCount(); error ImageNotFound(); error PaletteNotFound(); event DescriptorUpdated(address oldDescriptor, address newDescriptor); event InflatorUpdated(address oldInflator, address newInflator); event BackgroundsAdded(uint256 count); event PaletteSet(uint8 paletteIndex); event BodiesAdded(uint16 count); event AccessoriesAdded(uint16 count); event HeadsAdded(uint16 count); event GlassesAdded(uint16 count); struct NounArtStoragePage { uint16 imageCount; uint80 decompressedLength; address pointer; } struct Trait { NounArtStoragePage[] storagePages; uint256 storedImagesCount; } function descriptor() external view returns (address); function inflator() external view returns (IInflator); function setDescriptor(address descriptor) external; function setInflator(IInflator inflator) external; function addManyBackgrounds(string[] calldata _backgrounds) external; function addBackground(string calldata _background) external; function palettes(uint8 paletteIndex) external view returns (bytes memory); function setPalette(uint8 paletteIndex, bytes calldata palette) external; function addBodies( bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) external; function addAccessories( bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) external; function addHeads( bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) external; function addGlasses( bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) external; function addBodiesFromPointer( address pointer, uint80 decompressedLength, uint16 imageCount ) external; function setPalettePointer(uint8 paletteIndex, address pointer) external; function addAccessoriesFromPointer( address pointer, uint80 decompressedLength, uint16 imageCount ) external; function addHeadsFromPointer( address pointer, uint80 decompressedLength, uint16 imageCount ) external; function addGlassesFromPointer( address pointer, uint80 decompressedLength, uint16 imageCount ) external; function backgroundsCount() external view returns (uint256); function backgrounds(uint256 index) external view returns (string memory); function heads(uint256 index) external view returns (bytes memory); function bodies(uint256 index) external view returns (bytes memory); function accessories(uint256 index) external view returns (bytes memory); function glasses(uint256 index) external view returns (bytes memory); function getBodiesTrait() external view returns (Trait memory); function getAccessoriesTrait() external view returns (Trait memory); function getHeadsTrait() external view returns (Trait memory); function getGlassesTrait() external view returns (Trait memory); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.6; /// @notice Read and write to persistent storage at a fraction of the cost. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SSTORE2.sol) /// @author Modified from 0xSequence (https://github.com/0xSequence/sstore2/blob/master/contracts/SSTORE2.sol) library SSTORE2 { uint256 internal constant DATA_OFFSET = 1; // We skip the first byte as it's a STOP opcode to ensure the contract can't be called. /*/////////////////////////////////////////////////////////////// WRITE LOGIC //////////////////////////////////////////////////////////////*/ function write(bytes memory data) internal returns (address pointer) { // Prefix the bytecode with a STOP opcode to ensure it cannot be called. bytes memory runtimeCode = abi.encodePacked(hex'00', data); bytes memory creationCode = abi.encodePacked( //---------------------------------------------------------------------------------------------------------------// // Opcode | Opcode + Arguments | Description | Stack View // //---------------------------------------------------------------------------------------------------------------// // 0x60 | 0x600B | PUSH1 11 | codeOffset // // 0x59 | 0x59 | MSIZE | 0 codeOffset // // 0x81 | 0x81 | DUP2 | codeOffset 0 codeOffset // // 0x38 | 0x38 | CODESIZE | codeSize codeOffset 0 codeOffset // // 0x03 | 0x03 | SUB | (codeSize - codeOffset) 0 codeOffset // // 0x80 | 0x80 | DUP | (codeSize - codeOffset) (codeSize - codeOffset) 0 codeOffset // // 0x92 | 0x92 | SWAP3 | codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) // // 0x59 | 0x59 | MSIZE | 0 codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) // // 0x39 | 0x39 | CODECOPY | 0 (codeSize - codeOffset) // // 0xf3 | 0xf3 | RETURN | // //---------------------------------------------------------------------------------------------------------------// hex'60_0B_59_81_38_03_80_92_59_39_F3', // Returns all code in the contract except for the first 11 (0B in hex) bytes. runtimeCode // The bytecode we want the contract to have after deployment. Capped at 1 byte less than the code size limit. ); assembly { // Deploy a new contract with the generated creation code. // We start 32 bytes into the code to avoid copying the byte length. pointer := create(0, add(creationCode, 32), mload(creationCode)) } require(pointer != address(0), 'DEPLOYMENT_FAILED'); } /*/////////////////////////////////////////////////////////////// READ LOGIC //////////////////////////////////////////////////////////////*/ 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); } /*/////////////////////////////////////////////////////////////// INTERNAL HELPER LOGIC //////////////////////////////////////////////////////////////*/ function readBytecode( address pointer, uint256 start, uint256 size ) private view returns (bytes memory data) { assembly { // Get a pointer to some free memory. data := mload(0x40) // Update the free memory pointer to prevent overriding our data. // We use and(x, not(31)) as a cheaper equivalent to sub(x, mod(x, 32)). // Adding 31 to size and running the result through the logic above ensures // the memory pointer remains word-aligned, following the Solidity convention. mstore(0x40, add(data, and(add(add(size, 32), 31), not(31)))) // Store the size of the data in the first 32 byte chunk of free memory. mstore(data, size) // Copy the code into memory right after the 32 bytes we used to store the size. extcodecopy(pointer, add(data, 32), start, size) } } }
// SPDX-License-Identifier: GPL-3.0 /// @title Interface for Inflator /********************************* * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░█████████░░█████████░░░ * * ░░░░░░██░░░████░░██░░░████░░░ * * ░░██████░░░████████░░░████░░░ * * ░░██░░██░░░████░░██░░░████░░░ * * ░░██░░██░░░████░░██░░░████░░░ * * ░░░░░░█████████░░█████████░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ pragma solidity ^0.8.6; import { Inflate } from '../libs/Inflate.sol'; interface IInflator { function puff(bytes memory source, uint256 destlen) external pure returns (Inflate.ErrorCode, bytes memory); }
// SPDX-License-Identifier: Apache-2.0 pragma solidity >=0.8.0 <0.9.0; /// @notice Based on https://github.com/madler/zlib/blob/master/contrib/puff /// @dev Modified the original code for gas optimizations /// 1. Disable overflow/underflow checks /// 2. Chunk some loop iterations library Inflate { // Maximum bits in a code uint256 constant MAXBITS = 15; // Maximum number of literal/length codes uint256 constant MAXLCODES = 286; // Maximum number of distance codes uint256 constant MAXDCODES = 30; // Maximum codes lengths to read uint256 constant MAXCODES = (MAXLCODES + MAXDCODES); // Number of fixed literal/length codes uint256 constant FIXLCODES = 288; // Error codes enum ErrorCode { ERR_NONE, // 0 successful inflate ERR_NOT_TERMINATED, // 1 available inflate data did not terminate ERR_OUTPUT_EXHAUSTED, // 2 output space exhausted before completing inflate ERR_INVALID_BLOCK_TYPE, // 3 invalid block type (type == 3) ERR_STORED_LENGTH_NO_MATCH, // 4 stored block length did not match one's complement ERR_TOO_MANY_LENGTH_OR_DISTANCE_CODES, // 5 dynamic block code description: too many length or distance codes ERR_CODE_LENGTHS_CODES_INCOMPLETE, // 6 dynamic block code description: code lengths codes incomplete ERR_REPEAT_NO_FIRST_LENGTH, // 7 dynamic block code description: repeat lengths with no first length ERR_REPEAT_MORE, // 8 dynamic block code description: repeat more than specified lengths ERR_INVALID_LITERAL_LENGTH_CODE_LENGTHS, // 9 dynamic block code description: invalid literal/length code lengths ERR_INVALID_DISTANCE_CODE_LENGTHS, // 10 dynamic block code description: invalid distance code lengths ERR_MISSING_END_OF_BLOCK, // 11 dynamic block code description: missing end-of-block code ERR_INVALID_LENGTH_OR_DISTANCE_CODE, // 12 invalid literal/length or distance code in fixed or dynamic block ERR_DISTANCE_TOO_FAR, // 13 distance is too far back in fixed or dynamic block ERR_CONSTRUCT // 14 internal: error in construct() } // Input and output state struct State { ////////////////// // Output state // ////////////////// // Output buffer bytes output; // Bytes written to out so far uint256 outcnt; ///////////////// // Input state // ///////////////// // Input buffer bytes input; // Bytes read so far uint256 incnt; //////////////// // Temp state // //////////////// // Bit buffer uint256 bitbuf; // Number of bits in bit buffer uint256 bitcnt; ////////////////////////// // Static Huffman codes // ////////////////////////// Huffman lencode; Huffman distcode; } // Huffman code decoding tables struct Huffman { uint256[] counts; uint256[] symbols; } function bits(State memory s, uint256 need) private pure returns (ErrorCode, uint256) { unchecked { // Bit accumulator (can use up to 20 bits) uint256 val; // Load at least need bits into val val = s.bitbuf; while (s.bitcnt < need) { if (s.incnt == s.input.length) { // Out of input return (ErrorCode.ERR_NOT_TERMINATED, 0); } // Load eight bits val |= uint256(uint8(s.input[s.incnt++])) << s.bitcnt; s.bitcnt += 8; } // Drop need bits and update buffer, always zero to seven bits left s.bitbuf = val >> need; s.bitcnt -= need; // Return need bits, zeroing the bits above that uint256 ret = (val & ((1 << need) - 1)); return (ErrorCode.ERR_NONE, ret); } } function _stored(State memory s) private pure returns (ErrorCode) { unchecked { // Length of stored block uint256 len; // Discard leftover bits from current byte (assumes s.bitcnt < 8) s.bitbuf = 0; s.bitcnt = 0; // Get length and check against its one's complement if (s.incnt + 4 > s.input.length) { // Not enough input return ErrorCode.ERR_NOT_TERMINATED; } len = uint256(uint8(s.input[s.incnt++])); len |= uint256(uint8(s.input[s.incnt++])) << 8; if (uint8(s.input[s.incnt++]) != (~len & 0xFF) || uint8(s.input[s.incnt++]) != ((~len >> 8) & 0xFF)) { // Didn't match complement! return ErrorCode.ERR_STORED_LENGTH_NO_MATCH; } // Copy len bytes from in to out if (s.incnt + len > s.input.length) { // Not enough input return ErrorCode.ERR_NOT_TERMINATED; } if (s.outcnt + len > s.output.length) { // Not enough output space return ErrorCode.ERR_OUTPUT_EXHAUSTED; } while (len != 0) { // Note: Solidity reverts on underflow, so we decrement here len -= 1; s.output[s.outcnt++] = s.input[s.incnt++]; } // Done with a valid stored block return ErrorCode.ERR_NONE; } } function _decode(State memory s, Huffman memory h) private pure returns (ErrorCode, uint256) { unchecked { // Current number of bits in code uint256 len; // Len bits being decoded uint256 code = 0; // First code of length len uint256 first = 0; // Number of codes of length len uint256 count; // Index of first code of length len in symbol table uint256 index = 0; // Error code ErrorCode err; uint256 tempCode; for (len = 1; len <= MAXBITS; len += 5) { // Get next bit (err, tempCode) = bits(s, 1); if (err != ErrorCode.ERR_NONE) { return (err, 0); } code |= tempCode; count = h.counts[len]; // If length len, return symbol if (code < first + count) { return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); } // Else update for next length index += count; first += count; first <<= 1; code <<= 1; // Get next bit (err, tempCode) = bits(s, 1); if (err != ErrorCode.ERR_NONE) { return (err, 0); } code |= tempCode; count = h.counts[len + 1]; // If length len, return symbol if (code < first + count) { return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); } // Else update for next length index += count; first += count; first <<= 1; code <<= 1; // Get next bit (err, tempCode) = bits(s, 1); if (err != ErrorCode.ERR_NONE) { return (err, 0); } code |= tempCode; count = h.counts[len + 2]; // If length len, return symbol if (code < first + count) { return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); } // Else update for next length index += count; first += count; first <<= 1; code <<= 1; // Get next bit (err, tempCode) = bits(s, 1); if (err != ErrorCode.ERR_NONE) { return (err, 0); } code |= tempCode; count = h.counts[len + 3]; // If length len, return symbol if (code < first + count) { return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); } // Else update for next length index += count; first += count; first <<= 1; code <<= 1; // Get next bit (err, tempCode) = bits(s, 1); if (err != ErrorCode.ERR_NONE) { return (err, 0); } code |= tempCode; count = h.counts[len + 4]; // If length len, return symbol if (code < first + count) { return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); } // Else update for next length index += count; first += count; first <<= 1; code <<= 1; } // Ran out of codes return (ErrorCode.ERR_INVALID_LENGTH_OR_DISTANCE_CODE, 0); } } function _construct( Huffman memory h, uint256[] memory lengths, uint256 n, uint256 start ) private pure returns (ErrorCode) { unchecked { // Current symbol when stepping through lengths[] uint256 symbol; // Current length when stepping through h.counts[] uint256 len; // Number of possible codes left of current length uint256 left; // Offsets in symbol table for each length uint256[MAXBITS + 1] memory offs; // Count number of codes of each length for (len = 0; len <= MAXBITS; ++len) { h.counts[len] = 0; } for (symbol = 0; symbol < n; ++symbol) { // Assumes lengths are within bounds ++h.counts[lengths[start + symbol]]; } // No codes! if (h.counts[0] == n) { // Complete, but decode() will fail return (ErrorCode.ERR_NONE); } // Check for an over-subscribed or incomplete set of lengths // One possible code of zero length left = 1; for (len = 1; len <= MAXBITS; len += 5) { // One more bit, double codes left left <<= 1; if (left < h.counts[len]) { // Over-subscribed--return error return ErrorCode.ERR_CONSTRUCT; } // Deduct count from possible codes left -= h.counts[len]; // One more bit, double codes left left <<= 1; if (left < h.counts[len + 1]) { // Over-subscribed--return error return ErrorCode.ERR_CONSTRUCT; } // Deduct count from possible codes left -= h.counts[len + 1]; // One more bit, double codes left left <<= 1; if (left < h.counts[len + 2]) { // Over-subscribed--return error return ErrorCode.ERR_CONSTRUCT; } // Deduct count from possible codes left -= h.counts[len + 2]; // One more bit, double codes left left <<= 1; if (left < h.counts[len + 3]) { // Over-subscribed--return error return ErrorCode.ERR_CONSTRUCT; } // Deduct count from possible codes left -= h.counts[len + 3]; // One more bit, double codes left left <<= 1; if (left < h.counts[len + 4]) { // Over-subscribed--return error return ErrorCode.ERR_CONSTRUCT; } // Deduct count from possible codes left -= h.counts[len + 4]; } // Generate offsets into symbol table for each length for sorting offs[1] = 0; for (len = 1; len < MAXBITS; ++len) { offs[len + 1] = offs[len] + h.counts[len]; } // Put symbols in table sorted by length, by symbol order within each length for (symbol = 0; symbol < n; ++symbol) { if (lengths[start + symbol] != 0) { h.symbols[offs[lengths[start + symbol]]++] = symbol; } } // Left > 0 means incomplete return left > 0 ? ErrorCode.ERR_CONSTRUCT : ErrorCode.ERR_NONE; } } function _codes( State memory s, Huffman memory lencode, Huffman memory distcode ) private pure returns (ErrorCode) { unchecked { // Decoded symbol uint256 symbol; // Length for copy uint256 len; // Distance for copy uint256 dist; // TODO Solidity doesn't support constant arrays, but these are fixed at compile-time // Size base for length codes 257..285 uint16[29] memory lens = [ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258 ]; // Extra bits for length codes 257..285 uint8[29] memory lext = [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 ]; // Offset base for distance codes 0..29 uint16[30] memory dists = [ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 ]; // Extra bits for distance codes 0..29 uint8[30] memory dext = [ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 ]; // Error code ErrorCode err; // Decode literals and length/distance pairs while (symbol != 256) { (err, symbol) = _decode(s, lencode); if (err != ErrorCode.ERR_NONE) { // Invalid symbol return err; } if (symbol < 256) { // Literal: symbol is the byte // Write out the literal if (s.outcnt == s.output.length) { return ErrorCode.ERR_OUTPUT_EXHAUSTED; } s.output[s.outcnt] = bytes1(uint8(symbol)); ++s.outcnt; } else if (symbol > 256) { uint256 tempBits; // Length // Get and compute length symbol -= 257; if (symbol >= 29) { // Invalid fixed code return ErrorCode.ERR_INVALID_LENGTH_OR_DISTANCE_CODE; } (err, tempBits) = bits(s, lext[symbol]); if (err != ErrorCode.ERR_NONE) { return err; } len = lens[symbol] + tempBits; // Get and check distance (err, symbol) = _decode(s, distcode); if (err != ErrorCode.ERR_NONE) { // Invalid symbol return err; } (err, tempBits) = bits(s, dext[symbol]); if (err != ErrorCode.ERR_NONE) { return err; } dist = dists[symbol] + tempBits; if (dist > s.outcnt) { // Distance too far back return ErrorCode.ERR_DISTANCE_TOO_FAR; } // Copy length bytes from distance bytes back if (s.outcnt + len > s.output.length) { return ErrorCode.ERR_OUTPUT_EXHAUSTED; } while (len != 0) { // Note: Solidity reverts on underflow, so we decrement here len -= 1; s.output[s.outcnt] = s.output[s.outcnt - dist]; ++s.outcnt; } } else { s.outcnt += len; } } // Done with a valid fixed or dynamic block return ErrorCode.ERR_NONE; } } function _build_fixed(State memory s) private pure returns (ErrorCode) { unchecked { // Build fixed Huffman tables // TODO this is all a compile-time constant uint256 symbol; uint256[] memory lengths = new uint256[](FIXLCODES); // Literal/length table for (symbol = 0; symbol < 144; ++symbol) { lengths[symbol] = 8; } for (; symbol < 256; ++symbol) { lengths[symbol] = 9; } for (; symbol < 280; ++symbol) { lengths[symbol] = 7; } for (; symbol < FIXLCODES; ++symbol) { lengths[symbol] = 8; } _construct(s.lencode, lengths, FIXLCODES, 0); // Distance table for (symbol = 0; symbol < MAXDCODES; ++symbol) { lengths[symbol] = 5; } _construct(s.distcode, lengths, MAXDCODES, 0); return ErrorCode.ERR_NONE; } } function _fixed(State memory s) private pure returns (ErrorCode) { unchecked { // Decode data until end-of-block code return _codes(s, s.lencode, s.distcode); } } function _build_dynamic_lengths(State memory s) private pure returns (ErrorCode, uint256[] memory) { unchecked { uint256 ncode; // Index of lengths[] uint256 index; // Descriptor code lengths uint256[] memory lengths = new uint256[](MAXCODES); // Error code ErrorCode err; // Permutation of code length codes uint8[19] memory order = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; (err, ncode) = bits(s, 4); if (err != ErrorCode.ERR_NONE) { return (err, lengths); } ncode += 4; // Read code length code lengths (really), missing lengths are zero for (index = 0; index < ncode; ++index) { (err, lengths[order[index]]) = bits(s, 3); if (err != ErrorCode.ERR_NONE) { return (err, lengths); } } for (; index < 19; ++index) { lengths[order[index]] = 0; } return (ErrorCode.ERR_NONE, lengths); } } function _build_dynamic(State memory s) private pure returns ( ErrorCode, Huffman memory, Huffman memory ) { unchecked { // Number of lengths in descriptor uint256 nlen; uint256 ndist; // Index of lengths[] uint256 index; // Error code ErrorCode err; // Descriptor code lengths uint256[] memory lengths = new uint256[](MAXCODES); // Length and distance codes Huffman memory lencode = Huffman(new uint256[](MAXBITS + 1), new uint256[](MAXLCODES)); Huffman memory distcode = Huffman(new uint256[](MAXBITS + 1), new uint256[](MAXDCODES)); uint256 tempBits; // Get number of lengths in each table, check lengths (err, nlen) = bits(s, 5); if (err != ErrorCode.ERR_NONE) { return (err, lencode, distcode); } nlen += 257; (err, ndist) = bits(s, 5); if (err != ErrorCode.ERR_NONE) { return (err, lencode, distcode); } ndist += 1; if (nlen > MAXLCODES || ndist > MAXDCODES) { // Bad counts return (ErrorCode.ERR_TOO_MANY_LENGTH_OR_DISTANCE_CODES, lencode, distcode); } (err, lengths) = _build_dynamic_lengths(s); if (err != ErrorCode.ERR_NONE) { return (err, lencode, distcode); } // Build huffman table for code lengths codes (use lencode temporarily) err = _construct(lencode, lengths, 19, 0); if (err != ErrorCode.ERR_NONE) { // Require complete code set here return (ErrorCode.ERR_CODE_LENGTHS_CODES_INCOMPLETE, lencode, distcode); } // Read length/literal and distance code length tables index = 0; while (index < nlen + ndist) { // Decoded value uint256 symbol; // Last length to repeat uint256 len; (err, symbol) = _decode(s, lencode); if (err != ErrorCode.ERR_NONE) { // Invalid symbol return (err, lencode, distcode); } if (symbol < 16) { // Length in 0..15 lengths[index++] = symbol; } else { // Repeat instruction // Assume repeating zeros len = 0; if (symbol == 16) { // Repeat last length 3..6 times if (index == 0) { // No last length! return (ErrorCode.ERR_REPEAT_NO_FIRST_LENGTH, lencode, distcode); } // Last length len = lengths[index - 1]; (err, tempBits) = bits(s, 2); if (err != ErrorCode.ERR_NONE) { return (err, lencode, distcode); } symbol = 3 + tempBits; } else if (symbol == 17) { // Repeat zero 3..10 times (err, tempBits) = bits(s, 3); if (err != ErrorCode.ERR_NONE) { return (err, lencode, distcode); } symbol = 3 + tempBits; } else { // == 18, repeat zero 11..138 times (err, tempBits) = bits(s, 7); if (err != ErrorCode.ERR_NONE) { return (err, lencode, distcode); } symbol = 11 + tempBits; } if (index + symbol > nlen + ndist) { // Too many lengths! return (ErrorCode.ERR_REPEAT_MORE, lencode, distcode); } while (symbol != 0) { // Note: Solidity reverts on underflow, so we decrement here symbol -= 1; // Repeat last or zero symbol times lengths[index++] = len; } } } // Check for end-of-block code -- there better be one! if (lengths[256] == 0) { return (ErrorCode.ERR_MISSING_END_OF_BLOCK, lencode, distcode); } // Build huffman table for literal/length codes err = _construct(lencode, lengths, nlen, 0); if ( err != ErrorCode.ERR_NONE && (err == ErrorCode.ERR_NOT_TERMINATED || err == ErrorCode.ERR_OUTPUT_EXHAUSTED || nlen != lencode.counts[0] + lencode.counts[1]) ) { // Incomplete code ok only for single length 1 code return (ErrorCode.ERR_INVALID_LITERAL_LENGTH_CODE_LENGTHS, lencode, distcode); } // Build huffman table for distance codes err = _construct(distcode, lengths, ndist, nlen); if ( err != ErrorCode.ERR_NONE && (err == ErrorCode.ERR_NOT_TERMINATED || err == ErrorCode.ERR_OUTPUT_EXHAUSTED || ndist != distcode.counts[0] + distcode.counts[1]) ) { // Incomplete code ok only for single length 1 code return (ErrorCode.ERR_INVALID_DISTANCE_CODE_LENGTHS, lencode, distcode); } return (ErrorCode.ERR_NONE, lencode, distcode); } } function _dynamic(State memory s) private pure returns (ErrorCode) { unchecked { // Length and distance codes Huffman memory lencode; Huffman memory distcode; // Error code ErrorCode err; (err, lencode, distcode) = _build_dynamic(s); if (err != ErrorCode.ERR_NONE) { return err; } // Decode data until end-of-block code return _codes(s, lencode, distcode); } } function puff(bytes memory source, uint256 destlen) internal pure returns (ErrorCode, bytes memory) { unchecked { // Input/output state State memory s = State( new bytes(destlen), 0, source, 0, 0, 0, Huffman(new uint256[](MAXBITS + 1), new uint256[](FIXLCODES)), Huffman(new uint256[](MAXBITS + 1), new uint256[](MAXDCODES)) ); // Temp: last bit uint256 last; // Temp: block type bit uint256 t; // Error code ErrorCode err; // Build fixed Huffman tables err = _build_fixed(s); if (err != ErrorCode.ERR_NONE) { return (err, s.output); } // Process blocks until last block or error while (last == 0) { // One if last block (err, last) = bits(s, 1); if (err != ErrorCode.ERR_NONE) { return (err, s.output); } // Block type 0..3 (err, t) = bits(s, 2); if (err != ErrorCode.ERR_NONE) { return (err, s.output); } err = ( t == 0 ? _stored(s) : (t == 1 ? _fixed(s) : (t == 2 ? _dynamic(s) : ErrorCode.ERR_INVALID_BLOCK_TYPE)) ); // type == 3, invalid if (err != ErrorCode.ERR_NONE) { // Return with error break; } } return (err, s.output); } } }
{ "optimizer": { "enabled": true, "runs": 10000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_descriptor","type":"address"},{"internalType":"contract IInflator","name":"_inflator","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BadDecompressedLength","type":"error"},{"inputs":[],"name":"BadImageCount","type":"error"},{"inputs":[],"name":"BadPaletteLength","type":"error"},{"inputs":[],"name":"EmptyBytes","type":"error"},{"inputs":[],"name":"EmptyPalette","type":"error"},{"inputs":[],"name":"ImageNotFound","type":"error"},{"inputs":[],"name":"PaletteNotFound","type":"error"},{"inputs":[],"name":"SenderIsNotDescriptor","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"count","type":"uint16"}],"name":"AccessoriesAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"count","type":"uint256"}],"name":"BackgroundsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"count","type":"uint16"}],"name":"BodiesAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldDescriptor","type":"address"},{"indexed":false,"internalType":"address","name":"newDescriptor","type":"address"}],"name":"DescriptorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"count","type":"uint16"}],"name":"GlassesAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"count","type":"uint16"}],"name":"HeadsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldInflator","type":"address"},{"indexed":false,"internalType":"address","name":"newInflator","type":"address"}],"name":"InflatorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"paletteIndex","type":"uint8"}],"name":"PaletteSet","type":"event"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"accessories","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accessoriesTrait","outputs":[{"internalType":"uint256","name":"storedImagesCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedCompressed","type":"bytes"},{"internalType":"uint80","name":"decompressedLength","type":"uint80"},{"internalType":"uint16","name":"imageCount","type":"uint16"}],"name":"addAccessories","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pointer","type":"address"},{"internalType":"uint80","name":"decompressedLength","type":"uint80"},{"internalType":"uint16","name":"imageCount","type":"uint16"}],"name":"addAccessoriesFromPointer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_background","type":"string"}],"name":"addBackground","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedCompressed","type":"bytes"},{"internalType":"uint80","name":"decompressedLength","type":"uint80"},{"internalType":"uint16","name":"imageCount","type":"uint16"}],"name":"addBodies","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pointer","type":"address"},{"internalType":"uint80","name":"decompressedLength","type":"uint80"},{"internalType":"uint16","name":"imageCount","type":"uint16"}],"name":"addBodiesFromPointer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedCompressed","type":"bytes"},{"internalType":"uint80","name":"decompressedLength","type":"uint80"},{"internalType":"uint16","name":"imageCount","type":"uint16"}],"name":"addGlasses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pointer","type":"address"},{"internalType":"uint80","name":"decompressedLength","type":"uint80"},{"internalType":"uint16","name":"imageCount","type":"uint16"}],"name":"addGlassesFromPointer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedCompressed","type":"bytes"},{"internalType":"uint80","name":"decompressedLength","type":"uint80"},{"internalType":"uint16","name":"imageCount","type":"uint16"}],"name":"addHeads","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pointer","type":"address"},{"internalType":"uint80","name":"decompressedLength","type":"uint80"},{"internalType":"uint16","name":"imageCount","type":"uint16"}],"name":"addHeadsFromPointer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string[]","name":"_backgrounds","type":"string[]"}],"name":"addManyBackgrounds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"backgrounds","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"backgroundsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"bodies","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bodiesTrait","outputs":[{"internalType":"uint256","name":"storedImagesCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"descriptor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAccessoriesTrait","outputs":[{"components":[{"components":[{"internalType":"uint16","name":"imageCount","type":"uint16"},{"internalType":"uint80","name":"decompressedLength","type":"uint80"},{"internalType":"address","name":"pointer","type":"address"}],"internalType":"struct INounsArt.NounArtStoragePage[]","name":"storagePages","type":"tuple[]"},{"internalType":"uint256","name":"storedImagesCount","type":"uint256"}],"internalType":"struct INounsArt.Trait","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBodiesTrait","outputs":[{"components":[{"components":[{"internalType":"uint16","name":"imageCount","type":"uint16"},{"internalType":"uint80","name":"decompressedLength","type":"uint80"},{"internalType":"address","name":"pointer","type":"address"}],"internalType":"struct INounsArt.NounArtStoragePage[]","name":"storagePages","type":"tuple[]"},{"internalType":"uint256","name":"storedImagesCount","type":"uint256"}],"internalType":"struct INounsArt.Trait","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGlassesTrait","outputs":[{"components":[{"components":[{"internalType":"uint16","name":"imageCount","type":"uint16"},{"internalType":"uint80","name":"decompressedLength","type":"uint80"},{"internalType":"address","name":"pointer","type":"address"}],"internalType":"struct INounsArt.NounArtStoragePage[]","name":"storagePages","type":"tuple[]"},{"internalType":"uint256","name":"storedImagesCount","type":"uint256"}],"internalType":"struct INounsArt.Trait","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getHeadsTrait","outputs":[{"components":[{"components":[{"internalType":"uint16","name":"imageCount","type":"uint16"},{"internalType":"uint80","name":"decompressedLength","type":"uint80"},{"internalType":"address","name":"pointer","type":"address"}],"internalType":"struct INounsArt.NounArtStoragePage[]","name":"storagePages","type":"tuple[]"},{"internalType":"uint256","name":"storedImagesCount","type":"uint256"}],"internalType":"struct INounsArt.Trait","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"glasses","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"glassesTrait","outputs":[{"internalType":"uint256","name":"storedImagesCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"heads","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"headsTrait","outputs":[{"internalType":"uint256","name":"storedImagesCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"inflator","outputs":[{"internalType":"contract IInflator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"paletteIndex","type":"uint8"}],"name":"palettes","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"palettesPointers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_descriptor","type":"address"}],"name":"setDescriptor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IInflator","name":"_inflator","type":"address"}],"name":"setInflator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"paletteIndex","type":"uint8"},{"internalType":"bytes","name":"palette","type":"bytes"}],"name":"setPalette","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"paletteIndex","type":"uint8"},{"internalType":"address","name":"pointer","type":"address"}],"name":"setPalettePointer","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b506040516200218c3803806200218c83398101604081905262000034916200007f565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055620000be565b6001600160a01b03811681146200007c57600080fd5b50565b600080604083850312156200009357600080fd5b8251620000a08162000066565b6020840151909250620000b38162000066565b809150509250929050565b6120be80620000ce6000396000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80637ca942101161010f578063bc2d45fe116100a2578063e73dd38311610071578063e73dd38314610462578063e79c9ea61461046a578063fc362a701461047d578063fd30704b1461048757600080fd5b8063bc2d45fe14610414578063c64b2f5d14610427578063cd2b82501461042f578063e1d46ae61461044257600080fd5b8063970b2271116100de578063970b2271146103da578063aa5bf7d8146103e4578063b982d1b9146103f7578063bb5e488c1461040a57600080fd5b80637ca942101461038e5780638bd54c06146103a157806391b7916a146103b457806394f3df61146103c757600080fd5b8063461fc5af116101875780636e856531116101565780636e8565311461031f57806372aa4a961461033257806372c84d3f1461034557806373ac736b1461037b57600080fd5b8063461fc5af146102ce5780635a503f13146102e15780635c0910be146102f45780635e70664c1461030c57600080fd5b8063303e74df116101c3578063303e74df1461025b578063353c36a0146102a0578063368013dc146102b357806344cee73c146102bb57600080fd5b806301b9a397146101f557806304bde4dd1461020a5780630ba3db1a14610233578063222a36d014610246575b600080fd5b610208610203366004611751565b61048f565b005b61021d61021836600461176e565b61054e565b60405161022a91906117e3565b60405180910390f35b610208610241366004611869565b6105fa565b61024e61067e565b60405161022a91906118ce565b60005461027b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161022a565b6102086102ae366004611869565b61074a565b61024e6107c4565b61021d6102c936600461176e565b610877565b6102086102dc366004611966565b61088a565b61021d6102ef36600461176e565b61090c565b6005546102fe9081565b60405190815260200161022a565b61020861031a3660046119ab565b610919565b61020861032d366004611966565b61098c565b610208610340366004611751565b610a05565b61027b6103533660046119fe565b60036020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b610208610389366004611966565b610abc565b61021d61039c36600461176e565b610b35565b6102086103af366004611a19565b610b42565b6102086103c2366004611a50565b610bfb565b6102086103d5366004611869565b610cad565b6009546102fe9081565b6102086103f2366004611869565b610d27565b61021d61040536600461176e565b610da1565b6007546102fe9081565b61021d6104223660046119fe565b610dae565b61024e610e4a565b61020861043d366004611966565b610efd565b60015461027b9073ffffffffffffffffffffffffffffffffffffffff1681565b61024e610f76565b610208610478366004611ac5565b611029565b600b546102fe9081565b6002546102fe565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104c757604051631b7c44cd60e01b815260040160405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f6a470e5dd4b354979dc3b984575294975f737cb9ee3ae3cca949e998dbc7cee991015b60405180910390a15050565b6002818154811061055e57600080fd5b90600052602060002001600091509050805461057990611b18565b80601f01602080910402602001604051908101604052809291908181526020018280546105a590611b18565b80156105f25780601f106105c7576101008083540402835291602001916105f2565b820191906000526020600020905b8154815290600101906020018083116105d557829003601f168201915b505050505081565b60005473ffffffffffffffffffffffffffffffffffffffff16331461063257604051631b7c44cd60e01b815260040160405180910390fd5b6106406006858585856111b1565b60405161ffff821681527f2d0f2274b911553cd85de198b828dfe7ef8309c67e0b7674c045bcb0e5b5ba2e906020015b60405180910390a150505050565b60408051808201909152606081526000602082015260408051600480546060602082028401810185529383018181529293919284929091849160009085015b82821015610733576000848152602090819020604080516060810182529185015461ffff8116835262010000810469ffffffffffffffffffff16838501526c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16908201528252600190920191016106bd565b505050508152602001600182015481525050905090565b60005473ffffffffffffffffffffffffffffffffffffffff16331461078257604051631b7c44cd60e01b815260040160405180910390fd5b610790600a858585856111b1565b60405161ffff821681527ffbb56d0e73d76edc5867b20b68684b671a625696e50d8c985c2830fd1566aaec90602001610670565b6040805180820190915260608152600060208201526040805160088054602081028301606090810185529383018181529293919284929091849160009085018215610733576000848152602090819020604080516060810182529185015461ffff8116835262010000810469ffffffffffffffffffff16838501526c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16908201528252600190920191016106bd565b6060610884600483611243565b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146108c257604051631b7c44cd60e01b815260040160405180910390fd5b6108cf6008848484611288565b60405161ffff821681527fe74953497d5d03198c809f0f4a324019e503e87fef8e2081636487743ae29d62906020015b60405180910390a1505050565b6060610884600883611243565b60005473ffffffffffffffffffffffffffffffffffffffff16331461095157604051631b7c44cd60e01b815260040160405180910390fd5b61095b82826113ee565b604051600181527f379976e1287af3c12aafa34c6a1a61b0cbcb9dce67b3b220ece3b474a4a7427690602001610542565b60005473ffffffffffffffffffffffffffffffffffffffff1633146109c457604051631b7c44cd60e01b815260040160405180910390fd5b6109d16006848484611288565b60405161ffff821681527f2d0f2274b911553cd85de198b828dfe7ef8309c67e0b7674c045bcb0e5b5ba2e906020016108ff565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a3d57604051631b7c44cd60e01b815260040160405180910390fd5b6001805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527fad22bb31e9e983d055eeb60a03a1e572d4905254640c9ee3cd36c8d6431248309101610542565b60005473ffffffffffffffffffffffffffffffffffffffff163314610af457604051631b7c44cd60e01b815260040160405180910390fd5b610b01600a848484611288565b60405161ffff821681527ffbb56d0e73d76edc5867b20b68684b671a625696e50d8c985c2830fd1566aaec906020016108ff565b6060610884600683611243565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b7a57604051631b7c44cd60e01b815260040160405180910390fd5b60ff821660008181526003602090815260409182902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861617905590519182527f3469f6a12aa5e5edc4ea6e284300f2621e073fce4374d4673ded8f2ea7c18b4f9101610542565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c3357604051631b7c44cd60e01b815260040160405180910390fd5b60005b81811015610c7c57610c6a838383818110610c5357610c53611b6b565b9050602002810190610c659190611b9a565b6113ee565b80610c7481611c2e565b915050610c36565b506040518181527f379976e1287af3c12aafa34c6a1a61b0cbcb9dce67b3b220ece3b474a4a7427690602001610542565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ce557604051631b7c44cd60e01b815260040160405180910390fd5b610cf36008858585856111b1565b60405161ffff821681527fe74953497d5d03198c809f0f4a324019e503e87fef8e2081636487743ae29d6290602001610670565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d5f57604051631b7c44cd60e01b815260040160405180910390fd5b610d6d6004858585856111b1565b60405161ffff821681527feb09489df35ba64745f59c5a7efc6df50d432df8cfc3708deb7075e3c8a4f76a90602001610670565b6060610884600a83611243565b60ff811660009081526003602052604090205460609073ffffffffffffffffffffffffffffffffffffffff1680610e11576040517fafb85d6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ff8316600090815260036020526040902054610e439073ffffffffffffffffffffffffffffffffffffffff16611430565b9392505050565b6040805180820190915260608152600060208201526040805160068054602081028301606090810185529383018181529293919284929091849160009085018215610733576000848152602090819020604080516060810182529185015461ffff8116835262010000810469ffffffffffffffffffff16838501526c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16908201528252600190920191016106bd565b60005473ffffffffffffffffffffffffffffffffffffffff163314610f3557604051631b7c44cd60e01b815260040160405180910390fd5b610f426004848484611288565b60405161ffff821681527feb09489df35ba64745f59c5a7efc6df50d432df8cfc3708deb7075e3c8a4f76a906020016108ff565b60408051808201909152606081526000602082015260408051600a8054602081028301606090810185529383018181529293919284929091849160009085018215610733576000848152602090819020604080516060810182529185015461ffff8116835262010000810469ffffffffffffffffffff16838501526c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16908201528252600190920191016106bd565b60005473ffffffffffffffffffffffffffffffffffffffff16331461106157604051631b7c44cd60e01b815260040160405180910390fd5b600081900361109c576040517f61273c5200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110a7600382611c66565b1515806110b5575061030081115b156110ec576040517fe233eccd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61112b82828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061145e92505050565b60ff841660008181526003602090815260409182902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9590951694909417909355519081527f3469f6a12aa5e5edc4ea6e284300f2621e073fce4374d4673ded8f2ea7c18b4f91016108ff565b60008390036111ec576040517fc348b10c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061122d85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061145e92505050565b905061123b86828585611288565b505050505050565b6060600080611252858561153a565b915091506000611261836115fd565b905080828151811061127557611275611b6b565b6020026020010151935050505092915050565b8169ffffffffffffffffffff166000036112ce576040517fcce3526100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8061ffff1660000361130c576040517fa0cd7c8a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160608101825261ffff80841680835269ffffffffffffffffffff808716602080860191825273ffffffffffffffffffffffffffffffffffffffff808b169787019788528b5460018181018e5560008e81529384209851989091018054945199519092166c01000000000000000000000000026bffffffffffffffffffffffff9990951662010000027fffffffffffffffffffffffffffffffffffffffff000000000000000000000000909416979096169690961791909117959095161790925586018054919290916113e3908490611ca1565b909155505050505050565b600280546001810182556000919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0161142b828483611d2e565b505050565b60606108848260016114598173ffffffffffffffffffffffffffffffffffffffff84163b611e2b565b611709565b600080826040516020016114729190611e42565b60405160208183030381529060405290506000816040516020016114969190611e68565b60405160208183030381529060405290508051602082016000f0925073ffffffffffffffffffffffffffffffffffffffff8316611533576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4445504c4f594d454e545f4641494c4544000000000000000000000000000000604482015260640160405180910390fd5b5050919050565b8154600090819081805b828110156115c357600087828154811061156057611560611b6b565b6000918252602090912001805490915061157e9061ffff1684611ca1565b87101561159d57806115908489611e2b565b95509550505050506115f6565b80546115ad9061ffff1684611ca1565b92505080806115bb90611c2e565b915050611544565b506040517f264a7c1300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9250929050565b8054606090600090611634906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16611430565b60015484546040517f265b7f7e00000000000000000000000000000000000000000000000000000000815292935060009273ffffffffffffffffffffffffffffffffffffffff9092169163265b7f7e916116a591869162010000900469ffffffffffffffffffff1690600401611ead565b600060405180830381865afa1580156116c2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526116ea9190810190611f70565b915050808060200190518101906117019190611fc5565b949350505050565b60408051603f8301601f19168101909152818152818360208301863c9392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461174e57600080fd5b50565b60006020828403121561176357600080fd5b8135610e438161172c565b60006020828403121561178057600080fd5b5035919050565b60005b838110156117a257818101518382015260200161178a565b838111156117b1576000848401525b50505050565b600081518084526117cf816020860160208601611787565b601f01601f19169290920160200192915050565b602081526000610e4360208301846117b7565b60008083601f84011261180857600080fd5b50813567ffffffffffffffff81111561182057600080fd5b6020830191508360208285010111156115f657600080fd5b803569ffffffffffffffffffff8116811461185257600080fd5b919050565b803561ffff8116811461185257600080fd5b6000806000806060858703121561187f57600080fd5b843567ffffffffffffffff81111561189657600080fd5b6118a2878288016117f6565b90955093506118b5905060208601611838565b91506118c360408601611857565b905092959194509250565b6000602080835260608084018551604080858801528282518085526080890191508684019450600093505b80841015611950578451805161ffff1683528781015169ffffffffffffffffffff168884015283015173ffffffffffffffffffffffffffffffffffffffff16838301529386019360019390930192908501906118f9565b5094909701519590960194909452509392505050565b60008060006060848603121561197b57600080fd5b83356119868161172c565b925061199460208501611838565b91506119a260408501611857565b90509250925092565b600080602083850312156119be57600080fd5b823567ffffffffffffffff8111156119d557600080fd5b6119e1858286016117f6565b90969095509350505050565b803560ff8116811461185257600080fd5b600060208284031215611a1057600080fd5b610e43826119ed565b60008060408385031215611a2c57600080fd5b611a35836119ed565b91506020830135611a458161172c565b809150509250929050565b60008060208385031215611a6357600080fd5b823567ffffffffffffffff80821115611a7b57600080fd5b818501915085601f830112611a8f57600080fd5b813581811115611a9e57600080fd5b8660208260051b8501011115611ab357600080fd5b60209290920196919550909350505050565b600080600060408486031215611ada57600080fd5b611ae3846119ed565b9250602084013567ffffffffffffffff811115611aff57600080fd5b611b0b868287016117f6565b9497909650939450505050565b600181811c90821680611b2c57607f821691505b602082108103611b65577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611bcf57600080fd5b83018035915067ffffffffffffffff821115611bea57600080fd5b6020019150368190038213156115f657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611c5f57611c5f611bff565b5060010190565b600082611c9c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b60008219821115611cb457611cb4611bff565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b601f82111561142b57600081815260208120601f850160051c81016020861015611d0f5750805b601f850160051c820191505b8181101561123b57828155600101611d1b565b67ffffffffffffffff831115611d4657611d46611cb9565b611d5a83611d548354611b18565b83611ce8565b6000601f841160018114611dac5760008515611d765750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611e24565b600083815260209020601f19861690835b82811015611ddd5786850135825560209485019460019092019101611dbd565b5086821015611e18577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b600082821015611e3d57611e3d611bff565b500390565b6000815260008251611e5b816001850160208701611787565b9190910160010192915050565b7f600b5981380380925939f3000000000000000000000000000000000000000000815260008251611ea081600b850160208701611787565b91909101600b0192915050565b604081526000611ec060408301856117b7565b905069ffffffffffffffffffff831660208301529392505050565b604051601f8201601f1916810167ffffffffffffffff81118282101715611f0457611f04611cb9565b604052919050565b600082601f830112611f1d57600080fd5b815167ffffffffffffffff811115611f3757611f37611cb9565b611f4a6020601f19601f84011601611edb565b818152846020838601011115611f5f57600080fd5b611701826020830160208701611787565b60008060408385031215611f8357600080fd5b8251600f8110611f9257600080fd5b602084015190925067ffffffffffffffff811115611faf57600080fd5b611fbb85828601611f0c565b9150509250929050565b60006020808385031215611fd857600080fd5b825167ffffffffffffffff80821115611ff057600080fd5b818501915085601f83011261200457600080fd5b81518181111561201657612016611cb9565b8060051b612025858201611edb565b918252838101850191858101908984111561203f57600080fd5b86860192505b8383101561207b5782518581111561205d5760008081fd5b61206b8b89838a0101611f0c565b8352509186019190860190612045565b999850505050505050505056fea2646970667358221220cb943808ef0a70bb992ff59e33e111868dc0a00a9f6aefcbac991e2d47388d4f64736f6c634300080f00330000000000000000000000006229c811d04501523c6058bfaac29c91bb586268000000000000000000000000a2acee85cd81c42bcaa1fefa8ed2516b68872dbe
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101f05760003560e01c80637ca942101161010f578063bc2d45fe116100a2578063e73dd38311610071578063e73dd38314610462578063e79c9ea61461046a578063fc362a701461047d578063fd30704b1461048757600080fd5b8063bc2d45fe14610414578063c64b2f5d14610427578063cd2b82501461042f578063e1d46ae61461044257600080fd5b8063970b2271116100de578063970b2271146103da578063aa5bf7d8146103e4578063b982d1b9146103f7578063bb5e488c1461040a57600080fd5b80637ca942101461038e5780638bd54c06146103a157806391b7916a146103b457806394f3df61146103c757600080fd5b8063461fc5af116101875780636e856531116101565780636e8565311461031f57806372aa4a961461033257806372c84d3f1461034557806373ac736b1461037b57600080fd5b8063461fc5af146102ce5780635a503f13146102e15780635c0910be146102f45780635e70664c1461030c57600080fd5b8063303e74df116101c3578063303e74df1461025b578063353c36a0146102a0578063368013dc146102b357806344cee73c146102bb57600080fd5b806301b9a397146101f557806304bde4dd1461020a5780630ba3db1a14610233578063222a36d014610246575b600080fd5b610208610203366004611751565b61048f565b005b61021d61021836600461176e565b61054e565b60405161022a91906117e3565b60405180910390f35b610208610241366004611869565b6105fa565b61024e61067e565b60405161022a91906118ce565b60005461027b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161022a565b6102086102ae366004611869565b61074a565b61024e6107c4565b61021d6102c936600461176e565b610877565b6102086102dc366004611966565b61088a565b61021d6102ef36600461176e565b61090c565b6005546102fe9081565b60405190815260200161022a565b61020861031a3660046119ab565b610919565b61020861032d366004611966565b61098c565b610208610340366004611751565b610a05565b61027b6103533660046119fe565b60036020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b610208610389366004611966565b610abc565b61021d61039c36600461176e565b610b35565b6102086103af366004611a19565b610b42565b6102086103c2366004611a50565b610bfb565b6102086103d5366004611869565b610cad565b6009546102fe9081565b6102086103f2366004611869565b610d27565b61021d61040536600461176e565b610da1565b6007546102fe9081565b61021d6104223660046119fe565b610dae565b61024e610e4a565b61020861043d366004611966565b610efd565b60015461027b9073ffffffffffffffffffffffffffffffffffffffff1681565b61024e610f76565b610208610478366004611ac5565b611029565b600b546102fe9081565b6002546102fe565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104c757604051631b7c44cd60e01b815260040160405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f6a470e5dd4b354979dc3b984575294975f737cb9ee3ae3cca949e998dbc7cee991015b60405180910390a15050565b6002818154811061055e57600080fd5b90600052602060002001600091509050805461057990611b18565b80601f01602080910402602001604051908101604052809291908181526020018280546105a590611b18565b80156105f25780601f106105c7576101008083540402835291602001916105f2565b820191906000526020600020905b8154815290600101906020018083116105d557829003601f168201915b505050505081565b60005473ffffffffffffffffffffffffffffffffffffffff16331461063257604051631b7c44cd60e01b815260040160405180910390fd5b6106406006858585856111b1565b60405161ffff821681527f2d0f2274b911553cd85de198b828dfe7ef8309c67e0b7674c045bcb0e5b5ba2e906020015b60405180910390a150505050565b60408051808201909152606081526000602082015260408051600480546060602082028401810185529383018181529293919284929091849160009085015b82821015610733576000848152602090819020604080516060810182529185015461ffff8116835262010000810469ffffffffffffffffffff16838501526c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16908201528252600190920191016106bd565b505050508152602001600182015481525050905090565b60005473ffffffffffffffffffffffffffffffffffffffff16331461078257604051631b7c44cd60e01b815260040160405180910390fd5b610790600a858585856111b1565b60405161ffff821681527ffbb56d0e73d76edc5867b20b68684b671a625696e50d8c985c2830fd1566aaec90602001610670565b6040805180820190915260608152600060208201526040805160088054602081028301606090810185529383018181529293919284929091849160009085018215610733576000848152602090819020604080516060810182529185015461ffff8116835262010000810469ffffffffffffffffffff16838501526c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16908201528252600190920191016106bd565b6060610884600483611243565b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146108c257604051631b7c44cd60e01b815260040160405180910390fd5b6108cf6008848484611288565b60405161ffff821681527fe74953497d5d03198c809f0f4a324019e503e87fef8e2081636487743ae29d62906020015b60405180910390a1505050565b6060610884600883611243565b60005473ffffffffffffffffffffffffffffffffffffffff16331461095157604051631b7c44cd60e01b815260040160405180910390fd5b61095b82826113ee565b604051600181527f379976e1287af3c12aafa34c6a1a61b0cbcb9dce67b3b220ece3b474a4a7427690602001610542565b60005473ffffffffffffffffffffffffffffffffffffffff1633146109c457604051631b7c44cd60e01b815260040160405180910390fd5b6109d16006848484611288565b60405161ffff821681527f2d0f2274b911553cd85de198b828dfe7ef8309c67e0b7674c045bcb0e5b5ba2e906020016108ff565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a3d57604051631b7c44cd60e01b815260040160405180910390fd5b6001805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527fad22bb31e9e983d055eeb60a03a1e572d4905254640c9ee3cd36c8d6431248309101610542565b60005473ffffffffffffffffffffffffffffffffffffffff163314610af457604051631b7c44cd60e01b815260040160405180910390fd5b610b01600a848484611288565b60405161ffff821681527ffbb56d0e73d76edc5867b20b68684b671a625696e50d8c985c2830fd1566aaec906020016108ff565b6060610884600683611243565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b7a57604051631b7c44cd60e01b815260040160405180910390fd5b60ff821660008181526003602090815260409182902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861617905590519182527f3469f6a12aa5e5edc4ea6e284300f2621e073fce4374d4673ded8f2ea7c18b4f9101610542565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c3357604051631b7c44cd60e01b815260040160405180910390fd5b60005b81811015610c7c57610c6a838383818110610c5357610c53611b6b565b9050602002810190610c659190611b9a565b6113ee565b80610c7481611c2e565b915050610c36565b506040518181527f379976e1287af3c12aafa34c6a1a61b0cbcb9dce67b3b220ece3b474a4a7427690602001610542565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ce557604051631b7c44cd60e01b815260040160405180910390fd5b610cf36008858585856111b1565b60405161ffff821681527fe74953497d5d03198c809f0f4a324019e503e87fef8e2081636487743ae29d6290602001610670565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d5f57604051631b7c44cd60e01b815260040160405180910390fd5b610d6d6004858585856111b1565b60405161ffff821681527feb09489df35ba64745f59c5a7efc6df50d432df8cfc3708deb7075e3c8a4f76a90602001610670565b6060610884600a83611243565b60ff811660009081526003602052604090205460609073ffffffffffffffffffffffffffffffffffffffff1680610e11576040517fafb85d6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ff8316600090815260036020526040902054610e439073ffffffffffffffffffffffffffffffffffffffff16611430565b9392505050565b6040805180820190915260608152600060208201526040805160068054602081028301606090810185529383018181529293919284929091849160009085018215610733576000848152602090819020604080516060810182529185015461ffff8116835262010000810469ffffffffffffffffffff16838501526c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16908201528252600190920191016106bd565b60005473ffffffffffffffffffffffffffffffffffffffff163314610f3557604051631b7c44cd60e01b815260040160405180910390fd5b610f426004848484611288565b60405161ffff821681527feb09489df35ba64745f59c5a7efc6df50d432df8cfc3708deb7075e3c8a4f76a906020016108ff565b60408051808201909152606081526000602082015260408051600a8054602081028301606090810185529383018181529293919284929091849160009085018215610733576000848152602090819020604080516060810182529185015461ffff8116835262010000810469ffffffffffffffffffff16838501526c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16908201528252600190920191016106bd565b60005473ffffffffffffffffffffffffffffffffffffffff16331461106157604051631b7c44cd60e01b815260040160405180910390fd5b600081900361109c576040517f61273c5200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110a7600382611c66565b1515806110b5575061030081115b156110ec576040517fe233eccd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61112b82828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061145e92505050565b60ff841660008181526003602090815260409182902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9590951694909417909355519081527f3469f6a12aa5e5edc4ea6e284300f2621e073fce4374d4673ded8f2ea7c18b4f91016108ff565b60008390036111ec576040517fc348b10c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061122d85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061145e92505050565b905061123b86828585611288565b505050505050565b6060600080611252858561153a565b915091506000611261836115fd565b905080828151811061127557611275611b6b565b6020026020010151935050505092915050565b8169ffffffffffffffffffff166000036112ce576040517fcce3526100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8061ffff1660000361130c576040517fa0cd7c8a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160608101825261ffff80841680835269ffffffffffffffffffff808716602080860191825273ffffffffffffffffffffffffffffffffffffffff808b169787019788528b5460018181018e5560008e81529384209851989091018054945199519092166c01000000000000000000000000026bffffffffffffffffffffffff9990951662010000027fffffffffffffffffffffffffffffffffffffffff000000000000000000000000909416979096169690961791909117959095161790925586018054919290916113e3908490611ca1565b909155505050505050565b600280546001810182556000919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0161142b828483611d2e565b505050565b60606108848260016114598173ffffffffffffffffffffffffffffffffffffffff84163b611e2b565b611709565b600080826040516020016114729190611e42565b60405160208183030381529060405290506000816040516020016114969190611e68565b60405160208183030381529060405290508051602082016000f0925073ffffffffffffffffffffffffffffffffffffffff8316611533576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4445504c4f594d454e545f4641494c4544000000000000000000000000000000604482015260640160405180910390fd5b5050919050565b8154600090819081805b828110156115c357600087828154811061156057611560611b6b565b6000918252602090912001805490915061157e9061ffff1684611ca1565b87101561159d57806115908489611e2b565b95509550505050506115f6565b80546115ad9061ffff1684611ca1565b92505080806115bb90611c2e565b915050611544565b506040517f264a7c1300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9250929050565b8054606090600090611634906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16611430565b60015484546040517f265b7f7e00000000000000000000000000000000000000000000000000000000815292935060009273ffffffffffffffffffffffffffffffffffffffff9092169163265b7f7e916116a591869162010000900469ffffffffffffffffffff1690600401611ead565b600060405180830381865afa1580156116c2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526116ea9190810190611f70565b915050808060200190518101906117019190611fc5565b949350505050565b60408051603f8301601f19168101909152818152818360208301863c9392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461174e57600080fd5b50565b60006020828403121561176357600080fd5b8135610e438161172c565b60006020828403121561178057600080fd5b5035919050565b60005b838110156117a257818101518382015260200161178a565b838111156117b1576000848401525b50505050565b600081518084526117cf816020860160208601611787565b601f01601f19169290920160200192915050565b602081526000610e4360208301846117b7565b60008083601f84011261180857600080fd5b50813567ffffffffffffffff81111561182057600080fd5b6020830191508360208285010111156115f657600080fd5b803569ffffffffffffffffffff8116811461185257600080fd5b919050565b803561ffff8116811461185257600080fd5b6000806000806060858703121561187f57600080fd5b843567ffffffffffffffff81111561189657600080fd5b6118a2878288016117f6565b90955093506118b5905060208601611838565b91506118c360408601611857565b905092959194509250565b6000602080835260608084018551604080858801528282518085526080890191508684019450600093505b80841015611950578451805161ffff1683528781015169ffffffffffffffffffff168884015283015173ffffffffffffffffffffffffffffffffffffffff16838301529386019360019390930192908501906118f9565b5094909701519590960194909452509392505050565b60008060006060848603121561197b57600080fd5b83356119868161172c565b925061199460208501611838565b91506119a260408501611857565b90509250925092565b600080602083850312156119be57600080fd5b823567ffffffffffffffff8111156119d557600080fd5b6119e1858286016117f6565b90969095509350505050565b803560ff8116811461185257600080fd5b600060208284031215611a1057600080fd5b610e43826119ed565b60008060408385031215611a2c57600080fd5b611a35836119ed565b91506020830135611a458161172c565b809150509250929050565b60008060208385031215611a6357600080fd5b823567ffffffffffffffff80821115611a7b57600080fd5b818501915085601f830112611a8f57600080fd5b813581811115611a9e57600080fd5b8660208260051b8501011115611ab357600080fd5b60209290920196919550909350505050565b600080600060408486031215611ada57600080fd5b611ae3846119ed565b9250602084013567ffffffffffffffff811115611aff57600080fd5b611b0b868287016117f6565b9497909650939450505050565b600181811c90821680611b2c57607f821691505b602082108103611b65577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611bcf57600080fd5b83018035915067ffffffffffffffff821115611bea57600080fd5b6020019150368190038213156115f657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611c5f57611c5f611bff565b5060010190565b600082611c9c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b60008219821115611cb457611cb4611bff565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b601f82111561142b57600081815260208120601f850160051c81016020861015611d0f5750805b601f850160051c820191505b8181101561123b57828155600101611d1b565b67ffffffffffffffff831115611d4657611d46611cb9565b611d5a83611d548354611b18565b83611ce8565b6000601f841160018114611dac5760008515611d765750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611e24565b600083815260209020601f19861690835b82811015611ddd5786850135825560209485019460019092019101611dbd565b5086821015611e18577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b600082821015611e3d57611e3d611bff565b500390565b6000815260008251611e5b816001850160208701611787565b9190910160010192915050565b7f600b5981380380925939f3000000000000000000000000000000000000000000815260008251611ea081600b850160208701611787565b91909101600b0192915050565b604081526000611ec060408301856117b7565b905069ffffffffffffffffffff831660208301529392505050565b604051601f8201601f1916810167ffffffffffffffff81118282101715611f0457611f04611cb9565b604052919050565b600082601f830112611f1d57600080fd5b815167ffffffffffffffff811115611f3757611f37611cb9565b611f4a6020601f19601f84011601611edb565b818152846020838601011115611f5f57600080fd5b611701826020830160208701611787565b60008060408385031215611f8357600080fd5b8251600f8110611f9257600080fd5b602084015190925067ffffffffffffffff811115611faf57600080fd5b611fbb85828601611f0c565b9150509250929050565b60006020808385031215611fd857600080fd5b825167ffffffffffffffff80821115611ff057600080fd5b818501915085601f83011261200457600080fd5b81518181111561201657612016611cb9565b8060051b612025858201611edb565b918252838101850191858101908984111561203f57600080fd5b86860192505b8383101561207b5782518581111561205d5760008081fd5b61206b8b89838a0101611f0c565b8352509186019190860190612045565b999850505050505050505056fea2646970667358221220cb943808ef0a70bb992ff59e33e111868dc0a00a9f6aefcbac991e2d47388d4f64736f6c634300080f0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006229c811d04501523c6058bfaac29c91bb586268000000000000000000000000a2acee85cd81c42bcaa1fefa8ed2516b68872dbe
-----Decoded View---------------
Arg [0] : _descriptor (address): 0x6229c811D04501523C6058bfAAc29c91bb586268
Arg [1] : _inflator (address): 0xa2acee85Cd81c42BcAa1FeFA8eD2516b68872Dbe
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000006229c811d04501523c6058bfaac29c91bb586268
Arg [1] : 000000000000000000000000a2acee85cd81c42bcaa1fefa8ed2516b68872dbe
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.