Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 5 internal transactions
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
16638249 | 679 days ago | Contract Creation | 0 ETH | |||
16638248 | 679 days ago | Contract Creation | 0 ETH | |||
16638247 | 679 days ago | Contract Creation | 0 ETH | |||
16638246 | 679 days ago | Contract Creation | 0 ETH | |||
16638245 | 679 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
NounsArt
Compiler Version
v0.8.17+commit.8df45f5f
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 CNNouns art storage contract /********************************* * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░█████████░░█████████░░░ * * ░░░░░░██░░░████░░██░░░████░░░ * * ░░██████░░░████████░░░████░░░ * * ░░██░░██░░░████░░██░░░████░░░ * * ░░██░░██░░░████░░██░░░████░░░ * * ░░░░░░█████████░░█████████░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ pragma solidity ^0.8.6; // LICENSE // This file is a modified version of nounsDAO's NounsArt.sol: // https://github.com/nounsDAO/nouns-monorepo/blob/854b9b64770401da71503972c65c4f9eda060ba6/packages/nouns-contracts/contracts/NounsArt.sol // // NounsArt.sol licensed under the GPL-3.0 license. // With modifications by CNNouns DAO. 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 Heads Trait Trait public headsTrait; /// @notice Noun Glasses Trait Trait public glassesTrait; /// @notice Noun Skills Trait Trait public skillsTrait; /** * @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 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 Get the Trait struct for skills. * @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 getSkillsTrait() external view override returns (Trait memory) { return skillsTrait; } /** * @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 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 Add a batch of skill 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 addSkills( bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { addPage(skillsTrait, encodedCompressed, decompressedLength, imageCount); emit SkillsAdded(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 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 Add a batch of skill 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 addSkillsFromPointer( address pointer, uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { addPage(skillsTrait, pointer, decompressedLength, imageCount); emit SkillsAdded(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 glasses image bytes (RLE-encoded). */ function glasses(uint256 index) public view override returns (bytes memory) { return imageByIndex(glassesTrait, index); } /** * @notice Get a skill image bytes (RLE-encoded). */ function skills(uint256 index) public view override returns (bytes memory) { return imageByIndex(skillsTrait, 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; // LICENSE // This file is a modified version of nounsDAO's INounsArt.sol: // https://github.com/nounsDAO/nouns-monorepo/blob/854b9b64770401da71503972c65c4f9eda060ba6/packages/nouns-contracts/contracts/interfaces/INounsArt.sol // // INounsArt.sol licensed under the GPL-3.0 license. // With modifications by CNNouns DAO. 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 HeadsAdded(uint16 count); event GlassesAdded(uint16 count); event SkillsAdded(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 addHeads( bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) external; function addGlasses( bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) external; function addSkills( 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 addHeadsFromPointer( address pointer, uint80 decompressedLength, uint16 imageCount ) external; function addGlassesFromPointer( address pointer, uint80 decompressedLength, uint16 imageCount ) external; function addSkillsFromPointer( 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 glasses(uint256 index) external view returns (bytes memory); function skills(uint256 index) external view returns (bytes memory); function getBodiesTrait() external view returns (Trait memory); function getHeadsTrait() external view returns (Trait memory); function getGlassesTrait() external view returns (Trait memory); function getSkillsTrait() 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":"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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"count","type":"uint16"}],"name":"SkillsAdded","type":"event"},{"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":"bytes","name":"encodedCompressed","type":"bytes"},{"internalType":"uint80","name":"decompressedLength","type":"uint80"},{"internalType":"uint16","name":"imageCount","type":"uint16"}],"name":"addSkills","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":"addSkillsFromPointer","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":"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":[],"name":"getSkillsTrait","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"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"skills","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"skillsTrait","outputs":[{"internalType":"uint256","name":"storedImagesCount","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620021773803806200217783398101604081905262000034916200007f565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055620000be565b6001600160a01b03811681146200007c57600080fd5b50565b600080604083850312156200009357600080fd5b8251620000a08162000066565b6020840151909250620000b38162000066565b809150509250929050565b6120a980620000ce6000396000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c806372c84d3f1161010f578063bc2d45fe116100a2578063e79c9ea611610071578063e79c9ea614610457578063f51a8f1e1461046a578063fc362a701461047d578063fd30704b1461048757600080fd5b8063bc2d45fe14610409578063cd2b82501461041c578063e1d46ae61461042f578063e73dd3831461044f57600080fd5b806394f3df61116100de57806394f3df61146103c6578063970b2271146103d9578063aa5bf7d8146103e3578063b982d1b9146103f657600080fd5b806372c84d3f1461035757806373ac736b1461038d5780638bd54c06146103a057806391b7916a146103b357600080fd5b8063368013dc116101875780635a503f13116101565780635a503f13146103145780635c0910be146103275780635e70664c1461033157806372aa4a961461034457600080fd5b8063368013dc146102d357806344cee73c146102db578063461fc5af146102ee57806350d15fbe1461030157600080fd5b806324cde248116101c357806324cde2481461025b57806326ac853b14610273578063303e74df1461027b578063353c36a0146102c057600080fd5b806301b9a397146101f557806304bde4dd1461020a5780631dc9637d14610233578063222a36d014610246575b600080fd5b610208610203366004611751565b61048f565b005b61021d61021836600461176e565b61054e565b60405161022a91906117d7565b60405180910390f35b61020861024136600461181b565b6105fa565b61024e61067c565b60405161022a9190611860565b600b546102659081565b60405190815260200161022a565b61024e610748565b60005461029b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161022a565b6102086102ce36600461193a565b6107fb565b61024e61087f565b61021d6102e936600461176e565b610932565b6102086102fc36600461181b565b610945565b61021d61030f36600461176e565b6109be565b61021d61032236600461176e565b6109cb565b6005546102659081565b61020861033f36600461199f565b6109d8565b610208610352366004611751565b610a4b565b61029b6103653660046119f2565b60036020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b61020861039b36600461181b565b610b02565b6102086103ae366004611a0d565b610b7b565b6102086103c1366004611a44565b610c34565b6102086103d436600461193a565b610ce6565b6007546102659081565b6102086103f136600461193a565b610d60565b61021d61040436600461176e565b610dda565b61021d6104173660046119f2565b610de7565b61020861042a36600461181b565b610e83565b60015461029b9073ffffffffffffffffffffffffffffffffffffffff1681565b61024e610efc565b610208610465366004611ab9565b610faf565b61020861047836600461193a565b611137565b6009546102659081565b600254610265565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104c757604051631b7c44cd60e01b815260040160405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f6a470e5dd4b354979dc3b984575294975f737cb9ee3ae3cca949e998dbc7cee991015b60405180910390a15050565b6002818154811061055e57600080fd5b90600052602060002001600091509050805461057990611b0c565b80601f01602080910402602001604051908101604052809291908181526020018280546105a590611b0c565b80156105f25780601f106105c7576101008083540402835291602001916105f2565b820191906000526020600020905b8154815290600101906020018083116105d557829003601f168201915b505050505081565b60005473ffffffffffffffffffffffffffffffffffffffff16331461063257604051631b7c44cd60e01b815260040160405180910390fd5b61063f600a8484846111b1565b60405161ffff821681527fabb9adb54cb70346506b5d755f568fc186f68d9586d4a0c997f94ac947866b61906020015b60405180910390a1505050565b60408051808201909152606081526000602082015260408051600480546060602082028401810185529383018181529293919284929091849160009085015b82821015610731576000848152602090819020604080516060810182529185015461ffff8116835262010000810469ffffffffffffffffffff16838501526c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16908201528252600190920191016106bb565b505050508152602001600182015481525050905090565b60408051808201909152606081526000602082015260408051600a8054602081028301606090810185529383018181529293919284929091849160009085018215610731576000848152602090819020604080516060810182529185015461ffff8116835262010000810469ffffffffffffffffffff16838501526c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16908201528252600190920191016106bb565b60005473ffffffffffffffffffffffffffffffffffffffff16331461083357604051631b7c44cd60e01b815260040160405180910390fd5b610841600885858585611317565b60405161ffff821681527ffbb56d0e73d76edc5867b20b68684b671a625696e50d8c985c2830fd1566aaec906020015b60405180910390a150505050565b6040805180820190915260608152600060208201526040805160068054602081028301606090810185529383018181529293919284929091849160009085018215610731576000848152602090819020604080516060810182529185015461ffff8116835262010000810469ffffffffffffffffffff16838501526c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16908201528252600190920191016106bb565b606061093f6004836113a9565b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461097d57604051631b7c44cd60e01b815260040160405180910390fd5b61098a60068484846111b1565b60405161ffff821681527fe74953497d5d03198c809f0f4a324019e503e87fef8e2081636487743ae29d629060200161066f565b606061093f600a836113a9565b606061093f6006836113a9565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a1057604051631b7c44cd60e01b815260040160405180910390fd5b610a1a82826113ee565b604051600181527f379976e1287af3c12aafa34c6a1a61b0cbcb9dce67b3b220ece3b474a4a7427690602001610542565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a8357604051631b7c44cd60e01b815260040160405180910390fd5b6001805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527fad22bb31e9e983d055eeb60a03a1e572d4905254640c9ee3cd36c8d6431248309101610542565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b3a57604051631b7c44cd60e01b815260040160405180910390fd5b610b4760088484846111b1565b60405161ffff821681527ffbb56d0e73d76edc5867b20b68684b671a625696e50d8c985c2830fd1566aaec9060200161066f565b60005473ffffffffffffffffffffffffffffffffffffffff163314610bb357604051631b7c44cd60e01b815260040160405180910390fd5b60ff821660008181526003602090815260409182902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861617905590519182527f3469f6a12aa5e5edc4ea6e284300f2621e073fce4374d4673ded8f2ea7c18b4f9101610542565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c6c57604051631b7c44cd60e01b815260040160405180910390fd5b60005b81811015610cb557610ca3838383818110610c8c57610c8c611b5f565b9050602002810190610c9e9190611b8e565b6113ee565b80610cad81611c22565b915050610c6f565b506040518181527f379976e1287af3c12aafa34c6a1a61b0cbcb9dce67b3b220ece3b474a4a7427690602001610542565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d1e57604051631b7c44cd60e01b815260040160405180910390fd5b610d2c600685858585611317565b60405161ffff821681527fe74953497d5d03198c809f0f4a324019e503e87fef8e2081636487743ae29d6290602001610871565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d9857604051631b7c44cd60e01b815260040160405180910390fd5b610da6600485858585611317565b60405161ffff821681527feb09489df35ba64745f59c5a7efc6df50d432df8cfc3708deb7075e3c8a4f76a90602001610871565b606061093f6008836113a9565b60ff811660009081526003602052604090205460609073ffffffffffffffffffffffffffffffffffffffff1680610e4a576040517fafb85d6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ff8316600090815260036020526040902054610e7c9073ffffffffffffffffffffffffffffffffffffffff16611430565b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ebb57604051631b7c44cd60e01b815260040160405180910390fd5b610ec860048484846111b1565b60405161ffff821681527feb09489df35ba64745f59c5a7efc6df50d432df8cfc3708deb7075e3c8a4f76a9060200161066f565b6040805180820190915260608152600060208201526040805160088054602081028301606090810185529383018181529293919284929091849160009085018215610731576000848152602090819020604080516060810182529185015461ffff8116835262010000810469ffffffffffffffffffff16838501526c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16908201528252600190920191016106bb565b60005473ffffffffffffffffffffffffffffffffffffffff163314610fe757604051631b7c44cd60e01b815260040160405180910390fd5b6000819003611022576040517f61273c5200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61102d600382611c5a565b15158061103b575061030081115b15611072576040517fe233eccd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110b182828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061145e92505050565b60ff841660008181526003602090815260409182902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9590951694909417909355519081527f3469f6a12aa5e5edc4ea6e284300f2621e073fce4374d4673ded8f2ea7c18b4f910161066f565b60005473ffffffffffffffffffffffffffffffffffffffff16331461116f57604051631b7c44cd60e01b815260040160405180910390fd5b61117d600a85858585611317565b60405161ffff821681527fabb9adb54cb70346506b5d755f568fc186f68d9586d4a0c997f94ac947866b6190602001610871565b8169ffffffffffffffffffff166000036111f7576040517fcce3526100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8061ffff16600003611235576040517fa0cd7c8a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160608101825261ffff80841680835269ffffffffffffffffffff808716602080860191825273ffffffffffffffffffffffffffffffffffffffff808b169787019788528b5460018181018e5560008e81529384209851989091018054945199519092166c01000000000000000000000000026bffffffffffffffffffffffff9990951662010000027fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009094169790961696909617919091179590951617909255860180549192909161130c908490611c95565b909155505050505050565b6000839003611352576040517fc348b10c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061139385858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061145e92505050565b90506113a1868285856111b1565b505050505050565b60606000806113b8858561153a565b9150915060006113c7836115fd565b90508082815181106113db576113db611b5f565b6020026020010151935050505092915050565b600280546001810182556000919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0161142b828483611d1d565b505050565b606061093f8260016114598173ffffffffffffffffffffffffffffffffffffffff84163b611e1a565b611709565b600080826040516020016114729190611e2d565b60405160208183030381529060405290506000816040516020016114969190611e53565b60405160208183030381529060405290508051602082016000f0925073ffffffffffffffffffffffffffffffffffffffff8316611533576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4445504c4f594d454e545f4641494c4544000000000000000000000000000000604482015260640160405180910390fd5b5050919050565b8154600090819081805b828110156115c357600087828154811061156057611560611b5f565b6000918252602090912001805490915061157e9061ffff1684611c95565b87101561159d57806115908489611e1a565b95509550505050506115f6565b80546115ad9061ffff1684611c95565b92505080806115bb90611c22565b915050611544565b506040517f264a7c1300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9250929050565b8054606090600090611634906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16611430565b60015484546040517f265b7f7e00000000000000000000000000000000000000000000000000000000815292935060009273ffffffffffffffffffffffffffffffffffffffff9092169163265b7f7e916116a591869162010000900469ffffffffffffffffffff1690600401611e98565b600060405180830381865afa1580156116c2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526116ea9190810190611f5b565b915050808060200190518101906117019190611fb0565b949350505050565b60408051603f8301601f19168101909152818152818360208301863c9392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461174e57600080fd5b50565b60006020828403121561176357600080fd5b8135610e7c8161172c565b60006020828403121561178057600080fd5b5035919050565b60005b838110156117a257818101518382015260200161178a565b50506000910152565b600081518084526117c3816020860160208601611787565b601f01601f19169290920160200192915050565b602081526000610e7c60208301846117ab565b803569ffffffffffffffffffff8116811461180457600080fd5b919050565b803561ffff8116811461180457600080fd5b60008060006060848603121561183057600080fd5b833561183b8161172c565b9250611849602085016117ea565b915061185760408501611809565b90509250925092565b6000602080835260608084018551604080858801528282518085526080890191508684019450600093505b808410156118e2578451805161ffff1683528781015169ffffffffffffffffffff168884015283015173ffffffffffffffffffffffffffffffffffffffff168383015293860193600193909301929085019061188b565b5094909701519590960194909452509392505050565b60008083601f84011261190a57600080fd5b50813567ffffffffffffffff81111561192257600080fd5b6020830191508360208285010111156115f657600080fd5b6000806000806060858703121561195057600080fd5b843567ffffffffffffffff81111561196757600080fd5b611973878288016118f8565b90955093506119869050602086016117ea565b915061199460408601611809565b905092959194509250565b600080602083850312156119b257600080fd5b823567ffffffffffffffff8111156119c957600080fd5b6119d5858286016118f8565b90969095509350505050565b803560ff8116811461180457600080fd5b600060208284031215611a0457600080fd5b610e7c826119e1565b60008060408385031215611a2057600080fd5b611a29836119e1565b91506020830135611a398161172c565b809150509250929050565b60008060208385031215611a5757600080fd5b823567ffffffffffffffff80821115611a6f57600080fd5b818501915085601f830112611a8357600080fd5b813581811115611a9257600080fd5b8660208260051b8501011115611aa757600080fd5b60209290920196919550909350505050565b600080600060408486031215611ace57600080fd5b611ad7846119e1565b9250602084013567ffffffffffffffff811115611af357600080fd5b611aff868287016118f8565b9497909650939450505050565b600181811c90821680611b2057607f821691505b602082108103611b59577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611bc357600080fd5b83018035915067ffffffffffffffff821115611bde57600080fd5b6020019150368190038213156115f657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611c5357611c53611bf3565b5060010190565b600082611c90577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b8082018082111561093f5761093f611bf3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b601f82111561142b57600081815260208120601f850160051c81016020861015611cfe5750805b601f850160051c820191505b818110156113a157828155600101611d0a565b67ffffffffffffffff831115611d3557611d35611ca8565b611d4983611d438354611b0c565b83611cd7565b6000601f841160018114611d9b5760008515611d655750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611e13565b600083815260209020601f19861690835b82811015611dcc5786850135825560209485019460019092019101611dac565b5086821015611e07577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8181038181111561093f5761093f611bf3565b6000815260008251611e46816001850160208701611787565b9190910160010192915050565b7f600b5981380380925939f3000000000000000000000000000000000000000000815260008251611e8b81600b850160208701611787565b91909101600b0192915050565b604081526000611eab60408301856117ab565b905069ffffffffffffffffffff831660208301529392505050565b604051601f8201601f1916810167ffffffffffffffff81118282101715611eef57611eef611ca8565b604052919050565b600082601f830112611f0857600080fd5b815167ffffffffffffffff811115611f2257611f22611ca8565b611f356020601f19601f84011601611ec6565b818152846020838601011115611f4a57600080fd5b611701826020830160208701611787565b60008060408385031215611f6e57600080fd5b8251600f8110611f7d57600080fd5b602084015190925067ffffffffffffffff811115611f9a57600080fd5b611fa685828601611ef7565b9150509250929050565b60006020808385031215611fc357600080fd5b825167ffffffffffffffff80821115611fdb57600080fd5b818501915085601f830112611fef57600080fd5b81518181111561200157612001611ca8565b8060051b612010858201611ec6565b918252838101850191858101908984111561202a57600080fd5b86860192505b83831015612066578251858111156120485760008081fd5b6120568b89838a0101611ef7565b8352509186019190860190612030565b999850505050505050505056fea264697066735822122014caa77b46942d38ef86ba579dce3fc901edab7383d602d871fcc1465aefe6aa64736f6c6343000811003300000000000000000000000008d84a6cd9523ddc7a16f94d004db985c3406a70000000000000000000000000992d708d6005e2c1adb9a390e7bd277b3c1efcfc
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101f05760003560e01c806372c84d3f1161010f578063bc2d45fe116100a2578063e79c9ea611610071578063e79c9ea614610457578063f51a8f1e1461046a578063fc362a701461047d578063fd30704b1461048757600080fd5b8063bc2d45fe14610409578063cd2b82501461041c578063e1d46ae61461042f578063e73dd3831461044f57600080fd5b806394f3df61116100de57806394f3df61146103c6578063970b2271146103d9578063aa5bf7d8146103e3578063b982d1b9146103f657600080fd5b806372c84d3f1461035757806373ac736b1461038d5780638bd54c06146103a057806391b7916a146103b357600080fd5b8063368013dc116101875780635a503f13116101565780635a503f13146103145780635c0910be146103275780635e70664c1461033157806372aa4a961461034457600080fd5b8063368013dc146102d357806344cee73c146102db578063461fc5af146102ee57806350d15fbe1461030157600080fd5b806324cde248116101c357806324cde2481461025b57806326ac853b14610273578063303e74df1461027b578063353c36a0146102c057600080fd5b806301b9a397146101f557806304bde4dd1461020a5780631dc9637d14610233578063222a36d014610246575b600080fd5b610208610203366004611751565b61048f565b005b61021d61021836600461176e565b61054e565b60405161022a91906117d7565b60405180910390f35b61020861024136600461181b565b6105fa565b61024e61067c565b60405161022a9190611860565b600b546102659081565b60405190815260200161022a565b61024e610748565b60005461029b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161022a565b6102086102ce36600461193a565b6107fb565b61024e61087f565b61021d6102e936600461176e565b610932565b6102086102fc36600461181b565b610945565b61021d61030f36600461176e565b6109be565b61021d61032236600461176e565b6109cb565b6005546102659081565b61020861033f36600461199f565b6109d8565b610208610352366004611751565b610a4b565b61029b6103653660046119f2565b60036020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b61020861039b36600461181b565b610b02565b6102086103ae366004611a0d565b610b7b565b6102086103c1366004611a44565b610c34565b6102086103d436600461193a565b610ce6565b6007546102659081565b6102086103f136600461193a565b610d60565b61021d61040436600461176e565b610dda565b61021d6104173660046119f2565b610de7565b61020861042a36600461181b565b610e83565b60015461029b9073ffffffffffffffffffffffffffffffffffffffff1681565b61024e610efc565b610208610465366004611ab9565b610faf565b61020861047836600461193a565b611137565b6009546102659081565b600254610265565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104c757604051631b7c44cd60e01b815260040160405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f6a470e5dd4b354979dc3b984575294975f737cb9ee3ae3cca949e998dbc7cee991015b60405180910390a15050565b6002818154811061055e57600080fd5b90600052602060002001600091509050805461057990611b0c565b80601f01602080910402602001604051908101604052809291908181526020018280546105a590611b0c565b80156105f25780601f106105c7576101008083540402835291602001916105f2565b820191906000526020600020905b8154815290600101906020018083116105d557829003601f168201915b505050505081565b60005473ffffffffffffffffffffffffffffffffffffffff16331461063257604051631b7c44cd60e01b815260040160405180910390fd5b61063f600a8484846111b1565b60405161ffff821681527fabb9adb54cb70346506b5d755f568fc186f68d9586d4a0c997f94ac947866b61906020015b60405180910390a1505050565b60408051808201909152606081526000602082015260408051600480546060602082028401810185529383018181529293919284929091849160009085015b82821015610731576000848152602090819020604080516060810182529185015461ffff8116835262010000810469ffffffffffffffffffff16838501526c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16908201528252600190920191016106bb565b505050508152602001600182015481525050905090565b60408051808201909152606081526000602082015260408051600a8054602081028301606090810185529383018181529293919284929091849160009085018215610731576000848152602090819020604080516060810182529185015461ffff8116835262010000810469ffffffffffffffffffff16838501526c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16908201528252600190920191016106bb565b60005473ffffffffffffffffffffffffffffffffffffffff16331461083357604051631b7c44cd60e01b815260040160405180910390fd5b610841600885858585611317565b60405161ffff821681527ffbb56d0e73d76edc5867b20b68684b671a625696e50d8c985c2830fd1566aaec906020015b60405180910390a150505050565b6040805180820190915260608152600060208201526040805160068054602081028301606090810185529383018181529293919284929091849160009085018215610731576000848152602090819020604080516060810182529185015461ffff8116835262010000810469ffffffffffffffffffff16838501526c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16908201528252600190920191016106bb565b606061093f6004836113a9565b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461097d57604051631b7c44cd60e01b815260040160405180910390fd5b61098a60068484846111b1565b60405161ffff821681527fe74953497d5d03198c809f0f4a324019e503e87fef8e2081636487743ae29d629060200161066f565b606061093f600a836113a9565b606061093f6006836113a9565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a1057604051631b7c44cd60e01b815260040160405180910390fd5b610a1a82826113ee565b604051600181527f379976e1287af3c12aafa34c6a1a61b0cbcb9dce67b3b220ece3b474a4a7427690602001610542565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a8357604051631b7c44cd60e01b815260040160405180910390fd5b6001805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527fad22bb31e9e983d055eeb60a03a1e572d4905254640c9ee3cd36c8d6431248309101610542565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b3a57604051631b7c44cd60e01b815260040160405180910390fd5b610b4760088484846111b1565b60405161ffff821681527ffbb56d0e73d76edc5867b20b68684b671a625696e50d8c985c2830fd1566aaec9060200161066f565b60005473ffffffffffffffffffffffffffffffffffffffff163314610bb357604051631b7c44cd60e01b815260040160405180910390fd5b60ff821660008181526003602090815260409182902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861617905590519182527f3469f6a12aa5e5edc4ea6e284300f2621e073fce4374d4673ded8f2ea7c18b4f9101610542565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c6c57604051631b7c44cd60e01b815260040160405180910390fd5b60005b81811015610cb557610ca3838383818110610c8c57610c8c611b5f565b9050602002810190610c9e9190611b8e565b6113ee565b80610cad81611c22565b915050610c6f565b506040518181527f379976e1287af3c12aafa34c6a1a61b0cbcb9dce67b3b220ece3b474a4a7427690602001610542565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d1e57604051631b7c44cd60e01b815260040160405180910390fd5b610d2c600685858585611317565b60405161ffff821681527fe74953497d5d03198c809f0f4a324019e503e87fef8e2081636487743ae29d6290602001610871565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d9857604051631b7c44cd60e01b815260040160405180910390fd5b610da6600485858585611317565b60405161ffff821681527feb09489df35ba64745f59c5a7efc6df50d432df8cfc3708deb7075e3c8a4f76a90602001610871565b606061093f6008836113a9565b60ff811660009081526003602052604090205460609073ffffffffffffffffffffffffffffffffffffffff1680610e4a576040517fafb85d6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ff8316600090815260036020526040902054610e7c9073ffffffffffffffffffffffffffffffffffffffff16611430565b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ebb57604051631b7c44cd60e01b815260040160405180910390fd5b610ec860048484846111b1565b60405161ffff821681527feb09489df35ba64745f59c5a7efc6df50d432df8cfc3708deb7075e3c8a4f76a9060200161066f565b6040805180820190915260608152600060208201526040805160088054602081028301606090810185529383018181529293919284929091849160009085018215610731576000848152602090819020604080516060810182529185015461ffff8116835262010000810469ffffffffffffffffffff16838501526c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16908201528252600190920191016106bb565b60005473ffffffffffffffffffffffffffffffffffffffff163314610fe757604051631b7c44cd60e01b815260040160405180910390fd5b6000819003611022576040517f61273c5200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61102d600382611c5a565b15158061103b575061030081115b15611072576040517fe233eccd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110b182828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061145e92505050565b60ff841660008181526003602090815260409182902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9590951694909417909355519081527f3469f6a12aa5e5edc4ea6e284300f2621e073fce4374d4673ded8f2ea7c18b4f910161066f565b60005473ffffffffffffffffffffffffffffffffffffffff16331461116f57604051631b7c44cd60e01b815260040160405180910390fd5b61117d600a85858585611317565b60405161ffff821681527fabb9adb54cb70346506b5d755f568fc186f68d9586d4a0c997f94ac947866b6190602001610871565b8169ffffffffffffffffffff166000036111f7576040517fcce3526100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8061ffff16600003611235576040517fa0cd7c8a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160608101825261ffff80841680835269ffffffffffffffffffff808716602080860191825273ffffffffffffffffffffffffffffffffffffffff808b169787019788528b5460018181018e5560008e81529384209851989091018054945199519092166c01000000000000000000000000026bffffffffffffffffffffffff9990951662010000027fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009094169790961696909617919091179590951617909255860180549192909161130c908490611c95565b909155505050505050565b6000839003611352576040517fc348b10c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061139385858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061145e92505050565b90506113a1868285856111b1565b505050505050565b60606000806113b8858561153a565b9150915060006113c7836115fd565b90508082815181106113db576113db611b5f565b6020026020010151935050505092915050565b600280546001810182556000919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0161142b828483611d1d565b505050565b606061093f8260016114598173ffffffffffffffffffffffffffffffffffffffff84163b611e1a565b611709565b600080826040516020016114729190611e2d565b60405160208183030381529060405290506000816040516020016114969190611e53565b60405160208183030381529060405290508051602082016000f0925073ffffffffffffffffffffffffffffffffffffffff8316611533576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4445504c4f594d454e545f4641494c4544000000000000000000000000000000604482015260640160405180910390fd5b5050919050565b8154600090819081805b828110156115c357600087828154811061156057611560611b5f565b6000918252602090912001805490915061157e9061ffff1684611c95565b87101561159d57806115908489611e1a565b95509550505050506115f6565b80546115ad9061ffff1684611c95565b92505080806115bb90611c22565b915050611544565b506040517f264a7c1300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9250929050565b8054606090600090611634906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16611430565b60015484546040517f265b7f7e00000000000000000000000000000000000000000000000000000000815292935060009273ffffffffffffffffffffffffffffffffffffffff9092169163265b7f7e916116a591869162010000900469ffffffffffffffffffff1690600401611e98565b600060405180830381865afa1580156116c2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526116ea9190810190611f5b565b915050808060200190518101906117019190611fb0565b949350505050565b60408051603f8301601f19168101909152818152818360208301863c9392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461174e57600080fd5b50565b60006020828403121561176357600080fd5b8135610e7c8161172c565b60006020828403121561178057600080fd5b5035919050565b60005b838110156117a257818101518382015260200161178a565b50506000910152565b600081518084526117c3816020860160208601611787565b601f01601f19169290920160200192915050565b602081526000610e7c60208301846117ab565b803569ffffffffffffffffffff8116811461180457600080fd5b919050565b803561ffff8116811461180457600080fd5b60008060006060848603121561183057600080fd5b833561183b8161172c565b9250611849602085016117ea565b915061185760408501611809565b90509250925092565b6000602080835260608084018551604080858801528282518085526080890191508684019450600093505b808410156118e2578451805161ffff1683528781015169ffffffffffffffffffff168884015283015173ffffffffffffffffffffffffffffffffffffffff168383015293860193600193909301929085019061188b565b5094909701519590960194909452509392505050565b60008083601f84011261190a57600080fd5b50813567ffffffffffffffff81111561192257600080fd5b6020830191508360208285010111156115f657600080fd5b6000806000806060858703121561195057600080fd5b843567ffffffffffffffff81111561196757600080fd5b611973878288016118f8565b90955093506119869050602086016117ea565b915061199460408601611809565b905092959194509250565b600080602083850312156119b257600080fd5b823567ffffffffffffffff8111156119c957600080fd5b6119d5858286016118f8565b90969095509350505050565b803560ff8116811461180457600080fd5b600060208284031215611a0457600080fd5b610e7c826119e1565b60008060408385031215611a2057600080fd5b611a29836119e1565b91506020830135611a398161172c565b809150509250929050565b60008060208385031215611a5757600080fd5b823567ffffffffffffffff80821115611a6f57600080fd5b818501915085601f830112611a8357600080fd5b813581811115611a9257600080fd5b8660208260051b8501011115611aa757600080fd5b60209290920196919550909350505050565b600080600060408486031215611ace57600080fd5b611ad7846119e1565b9250602084013567ffffffffffffffff811115611af357600080fd5b611aff868287016118f8565b9497909650939450505050565b600181811c90821680611b2057607f821691505b602082108103611b59577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611bc357600080fd5b83018035915067ffffffffffffffff821115611bde57600080fd5b6020019150368190038213156115f657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611c5357611c53611bf3565b5060010190565b600082611c90577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b8082018082111561093f5761093f611bf3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b601f82111561142b57600081815260208120601f850160051c81016020861015611cfe5750805b601f850160051c820191505b818110156113a157828155600101611d0a565b67ffffffffffffffff831115611d3557611d35611ca8565b611d4983611d438354611b0c565b83611cd7565b6000601f841160018114611d9b5760008515611d655750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611e13565b600083815260209020601f19861690835b82811015611dcc5786850135825560209485019460019092019101611dac565b5086821015611e07577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8181038181111561093f5761093f611bf3565b6000815260008251611e46816001850160208701611787565b9190910160010192915050565b7f600b5981380380925939f3000000000000000000000000000000000000000000815260008251611e8b81600b850160208701611787565b91909101600b0192915050565b604081526000611eab60408301856117ab565b905069ffffffffffffffffffff831660208301529392505050565b604051601f8201601f1916810167ffffffffffffffff81118282101715611eef57611eef611ca8565b604052919050565b600082601f830112611f0857600080fd5b815167ffffffffffffffff811115611f2257611f22611ca8565b611f356020601f19601f84011601611ec6565b818152846020838601011115611f4a57600080fd5b611701826020830160208701611787565b60008060408385031215611f6e57600080fd5b8251600f8110611f7d57600080fd5b602084015190925067ffffffffffffffff811115611f9a57600080fd5b611fa685828601611ef7565b9150509250929050565b60006020808385031215611fc357600080fd5b825167ffffffffffffffff80821115611fdb57600080fd5b818501915085601f830112611fef57600080fd5b81518181111561200157612001611ca8565b8060051b612010858201611ec6565b918252838101850191858101908984111561202a57600080fd5b86860192505b83831015612066578251858111156120485760008081fd5b6120568b89838a0101611ef7565b8352509186019190860190612030565b999850505050505050505056fea264697066735822122014caa77b46942d38ef86ba579dce3fc901edab7383d602d871fcc1465aefe6aa64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000008d84a6cd9523ddc7a16f94d004db985c3406a70000000000000000000000000992d708d6005e2c1adb9a390e7bd277b3c1efcfc
-----Decoded View---------------
Arg [0] : _descriptor (address): 0x08d84A6cd9523Ddc7a16F94D004Db985C3406a70
Arg [1] : _inflator (address): 0x992d708d6005e2C1ADB9A390E7Bd277B3C1efcFc
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000008d84a6cd9523ddc7a16f94d004db985c3406a70
Arg [1] : 000000000000000000000000992d708d6005e2c1adb9a390e7bd277b3c1efcfc
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 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.