ETH Price: $2,295.89 (+1.40%)

Contract

0x31Cd7378715174e2c5Bd7EDF9984c9bC2A9209Eb
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Settle Auction166510922023-02-17 21:29:35568 days ago1676669375IN
0x31Cd7378...C2A9209Eb
0 ETH0.0094044358.54975414
Bid166499362023-02-17 17:34:11568 days ago1676655251IN
0x31Cd7378...C2A9209Eb
0.3612 ETH0.0031153275.48637471
Settle Auction166498922023-02-17 17:25:23568 days ago1676654723IN
0x31Cd7378...C2A9209Eb
0 ETH0.0298294.3124833
Bid166493392023-02-17 15:34:11568 days ago1676648051IN
0x31Cd7378...C2A9209Eb
0.3612 ETH0.0017003641.20100371
Settle Auction166493152023-02-17 15:29:11568 days ago1676647751IN
0x31Cd7378...C2A9209Eb
0 ETH0.0139920944.25314986
Bid166487582023-02-17 13:34:11568 days ago1676640851IN
0x31Cd7378...C2A9209Eb
0.3612 ETH0.0009587523.23129919
Settle Auction166487032023-02-17 13:23:11568 days ago1676640191IN
0x31Cd7378...C2A9209Eb
0 ETH0.0078810124.92547727
Bid166485902023-02-17 13:00:11568 days ago1676638811IN
0x31Cd7378...C2A9209Eb
0.3612 ETH0.0009416122.81600171
Settle Auction166485442023-02-17 12:50:59568 days ago1676638259IN
0x31Cd7378...C2A9209Eb
0 ETH0.0071753322.69361142
Bid166468982023-02-17 7:17:11568 days ago1676618231IN
0x31Cd7378...C2A9209Eb
0.3612 ETH0.0009198422.28841189
Settle Auction166468872023-02-17 7:14:59568 days ago1676618099IN
0x31Cd7378...C2A9209Eb
0 ETH0.0070270822.05038319
Bid166437922023-02-16 20:51:11569 days ago1676580671IN
0x31Cd7378...C2A9209Eb
0.3612 ETH0.0018224644.15947477
Settle Auction166437682023-02-16 20:46:23569 days ago1676580383IN
0x31Cd7378...C2A9209Eb
0 ETH0.0145693746.07891634
Bid166322172023-02-15 6:00:11570 days ago1676440811IN
0x31Cd7378...C2A9209Eb
0.3612 ETH0.0010420625.24996514
Settle Auction166321832023-02-15 5:53:23570 days ago1676440403IN
0x31Cd7378...C2A9209Eb
0 ETH0.0081119725.45468924
Bid165951012023-02-10 1:34:11576 days ago1675992851IN
0x31Cd7378...C2A9209Eb
0.3612 ETH0.000903621.89506083
Settle Auction165950392023-02-10 1:21:47576 days ago1675992107IN
0x31Cd7378...C2A9209Eb
0 ETH0.0074728323.44912709
Bid165865352023-02-08 20:51:11577 days ago1675889471IN
0x31Cd7378...C2A9209Eb
0.3612 ETH0.0015666337.96064702
Settle Auction165864512023-02-08 20:34:23577 days ago1675888463IN
0x31Cd7378...C2A9209Eb
0 ETH0.0104723233.12109065
Bid165671722023-02-06 3:51:11580 days ago1675655471IN
0x31Cd7378...C2A9209Eb
0.3612 ETH0.0006995216.95005635
Settle Auction165670902023-02-06 3:34:35580 days ago1675654475IN
0x31Cd7378...C2A9209Eb
0 ETH0.0051309616.22782872
Bid165626962023-02-05 12:51:11580 days ago1675601471IN
0x31Cd7378...C2A9209Eb
0.3612 ETH0.0010251724.84076578
Settle Auction165626342023-02-05 12:38:23580 days ago1675600703IN
0x31Cd7378...C2A9209Eb
0 ETH0.0054176117
Bid165612512023-02-05 8:00:11580 days ago1675584011IN
0x31Cd7378...C2A9209Eb
0.3612 ETH0.0009177918.18490879
Bid165612372023-02-05 7:57:23580 days ago1675583843IN
0x31Cd7378...C2A9209Eb
0.004 ETH0.0006968715.92136065
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
166510922023-02-17 21:29:35568 days ago1676669375
0x31Cd7378...C2A9209Eb
0.01806 ETH
166510922023-02-17 21:29:35568 days ago1676669375
0x31Cd7378...C2A9209Eb
0.34314 ETH
166498922023-02-17 17:25:23568 days ago1676654723
0x31Cd7378...C2A9209Eb
0.01806 ETH
166498922023-02-17 17:25:23568 days ago1676654723
0x31Cd7378...C2A9209Eb
0.34314 ETH
166493152023-02-17 15:29:11568 days ago1676647751
0x31Cd7378...C2A9209Eb
0.01806 ETH
166493152023-02-17 15:29:11568 days ago1676647751
0x31Cd7378...C2A9209Eb
0.34314 ETH
166487032023-02-17 13:23:11568 days ago1676640191
0x31Cd7378...C2A9209Eb
0.01806 ETH
166487032023-02-17 13:23:11568 days ago1676640191
0x31Cd7378...C2A9209Eb
0.34314 ETH
166485442023-02-17 12:50:59568 days ago1676638259
0x31Cd7378...C2A9209Eb
0.01806 ETH
166485442023-02-17 12:50:59568 days ago1676638259
0x31Cd7378...C2A9209Eb
0.34314 ETH
166468872023-02-17 7:14:59568 days ago1676618099
0x31Cd7378...C2A9209Eb
0.01806 ETH
166468872023-02-17 7:14:59568 days ago1676618099
0x31Cd7378...C2A9209Eb
0.34314 ETH
166437682023-02-16 20:46:23569 days ago1676580383
0x31Cd7378...C2A9209Eb
0.01806 ETH
166437682023-02-16 20:46:23569 days ago1676580383
0x31Cd7378...C2A9209Eb
0.34314 ETH
166321832023-02-15 5:53:23570 days ago1676440403
0x31Cd7378...C2A9209Eb
0.01806 ETH
166321832023-02-15 5:53:23570 days ago1676440403
0x31Cd7378...C2A9209Eb
0.34314 ETH
165950392023-02-10 1:21:47576 days ago1675992107
0x31Cd7378...C2A9209Eb
0.01806 ETH
165950392023-02-10 1:21:47576 days ago1675992107
0x31Cd7378...C2A9209Eb
0.34314 ETH
165864512023-02-08 20:34:23577 days ago1675888463
0x31Cd7378...C2A9209Eb
0.01806 ETH
165864512023-02-08 20:34:23577 days ago1675888463
0x31Cd7378...C2A9209Eb
0.34314 ETH
165670902023-02-06 3:34:35580 days ago1675654475
0x31Cd7378...C2A9209Eb
0.01806 ETH
165670902023-02-06 3:34:35580 days ago1675654475
0x31Cd7378...C2A9209Eb
0.34314 ETH
165626342023-02-05 12:38:23580 days ago1675600703
0x31Cd7378...C2A9209Eb
0.01806 ETH
165626342023-02-05 12:38:23580 days ago1675600703
0x31Cd7378...C2A9209Eb
0.34314 ETH
165612512023-02-05 8:00:11580 days ago1675584011
0x31Cd7378...C2A9209Eb
0.004 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
NounletAuction

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 24 : NounletAuction.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

import {NounletMinter as Minter, Permission} from "./NounletMinter.sol";
import {NFTReceiver as Receiver} from "../utils/NFTReceiver.sol";
import {ReentrancyGuard} from "@rari-capital/solmate/src/utils/ReentrancyGuard.sol";
import {SafeCastLib} from "@rari-capital/solmate/src/utils/SafeCastLib.sol";
import {Owned} from "@rari-capital/solmate/src/auth/Owned.sol";
import {SafeSend} from "../utils/SafeSend.sol";

import {INounletAuction as IAuction, Auction, Vault} from "../interfaces/INounletAuction.sol";
import {INounletRegistry as IRegistry} from "../interfaces/INounletRegistry.sol";
import {INounletToken as INounlet} from "../interfaces/INounletToken.sol";

/// @title NounletAuction
/// @author Tessera
/// @notice Module contract for holding auctions of newly minted fractions
contract NounletAuction is IAuction, Minter, Receiver, ReentrancyGuard, SafeSend, Owned {
    /// @dev Using safe casting library for uint256 types
    using SafeCastLib for uint256;
    /// @notice Address of NounletRegistry contract
    address public immutable registry;
    /// @notice Duration time of each auction
    uint48 public duration = 25 minutes;
    /// @notice Percentage of minimum bid increase
    uint48 public constant MIN_INCREASE = 5;
    /// @notice Duration time extension for bids placed in final 10 minutes
    uint48 public constant TIME_BUFFER = 5 minutes;
    /// @notice Total supply of Nounlet tokens for each Noun
    uint48 public constant TOTAL_SUPPLY = 100;
    /// @notice Mapping of Vault address to struct of vault curator and current token ID
    mapping(address => Vault) public vaultInfo;
    /// @notice Mapping of Vault address to id to auction struct with bidder, bid amount, and endtime
    mapping(address => mapping(uint256 => Auction)) public auctionInfo;

    /// @dev Initializes NounletRegistry and NounletSupply contracts
    constructor(address _registry, address _supply) Minter(_supply) Owned(msg.sender) {
        registry = _registry;
    }

    function updateDuration(uint48 _duration) external onlyOwner {
        duration = _duration;
    }

    /// @notice Creates a new auction for the first Nounlet of each Noun
    /// @param _vault Address of the vault
    /// @param _curator Address of the Noun owner
    /// @param _mintProof Merkle proof for minting new Nounlets
    function createAuction(
        address _vault,
        address _curator,
        bytes32[] calldata _mintProof
    ) external {
        // Reverts if first token has already been minted
        if (vaultInfo[_vault].currentId != 0) revert AuctionAlreadyCreated();

        // Sets the vault info and mints the first Nounlet
        vaultInfo[_vault] = Vault(_curator, 1);
        _create(_vault, 1, _mintProof);
    }

    /// @notice Settles the current auction and mints the next Nounlet
    /// @param _vault Address of the vault
    /// @param _mintProof Merkle proof for minting new Nounlets
    function settleAuction(address _vault, bytes32[] calldata _mintProof) external nonReentrant {
        // Settles the current auction and increments current ID in memory
        uint256 id = uint256(vaultInfo[_vault].currentId);
        _settle(_vault, id);
        // Mints the next Nounlet if total supply is greater than or equal to current ID
        if (uint256(TOTAL_SUPPLY) >= ++id) _create(_vault, id, _mintProof);
    }

    /// @notice Creates a new bid on the current auction of a given vault
    /// @param _vault Address of the vault
    function bid(address _vault) external payable nonReentrant {
        // Gets the current ID and declares auction info in storage
        uint256 id = uint256(vaultInfo[_vault].currentId);
        Auction storage auction = auctionInfo[_vault][id];
        // Reverts if end time of auction is less than current time
        uint256 endTime = uint256(auction.endTime);
        if (endTime < block.timestamp) revert AuctionExpired();
        // Reverts if current bid is not at least 5% greater than the previous bid
        uint256 ethAmount = auction.amount;
        if (msg.value < ethAmount + ((ethAmount * MIN_INCREASE) / 100)) revert InvalidBidIncrease();

        // Updates auction end time if less than current time plus time buffer of 10 minutes
        address token = IRegistry(registry).vaultToToken(_vault);
        uint256 extendedTime = block.timestamp + TIME_BUFFER;
        if (endTime < extendedTime) auction.endTime = extendedTime.safeCastTo32();

        // Sets bidder and bid amount to auction info in storage
        _sendEthOrWeth(auction.bidder, ethAmount);
        auction.bidder = msg.sender;
        auction.amount = msg.value.safeCastTo64();

        // Emits bid event and transfers bid amount to this contract
        emit Bid(_vault, token, id, msg.sender, msg.value, auction.endTime);
    }

    /// @dev Creates a new auction and initializes auction info
    /// @param _vault Address of the vault
    /// @param _id ID of the token
    /// @param _mintProof Merkle proof for minting new Nounlets
    function _create(
        address _vault,
        uint256 _id,
        bytes32[] calldata _mintProof
    ) internal {
        // Mints a new fraction through NounletMinter module
        _mintFraction(_vault, address(this), _id, _mintProof);

        // Initializes end time and sets first bidder as vault curator
        address token = IRegistry(registry).vaultToToken(_vault);
        uint256 endTime = block.timestamp + duration;
        auctionInfo[_vault][_id].endTime = endTime.safeCastTo32();
        auctionInfo[_vault][_id].bidder = vaultInfo[_vault].curator;

        // Emits event for creating new auction
        emit Created(_vault, token, _id, endTime);
    }

    /// @dev Settles a finished auction
    /// @param _vault Address of the vault
    /// @param _id ID of the token
    function _settle(address _vault, uint256 _id) internal {
        // Reverts if auction end time is greater than current time
        Auction memory auction = auctionInfo[_vault][_id];
        if (uint256(auction.endTime) > block.timestamp) revert AuctionNotCompleted();
        if (uint256(TOTAL_SUPPLY) < _id) revert AuctionExpired();

        // Gets royalty info based on final bid amount
        uint64 bidAmount = auction.amount;
        address token = IRegistry(registry).vaultToToken(_vault);
        (address beneficiary, ) = INounlet(token).royaltyInfo(_id, bidAmount);
        uint256 royaltyAmount = bidAmount / 20;
        //Transfers nounlet to winner
        INounlet(token).transferFrom(address(this), auction.bidder, _id, 1, "");

        // Increments current ID in storage
        ++vaultInfo[_vault].currentId;

        // Transfers bid amount to curator and royalties to creator
        _sendEthOrWeth(vaultInfo[_vault].curator, bidAmount - royaltyAmount);
        _sendEthOrWeth(beneficiary, royaltyAmount);

        // Emits event for settling current auction
        emit Settled(_vault, token, _id, auction.bidder, bidAmount);
    }
}

File 2 of 24 : ISVGRenderer.sol
// SPDX-License-Identifier: GPL-3.0

/// @title Interface for SVGRenderer

/*********************************
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░░░░█████████░░█████████░░░ *
 * ░░░░░░██░░░████░░██░░░████░░░ *
 * ░░██████░░░████████░░░████░░░ *
 * ░░██░░██░░░████░░██░░░████░░░ *
 * ░░██░░██░░░████░░██░░░████░░░ *
 * ░░░░░░█████████░░█████████░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 *********************************/

pragma solidity ^0.8.6;

interface ISVGRenderer {
    struct Part {
        bytes image;
        bytes palette;
    }

    struct SVGParams {
        Part[] parts;
        string background;
    }

    function generateSVG(SVGParams memory params) external view returns (string memory svg);

    function generateSVGPart(Part memory part) external view returns (string memory partialSVG);

    function generateSVGParts(Part[] memory parts) external view returns (string memory partialSVG);
}

File 3 of 24 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 4 of 24 : Owned.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event OwnerUpdated(address indexed user, address indexed newOwner);

    /*//////////////////////////////////////////////////////////////
                            OWNERSHIP STORAGE
    //////////////////////////////////////////////////////////////*/

    address public owner;

    modifier onlyOwner() virtual {
        require(msg.sender == owner, "UNAUTHORIZED");

        _;
    }

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(address _owner) {
        owner = _owner;

        emit OwnerUpdated(address(0), _owner);
    }

    /*//////////////////////////////////////////////////////////////
                             OWNERSHIP LOGIC
    //////////////////////////////////////////////////////////////*/

    function setOwner(address newOwner) public virtual onlyOwner {
        owner = newOwner;

        emit OwnerUpdated(msg.sender, newOwner);
    }
}

File 5 of 24 : ERC1155.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Minimalist and gas efficient standard ERC1155 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol)
abstract contract ERC1155 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event TransferSingle(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 id,
        uint256 amount
    );

    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] amounts
    );

    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    event URI(string value, uint256 indexed id);

    /*//////////////////////////////////////////////////////////////
                             ERC1155 STORAGE
    //////////////////////////////////////////////////////////////*/

    mapping(address => mapping(uint256 => uint256)) public balanceOf;

    mapping(address => mapping(address => bool)) public isApprovedForAll;

    /*//////////////////////////////////////////////////////////////
                             METADATA LOGIC
    //////////////////////////////////////////////////////////////*/

    function uri(uint256 id) public view virtual returns (string memory);

    /*//////////////////////////////////////////////////////////////
                              ERC1155 LOGIC
    //////////////////////////////////////////////////////////////*/

    function setApprovalForAll(address operator, bool approved) public virtual {
        isApprovedForAll[msg.sender][operator] = approved;

        emit ApprovalForAll(msg.sender, operator, approved);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) public virtual {
        require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED");

        balanceOf[from][id] -= amount;
        balanceOf[to][id] += amount;

        emit TransferSingle(msg.sender, from, to, id, amount);

        require(
            to.code.length == 0
                ? to != address(0)
                : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) ==
                    ERC1155TokenReceiver.onERC1155Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) public virtual {
        require(ids.length == amounts.length, "LENGTH_MISMATCH");

        require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED");

        // Storing these outside the loop saves ~15 gas per iteration.
        uint256 id;
        uint256 amount;

        for (uint256 i = 0; i < ids.length; ) {
            id = ids[i];
            amount = amounts[i];

            balanceOf[from][id] -= amount;
            balanceOf[to][id] += amount;

            // An array can't have a total length
            // larger than the max uint256 value.
            unchecked {
                ++i;
            }
        }

        emit TransferBatch(msg.sender, from, to, ids, amounts);

        require(
            to.code.length == 0
                ? to != address(0)
                : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) ==
                    ERC1155TokenReceiver.onERC1155BatchReceived.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function balanceOfBatch(address[] calldata owners, uint256[] calldata ids)
        public
        view
        virtual
        returns (uint256[] memory balances)
    {
        require(owners.length == ids.length, "LENGTH_MISMATCH");

        balances = new uint256[](owners.length);

        // Unchecked because the only math done is incrementing
        // the array index counter which cannot possibly overflow.
        unchecked {
            for (uint256 i = 0; i < owners.length; ++i) {
                balances[i] = balanceOf[owners[i]][ids[i]];
            }
        }
    }

    /*//////////////////////////////////////////////////////////////
                              ERC165 LOGIC
    //////////////////////////////////////////////////////////////*/

    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return
            interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
            interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155
            interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        balanceOf[to][id] += amount;

        emit TransferSingle(msg.sender, address(0), to, id, amount);

        require(
            to.code.length == 0
                ? to != address(0)
                : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, address(0), id, amount, data) ==
                    ERC1155TokenReceiver.onERC1155Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function _batchMint(
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        uint256 idsLength = ids.length; // Saves MLOADs.

        require(idsLength == amounts.length, "LENGTH_MISMATCH");

        for (uint256 i = 0; i < idsLength; ) {
            balanceOf[to][ids[i]] += amounts[i];

            // An array can't have a total length
            // larger than the max uint256 value.
            unchecked {
                ++i;
            }
        }

        emit TransferBatch(msg.sender, address(0), to, ids, amounts);

        require(
            to.code.length == 0
                ? to != address(0)
                : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) ==
                    ERC1155TokenReceiver.onERC1155BatchReceived.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function _batchBurn(
        address from,
        uint256[] memory ids,
        uint256[] memory amounts
    ) internal virtual {
        uint256 idsLength = ids.length; // Saves MLOADs.

        require(idsLength == amounts.length, "LENGTH_MISMATCH");

        for (uint256 i = 0; i < idsLength; ) {
            balanceOf[from][ids[i]] -= amounts[i];

            // An array can't have a total length
            // larger than the max uint256 value.
            unchecked {
                ++i;
            }
        }

        emit TransferBatch(msg.sender, from, address(0), ids, amounts);
    }

    function _burn(
        address from,
        uint256 id,
        uint256 amount
    ) internal virtual {
        balanceOf[from][id] -= amount;

        emit TransferSingle(msg.sender, from, address(0), id, amount);
    }
}

/// @notice A generic interface for a contract which properly accepts ERC1155 tokens.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol)
abstract contract ERC1155TokenReceiver {
    function onERC1155Received(
        address,
        address,
        uint256,
        uint256,
        bytes calldata
    ) external virtual returns (bytes4) {
        return ERC1155TokenReceiver.onERC1155Received.selector;
    }

    function onERC1155BatchReceived(
        address,
        address,
        uint256[] calldata,
        uint256[] calldata,
        bytes calldata
    ) external virtual returns (bytes4) {
        return ERC1155TokenReceiver.onERC1155BatchReceived.selector;
    }
}

File 6 of 24 : ERC20.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 amount);

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    /*//////////////////////////////////////////////////////////////
                            METADATA STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*//////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

    mapping(address => mapping(address => uint256)) public allowance;

    /*//////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }

    /*//////////////////////////////////////////////////////////////
                             EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                keccak256(
                                    "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                ),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                v,
                r,
                s
            );

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount;

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

        emit Transfer(from, address(0), amount);
    }
}

File 7 of 24 : ERC721.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)
abstract contract ERC721 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 indexed id);

    event Approval(address indexed owner, address indexed spender, uint256 indexed id);

    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /*//////////////////////////////////////////////////////////////
                         METADATA STORAGE/LOGIC
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    function tokenURI(uint256 id) public view virtual returns (string memory);

    /*//////////////////////////////////////////////////////////////
                      ERC721 BALANCE/OWNER STORAGE
    //////////////////////////////////////////////////////////////*/

    mapping(uint256 => address) internal _ownerOf;

    mapping(address => uint256) internal _balanceOf;

    function ownerOf(uint256 id) public view virtual returns (address owner) {
        require((owner = _ownerOf[id]) != address(0), "NOT_MINTED");
    }

    function balanceOf(address owner) public view virtual returns (uint256) {
        require(owner != address(0), "ZERO_ADDRESS");

        return _balanceOf[owner];
    }

    /*//////////////////////////////////////////////////////////////
                         ERC721 APPROVAL STORAGE
    //////////////////////////////////////////////////////////////*/

    mapping(uint256 => address) public getApproved;

    mapping(address => mapping(address => bool)) public isApprovedForAll;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(string memory _name, string memory _symbol) {
        name = _name;
        symbol = _symbol;
    }

    /*//////////////////////////////////////////////////////////////
                              ERC721 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 id) public virtual {
        address owner = _ownerOf[id];

        require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED");

        getApproved[id] = spender;

        emit Approval(owner, spender, id);
    }

    function setApprovalForAll(address operator, bool approved) public virtual {
        isApprovedForAll[msg.sender][operator] = approved;

        emit ApprovalForAll(msg.sender, operator, approved);
    }

    function transferFrom(
        address from,
        address to,
        uint256 id
    ) public virtual {
        require(from == _ownerOf[id], "WRONG_FROM");

        require(to != address(0), "INVALID_RECIPIENT");

        require(
            msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],
            "NOT_AUTHORIZED"
        );

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        unchecked {
            _balanceOf[from]--;

            _balanceOf[to]++;
        }

        _ownerOf[id] = to;

        delete getApproved[id];

        emit Transfer(from, to, id);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id
    ) public virtual {
        transferFrom(from, to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        bytes calldata data
    ) public virtual {
        transferFrom(from, to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    /*//////////////////////////////////////////////////////////////
                              ERC165 LOGIC
    //////////////////////////////////////////////////////////////*/

    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return
            interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
            interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721
            interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 id) internal virtual {
        require(to != address(0), "INVALID_RECIPIENT");

        require(_ownerOf[id] == address(0), "ALREADY_MINTED");

        // Counter overflow is incredibly unrealistic.
        unchecked {
            _balanceOf[to]++;
        }

        _ownerOf[id] = to;

        emit Transfer(address(0), to, id);
    }

    function _burn(uint256 id) internal virtual {
        address owner = _ownerOf[id];

        require(owner != address(0), "NOT_MINTED");

        // Ownership check above ensures no underflow.
        unchecked {
            _balanceOf[owner]--;
        }

        delete _ownerOf[id];

        delete getApproved[id];

        emit Transfer(owner, address(0), id);
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL SAFE MINT LOGIC
    //////////////////////////////////////////////////////////////*/

    function _safeMint(address to, uint256 id) internal virtual {
        _mint(to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function _safeMint(
        address to,
        uint256 id,
        bytes memory data
    ) internal virtual {
        _mint(to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }
}

/// @notice A generic interface for a contract which properly accepts ERC721 tokens.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)
abstract contract ERC721TokenReceiver {
    function onERC721Received(
        address,
        address,
        uint256,
        bytes calldata
    ) external virtual returns (bytes4) {
        return ERC721TokenReceiver.onERC721Received.selector;
    }
}

File 8 of 24 : WETH.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

import {ERC20} from "./ERC20.sol";

import {SafeTransferLib} from "../utils/SafeTransferLib.sol";

/// @notice Minimalist and modern Wrapped Ether implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/WETH.sol)
/// @author Inspired by WETH9 (https://github.com/dapphub/ds-weth/blob/master/src/weth9.sol)
contract WETH is ERC20("Wrapped Ether", "WETH", 18) {
    using SafeTransferLib for address;

    event Deposit(address indexed from, uint256 amount);

    event Withdrawal(address indexed to, uint256 amount);

    function deposit() public payable virtual {
        _mint(msg.sender, msg.value);

        emit Deposit(msg.sender, msg.value);
    }

    function withdraw(uint256 amount) public virtual {
        _burn(msg.sender, amount);

        emit Withdrawal(msg.sender, amount);

        msg.sender.safeTransferETH(amount);
    }

    receive() external payable virtual {
        deposit();
    }
}

File 9 of 24 : ReentrancyGuard.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Gas optimized reentrancy protection for smart contracts.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ReentrancyGuard.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
    uint256 private locked = 1;

    modifier nonReentrant() virtual {
        require(locked == 1, "REENTRANCY");

        locked = 2;

        _;

        locked = 1;
    }
}

File 10 of 24 : SafeCastLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Safe unsigned integer casting library that reverts on overflow.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeCastLib.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeCast.sol)
library SafeCastLib {
    function safeCastTo248(uint256 x) internal pure returns (uint248 y) {
        require(x < 1 << 248);

        y = uint248(x);
    }

    function safeCastTo224(uint256 x) internal pure returns (uint224 y) {
        require(x < 1 << 224);

        y = uint224(x);
    }

    function safeCastTo192(uint256 x) internal pure returns (uint192 y) {
        require(x < 1 << 192);

        y = uint192(x);
    }

    function safeCastTo160(uint256 x) internal pure returns (uint160 y) {
        require(x < 1 << 160);

        y = uint160(x);
    }

    function safeCastTo128(uint256 x) internal pure returns (uint128 y) {
        require(x < 1 << 128);

        y = uint128(x);
    }

    function safeCastTo96(uint256 x) internal pure returns (uint96 y) {
        require(x < 1 << 96);

        y = uint96(x);
    }

    function safeCastTo64(uint256 x) internal pure returns (uint64 y) {
        require(x < 1 << 64);

        y = uint64(x);
    }

    function safeCastTo32(uint256 x) internal pure returns (uint32 y) {
        require(x < 1 << 32);

        y = uint32(x);
    }

    function safeCastTo24(uint256 x) internal pure returns (uint24 y) {
        require(x < 1 << 24);

        y = uint24(x);
    }

    function safeCastTo8(uint256 x) internal pure returns (uint8 y) {
        require(x < 1 << 8);

        y = uint8(x);
    }
}

File 11 of 24 : SafeTransferLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

import {ERC20} from "../tokens/ERC20.sol";

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
    /*//////////////////////////////////////////////////////////////
                             ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferETH(address to, uint256 amount) internal {
        bool success;

        assembly {
            // Transfer the ETH and store if it succeeded or not.
            success := call(gas(), to, amount, 0, 0, 0, 0)
        }

        require(success, "ETH_TRANSFER_FAILED");
    }

    /*//////////////////////////////////////////////////////////////
                            ERC20 OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferFrom(
        ERC20 token,
        address from,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), from) // Append the "from" argument.
            mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
            )
        }

        require(success, "TRANSFER_FROM_FAILED");
    }

    function safeTransfer(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "TRANSFER_FAILED");
    }

    function safeApprove(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "APPROVE_FAILED");
    }
}

File 12 of 24 : IModule.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

import {Permission} from "./IVaultRegistry.sol";

/// @dev Interface for generic Module contract
interface IModule {
    function getLeafNodes() external view returns (bytes32[] memory nodes);

    function getPermissions() external view returns (Permission[] memory permissions);
}

File 13 of 24 : INounletAuction.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

import {IModule, Permission} from "./IModule.sol";

/// @dev Auction information
struct Auction {
    // Address of the highest bidder
    address bidder;
    // Amount of the highest bid
    uint64 amount;
    // End time of the auction
    uint32 endTime;
}

/// @dev Vault information
struct Vault {
    // Address of the vault curator
    address curator;
    // Current ID of the token
    uint96 currentId;
}

/// @dev Interface for NounletAuction contract
interface INounletAuction is IModule {
    /// @dev Emitted when the auction has already been created for the first Nounlet of a Noun
    error AuctionAlreadyCreated();
    /// @dev Emitted when the auction has not completed
    error AuctionNotCompleted();
    /// @dev Emitted when the auction has already ended
    error AuctionExpired();
    /// @dev Emitted when the minimum bid increase has not been met
    error InvalidBidIncrease();
    /// @dev Emitted when the caller is the not the auction winner
    error NotWinner();

    /// @dev Event log for creating a new auction
    /// @param _vault Address of the vault
    /// @param _token Address of the token contract
    /// @param _id ID of the token
    /// @param _endTime End time of the auction
    event Created(
        address indexed _vault,
        address indexed _token,
        uint256 indexed _id,
        uint256 _endTime
    );

    /// @dev Event log for bidding on an auction
    /// @param _vault Address of the vault
    /// @param _token Address of the token contract
    /// @param _id ID of the token
    /// @param _bidder Address of the bidder
    /// @param _value Ether value of the current bid
    /// @param _endTime New end time if bid is placed in final 10 minutes
    event Bid(
        address indexed _vault,
        address indexed _token,
        uint256 indexed _id,
        address _bidder,
        uint256 _value,
        uint256 _endTime
    );

    /// @dev Event log for settling a finished auction
    /// @param _vault Address of the vault
    /// @param _token Address of the token contract
    /// @param _id ID of the token
    /// @param _winner Address of the highest bidder at auction end
    /// @param _amount Ether value of the highest bid at auction end
    event Settled(
        address indexed _vault,
        address indexed _token,
        uint256 indexed _id,
        address _winner,
        uint256 _amount
    );

    function duration() external view returns (uint48);

    function MIN_INCREASE() external view returns (uint48);

    function TIME_BUFFER() external view returns (uint48);

    function TOTAL_SUPPLY() external view returns (uint48);

    function auctionInfo(address, uint256)
        external
        view
        returns (
            address bidder,
            uint64 bid,
            uint32 endTime
        );

    function bid(address _vault) external payable;

    function registry() external view returns (address);

    function createAuction(
        address _vault,
        address _curator,
        bytes32[] calldata _mintProof
    ) external;

    function settleAuction(address _vault, bytes32[] calldata _mintProof) external;

    function vaultInfo(address) external view returns (address curator, uint96 currentId);
}

File 14 of 24 : INounletMinter.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

import {IModule, Permission} from "./IModule.sol";

/// @dev Interface for NounletMinter contract
interface INounletMinter is IModule {
    function supply() external view returns (address);
}

File 15 of 24 : INounletRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

/// @dev Interface for NounletRegistry contract
interface INounletRegistry {
    /// @dev Emitted when the caller is not a registered vault
    error UnregisteredVault(address _sender);

    /// @dev Event log for deploying vault
    /// @param _vault Address of the vault
    /// @param _token Address of the token
    event VaultDeployed(address indexed _vault, address indexed _token);

    function batchBurn(address _from, uint256[] memory _ids) external;

    function create(
        bytes32 _merkleRoot,
        address[] memory _plugins,
        bytes4[] memory _selectors,
        address _descriptor,
        uint256 _nounId
    ) external returns (address vault);

    function factory() external view returns (address);

    function implementation() external view returns (address);

    function mint(address _to, uint256 _id) external;

    function nounsToken() external view returns (address);

    function royaltyBeneficiary() external view returns (address);

    function uri(address _vault, uint256 _id) external view returns (string memory);

    function vaultToToken(address) external view returns (address token);
}

File 16 of 24 : INounletSupply.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

/// @dev Interface for NounletSupply target contract
interface INounletSupply {
    function batchBurn(address _from, uint256[] memory _ids) external;

    function mint(address _to, uint256 _id) external;
}

File 17 of 24 : INounletToken.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {INounsSeeder} from "./INounsSeeder.sol";

/// @dev Interface for NounletToken contract
interface INounletToken is IERC165 {
    /// @dev Emitted when deadline for signature has passed
    error SignatureExpired(uint256 _timestamp, uint256 _deadline);
    /// @dev Emitted when caller is not required address
    error InvalidSender(address _required, address _provided);
    /// @dev Emitted when owner signature is invalid
    error InvalidSignature(address _signer, address _owner);

    function NOUNLET_REGISTRY() external pure returns (address);

    function NOUNS_DESCRIPTOR() external pure returns (address);

    function NOUNS_TOKEN_ID() external pure returns (uint256);

    function ROYALTY_BENEFICIARY() external pure returns (address);

    function batchBurn(address _from, uint256[] memory _ids) external;

    function generateSeed(uint256 _id) external view returns (INounsSeeder.Seed memory);

    function mint(
        address _to,
        uint256 _id,
        bytes memory _data
    ) external;

    function permitAll(
        address _owner,
        address _operator,
        bool _approved,
        uint256 _deadline,
        uint8 _v,
        bytes32 _r,
        bytes32 _s
    ) external;

    function royaltyInfo(uint256 _id, uint256 _salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);

    function safeTransferFrom(
        address _from,
        address _to,
        uint256 _id,
        uint256 _amount,
        bytes memory _data
    ) external;

    function safeBatchTransferFrom(
        address _from,
        address _to,
        uint256[] memory _ids,
        uint256[] memory _amounts,
        bytes memory _data
    ) external;

    function transferFrom(
        address _from,
        address _to,
        uint256 _id,
        uint256 _amount,
        bytes memory _data
    ) external;

    function batchTransferFrom(
        address _from,
        address _to,
        uint256[] calldata _ids,
        uint256[] calldata _amounts,
        bytes calldata _data
    ) external;

    function supportsInterface(bytes4 _interfaceId) external view returns (bool);

    function uri(uint256 _id) external view returns (string memory);
}

File 18 of 24 : INounsDescriptor.sol
// SPDX-License-Identifier: GPL-3.0

/// @title Common interface for NounsDescriptor versions, as used by NounsToken and NounsSeeder.

/*********************************
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░░░░█████████░░█████████░░░ *
 * ░░░░░░██░░░████░░██░░░████░░░ *
 * ░░██████░░░████████░░░████░░░ *
 * ░░██░░██░░░████░░██░░░████░░░ *
 * ░░██░░██░░░████░░██░░░████░░░ *
 * ░░░░░░█████████░░█████████░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 *********************************/

pragma solidity ^0.8.13;

import {INounsSeeder} from "./INounsSeeder.sol";
import {ISVGRenderer} from "nouns-contracts/contracts/interfaces/ISVGRenderer.sol";

interface INounsDescriptor {
    function tokenURI(uint256 tokenId, INounsSeeder.Seed memory seed)
        external
        view
        returns (string memory);

    function dataURI(uint256 tokenId, INounsSeeder.Seed memory seed)
        external
        view
        returns (string memory);

    function backgroundCount() external view returns (uint256);

    function bodyCount() external view returns (uint256);

    function accessoryCount() external view returns (uint256);

    function headCount() external view returns (uint256);

    function glassesCount() external view returns (uint256);

    function genericDataURI(
        string calldata name,
        string calldata description,
        INounsSeeder.Seed memory seed
    ) external view returns (string memory);

    function renderer() external view returns (address);

    function art() external view returns (address);

    function getPartsForSeed(INounsSeeder.Seed memory seed)
        external
        view
        returns (ISVGRenderer.Part[] memory);
}

File 19 of 24 : INounsSeeder.sol
// SPDX-License-Identifier: GPL-3.0

/// @title Interface for NounsSeeder

/*********************************
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░░░░█████████░░█████████░░░ *
 * ░░░░░░██░░░████░░██░░░████░░░ *
 * ░░██████░░░████████░░░████░░░ *
 * ░░██░░██░░░████░░██░░░████░░░ *
 * ░░██░░██░░░████░░██░░░████░░░ *
 * ░░░░░░█████████░░█████████░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
 *********************************/

pragma solidity ^0.8.13;

import {INounsDescriptor} from "./INounsDescriptor.sol";

interface INounsSeeder {
    struct Seed {
        uint48 background;
        uint48 body;
        uint48 accessory;
        uint48 head;
        uint48 glasses;
    }

    function generateSeed(uint256 nounId, INounsDescriptor descriptor)
        external
        view
        returns (Seed memory);
}

File 20 of 24 : IVault.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

/// @dev Interface for Vault proxy contract
interface IVault {
    /// @dev Emitted when execution reverted with no reason
    error ExecutionReverted();
    /// @dev Emitted when ownership of the proxy has been renounced
    error Initialized(address _owner, address _newOwner, uint256 _nonce);
    /// @dev Emitted when there is no implementation stored in methods for a function signature
    error MethodNotFound();
    /// @dev Emitted when length of input arrays don't match
    error ArrayMismatch(uint256 _pluginsLength, uint256 _selectorsLength);
    /// @dev Emitted when a plugin selector would overwrite an existing plugin
    error InvalidSelector(bytes4 _selector);
    /// @dev Emitted when the caller is not the owner
    error NotAuthorized(address _caller, address _target, bytes4 _selector);
    /// @dev Emitted when the caller is not the owner
    error NotOwner(address _owner, address _caller);
    /// @dev Emitted when the owner is changed during the DELEGATECALL
    error OwnerChanged(address _originalOwner, address _newOwner);
    /// @dev Emitted when passing an EOA or an undeployed contract as the target
    error TargetInvalid(address _target);

    /// @dev Event log for executing transactions
    /// @param _target Address of target contract
    /// @param _data Transaction data being executed
    /// @param _response Return data of delegatecall
    event Execute(address indexed _target, bytes _data, bytes _response);
    /// @dev Event log for installing plugins
    /// @param _selectors List of function selectors
    /// @param _plugins List of plugin contracts
    event UpdatedPlugins(bytes4[] _selectors, address[] _plugins);

    function execute(
        address _target,
        bytes memory _data,
        bytes32[] memory _proof
    ) external payable returns (bool success, bytes memory response);

    function setPlugins(address[] memory _plugins, bytes4[] memory _selectors) external;

    function methods(bytes4) external view returns (address);

    function MERKLE_ROOT() external view returns (bytes32);

    function OWNER() external view returns (address);

    function FACTORY() external view returns (address);
}

File 21 of 24 : IVaultRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

/// @dev Vault permissions
struct Permission {
    // Address of module contract
    address module;
    // Address of target contract
    address target;
    // Function selector from target contract
    bytes4 selector;
}

/// @dev Vault information
struct VaultInfo {
    // Address of FERC1155 token contract
    address token;
    // ID of the token type
    uint256 id;
}

/// @dev Interface for VaultRegistry contract
interface IVaultRegistry {
    /// @dev Emitted when the caller is not the controller
    error InvalidController(address _controller, address _sender);
    /// @dev Emitted when the caller is not a registered vault
    error UnregisteredVault(address _sender);

    /// @dev Event log for deploying vault
    /// @param _vault Address of the vault
    /// @param _token Address of the token
    /// @param _id Id of the token
    event VaultDeployed(address indexed _vault, address indexed _token, uint256 _id);

    function burn(address _from, uint256 _value) external;

    function create(
        bytes32 _merkleRoot,
        address[] memory _plugins,
        bytes4[] memory _selectors
    ) external returns (address vault);

    function createCollection(
        bytes32 _merkleRoot,
        address[] memory _plugins,
        bytes4[] memory _selectors
    ) external returns (address vault, address token);

    function createCollectionFor(
        bytes32 _merkleRoot,
        address _controller,
        address[] memory _plugins,
        bytes4[] memory _selectors
    ) external returns (address vault, address token);

    function createFor(
        bytes32 _merkleRoot,
        address _owner,
        address[] memory _plugins,
        bytes4[] memory _selectors
    ) external returns (address vault);

    function createInCollection(
        bytes32 _merkleRoot,
        address _token,
        address[] memory _plugins,
        bytes4[] memory _selectors
    ) external returns (address vault);

    function factory() external view returns (address);

    function fNFT() external view returns (address);

    function fNFTImplementation() external view returns (address);

    function mint(address _to, uint256 _value) external;

    function nextId(address) external view returns (uint256);

    function totalSupply(address _vault) external view returns (uint256);

    function uri(address _vault) external view returns (string memory);

    function vaultToToken(address) external view returns (address token, uint256 id);
}

File 22 of 24 : NounletMinter.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

import {INounletMinter as IMinter, Permission} from "../interfaces/INounletMinter.sol";
import {INounletSupply as ISupply} from "../interfaces/INounletSupply.sol";
import {IVault} from "../interfaces/IVault.sol";

/// @title NounletMinter
/// @author Tessera
/// @notice Module contract for minting new fractions
contract NounletMinter is IMinter {
    /// @notice Address of NounletSupply target contract
    address public immutable supply;

    /// @dev Initializes NounletSupply target contract
    constructor(address _supply) {
        supply = _supply;
    }

    /// @notice Gets the list of leaf nodes used to generate a merkle tree
    /// @dev Leaf nodes are hashed permissions of the merkle tree
    /// @return nodes A list of leaf nodes
    function getLeafNodes() external view returns (bytes32[] memory nodes) {
        // Gets list of permissions from this module
        Permission[] memory permissions = getPermissions();
        nodes = new bytes32[](permissions.length);
        for (uint256 i; i < permissions.length; ) {
            // Hashes permission into leaf node
            nodes[i] = keccak256(abi.encode(permissions[i]));
            // Can't overflow since loop is a fixed size
            unchecked {
                ++i;
            }
        }
    }

    /// @notice Gets the list of permissions installed on a vault
    /// @dev Permissions consist of a module contract, target contract, and function selector
    /// @return permissions A list of Permission Structs
    function getPermissions() public view returns (Permission[] memory permissions) {
        permissions = new Permission[](1);
        // Mint function selector from supply contract
        permissions[0] = Permission(address(this), supply, ISupply.mint.selector);
    }

    /// @notice Mints a single fraction
    /// @param _vault Address of the Vault
    /// @param _to Address of the receiver
    /// @param _id ID of the fractional token
    /// @param _mintProof Merkle proof for minting fractions
    function _mintFraction(
        address _vault,
        address _to,
        uint256 _id,
        bytes32[] calldata _mintProof
    ) internal {
        bytes memory data = abi.encodeCall(ISupply.mint, (_to, _id));
        IVault(payable(_vault)).execute(supply, data, _mintProof);
    }
}

File 23 of 24 : NFTReceiver.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

import {ERC721TokenReceiver} from "@rari-capital/solmate/src/tokens/ERC721.sol";
import {ERC1155TokenReceiver} from "@rari-capital/solmate/src/tokens/ERC1155.sol";

/// @title NFT Receiver
/// @author Tessera
/// @notice Plugin contract for handling receipts of non-fungible tokens
contract NFTReceiver is ERC721TokenReceiver, ERC1155TokenReceiver {
    /// @notice Handles the receipt of a single ERC721 token
    function onERC721Received(
        address,
        address,
        uint256,
        bytes calldata
    ) external virtual override returns (bytes4) {
        return ERC721TokenReceiver.onERC721Received.selector;
    }

    /// @notice Handles the receipt of a single ERC1155 token type
    function onERC1155Received(
        address,
        address,
        uint256,
        uint256,
        bytes calldata
    ) external virtual override returns (bytes4) {
        return ERC1155TokenReceiver.onERC1155Received.selector;
    }

    /// @notice Handles the receipt of multiple ERC1155 token types
    function onERC1155BatchReceived(
        address,
        address,
        uint256[] calldata,
        uint256[] calldata,
        bytes calldata
    ) external virtual override returns (bytes4) {
        return ERC1155TokenReceiver.onERC1155BatchReceived.selector;
    }
}

File 24 of 24 : SafeSend.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

import {WETH} from "@rari-capital/solmate/src/tokens/WETH.sol";

/// @title SafeSend
/// @author Tessera
/// @notice Utility contract for sending Ether or WETH value to an address
abstract contract SafeSend {
    /// @notice Address for WETH contract on mainnet
    address payable public constant WETH_ADDRESS =
        payable(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);

    /// @notice Attempts to send ether to an address
    /// @param _to Address attemping to send to
    /// @param _value Amount to send
    /// @return success Status of transfer
    function _attemptETHTransfer(address _to, uint256 _value) internal returns (bool success) {
        // Here increase the gas limit a reasonable amount above the default, and try
        // to send ETH to the recipient.
        // NOTE: This might allow the recipient to attempt a limited reentrancy attack.
        (success, ) = _to.call{value: _value, gas: 30000}("");
    }

    /// @notice Sends eth or weth to an address
    /// @param _to Address to send to
    /// @param _value Amount to send
    function _sendEthOrWeth(address _to, uint256 _value) internal {
        if (!_attemptETHTransfer(_to, _value)) {
            WETH(WETH_ADDRESS).deposit{value: _value}();
            WETH(WETH_ADDRESS).transfer(_to, _value);
        }
    }
}

Settings
{
  "remappings": [
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "@rari-capital/solmate/src/=lib/solmate/src/",
    "base64-sol/=lib/base64/",
    "base64/=lib/base64/",
    "clones-with-immutable-args/=lib/clones-with-immutable-args/",
    "ds-test/=lib/clones-with-immutable-args/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "nouns-contracts/=lib/nouns-monorepo/packages/nouns-contracts/",
    "nouns-monorepo/=lib/nouns-monorepo/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "solmate/=lib/solmate/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_registry","type":"address"},{"internalType":"address","name":"_supply","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AuctionAlreadyCreated","type":"error"},{"inputs":[],"name":"AuctionExpired","type":"error"},{"inputs":[],"name":"AuctionNotCompleted","type":"error"},{"inputs":[],"name":"InvalidBidIncrease","type":"error"},{"inputs":[],"name":"NotWinner","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_vault","type":"address"},{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":true,"internalType":"uint256","name":"_id","type":"uint256"},{"indexed":false,"internalType":"address","name":"_bidder","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_endTime","type":"uint256"}],"name":"Bid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_vault","type":"address"},{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":true,"internalType":"uint256","name":"_id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_endTime","type":"uint256"}],"name":"Created","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_vault","type":"address"},{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":true,"internalType":"uint256","name":"_id","type":"uint256"},{"indexed":false,"internalType":"address","name":"_winner","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Settled","type":"event"},{"inputs":[],"name":"MIN_INCREASE","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TIME_BUFFER","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOTAL_SUPPLY","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH_ADDRESS","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"auctionInfo","outputs":[{"internalType":"address","name":"bidder","type":"address"},{"internalType":"uint64","name":"amount","type":"uint64"},{"internalType":"uint32","name":"endTime","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"bid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_curator","type":"address"},{"internalType":"bytes32[]","name":"_mintProof","type":"bytes32[]"}],"name":"createAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"duration","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLeafNodes","outputs":[{"internalType":"bytes32[]","name":"nodes","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPermissions","outputs":[{"components":[{"internalType":"address","name":"module","type":"address"},{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes4","name":"selector","type":"bytes4"}],"internalType":"struct Permission[]","name":"permissions","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"registry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"bytes32[]","name":"_mintProof","type":"bytes32[]"}],"name":"settleAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"supply","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint48","name":"_duration","type":"uint48"}],"name":"updateDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"vaultInfo","outputs":[{"internalType":"address","name":"curator","type":"address"},{"internalType":"uint96","name":"currentId","type":"uint96"}],"stateMutability":"view","type":"function"}]

60c060405260016000819055805465ffffffffffff60a01b191661017760a21b1790553480156200002f57600080fd5b5060405162001b7638038062001b768339810160408190526200005291620000d2565b6001600160a01b038116608052600180546001600160a01b0319163390811790915560405181906000907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76908290a350506001600160a01b031660a0526200010a565b80516001600160a01b0381168114620000cd57600080fd5b919050565b60008060408385031215620000e657600080fd5b620000f183620000b5565b91506200010160208401620000b5565b90509250929050565b60805160a051611a23620001536000396000818161029e0152818161074701528181610c170152610ec601526000818161017b0152818161091401526111c30152611a236000f3fe60806040526004361061011f5760003560e01c8063902d55a5116100a0578063cbbb4ac511610064578063cbbb4ac5146103c8578063d1d64216146103ea578063e8c6ec5d1461047e578063f23a6e611461049e578063f31022b6146104cb57600080fd5b8063902d55a5146102e05780639164359a146102f55780639cf5453d14610364578063bc197c8114610377578063c3a07df6146103a657600080fd5b806353653131116100e7578063536531311461024157806354da829a1461025757806376d63eea146102775780637b1039991461028c5780638da5cb5b146102c057600080fd5b8063040141e514610124578063047fc9aa146101695780630fb5a6b41461019d57806313af4035146101da578063150b7a02146101fc575b600080fd5b34801561013057600080fd5b5061014c73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561017557600080fd5b5061014c7f000000000000000000000000000000000000000000000000000000000000000081565b3480156101a957600080fd5b506001546101c390600160a01b900465ffffffffffff1681565b60405165ffffffffffff9091168152602001610160565b3480156101e657600080fd5b506101fa6101f53660046112bb565b6104eb565b005b34801561020857600080fd5b50610228610217366004611327565b630a85bd0160e11b95945050505050565b6040516001600160e01b03199091168152602001610160565b34801561024d57600080fd5b506101c361012c81565b34801561026357600080fd5b506101fa6102723660046113dd565b610585565b34801561028357600080fd5b506101c3600581565b34801561029857600080fd5b5061014c7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102cc57600080fd5b5060015461014c906001600160a01b031681565b3480156102ec57600080fd5b506101c3606481565b34801561030157600080fd5b5061033d6103103660046112bb565b6002602052600090815260409020546001600160a01b03811690600160a01b90046001600160601b031682565b604080516001600160a01b0390931683526001600160601b03909116602083015201610160565b6101fa6103723660046112bb565b610626565b34801561038357600080fd5b50610228610392366004611431565b63bc197c8160e01b98975050505050505050565b3480156103b257600080fd5b506103bb6108ba565b6040516101609190611520565b3480156103d457600080fd5b506103dd61096d565b604051610160919061156e565b3480156103f657600080fd5b5061044b6104053660046115a6565b60036020908152600092835260408084209091529082529020546001600160a01b03811690600160a01b81046001600160401b031690600160e01b900463ffffffff1683565b604080516001600160a01b0390941684526001600160401b03909216602084015263ffffffff1690820152606001610160565b34801561048a57600080fd5b506101fa6104993660046115d2565b610a36565b3480156104aa57600080fd5b506102286104b93660046115fa565b63f23a6e6160e01b9695505050505050565b3480156104d757600080fd5b506101fa6104e6366004611675565b610aa9565b6001546001600160a01b031633146105395760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b60448201526064015b60405180910390fd5b600180546001600160a01b0319166001600160a01b03831690811790915560405133907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7690600090a350565b6000546001146105c45760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b6044820152606401610530565b600260008181556001600160a01b03851681526020919091526040902054600160a01b90046001600160601b03166105fc8482610b4f565b610605816116ef565b90506064811161061b5761061b84828585610e97565b505060016000555050565b6000546001146106655760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b6044820152606401610530565b600260008181556001600160a01b0383168152602091825260408082205460038452818320600160a01b9091046001600160601b0316808452935290208054600160e01b900463ffffffff16428110156106d257604051630129799f60e21b815260040160405180910390fd5b8154600160a01b90046001600160401b031660646106f1600583611708565b6106fb919061173d565b6107059082611751565b34101561072557604051630c62a72d60e01b815260040160405180910390fd5b6040516310b467bd60e21b81526001600160a01b0386811660048301526000917f0000000000000000000000000000000000000000000000000000000000000000909116906342d19ef490602401602060405180830381865afa158015610790573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b49190611769565b905060006107c461012c42611751565b9050808410156107f7576107d781611025565b855463ffffffff91909116600160e01b026001600160e01b039091161785555b845461080c906001600160a01b03168461103c565b84546001600160a01b031916331785556108253461113e565b855467ffffffffffffffff60a01b1916600160a01b6001600160401b0392909216919091021780865560408051338152346020820152600160e01b90920463ffffffff169082015286906001600160a01b0384811691908a16907f4f2ba8a69ff33f399774e6b002d84d73ac2da9597030a88251649b17622937e59060600160405180910390a4505060016000555050505050565b604080516001808252818301909252606091816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816108d1575050604080516060810182523081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660208201526340c10f1960e01b91810191909152815191925090829060009061095f5761095f61179c565b602002602001018190525090565b606060006109796108ba565b905080516001600160401b0381111561099457610994611786565b6040519080825280602002602001820160405280156109bd578160200160208202803683370190505b50915060005b8151811015610a31578181815181106109de576109de61179c565b60200260200101516040516020016109f691906117b2565b60405160208183030381529060405280519060200120838281518110610a1e57610a1e61179c565b60209081029190910101526001016109c3565b505090565b6001546001600160a01b03163314610a7f5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610530565b6001805465ffffffffffff909216600160a01b0265ffffffffffff60a01b19909216919091179055565b6001600160a01b038416600090815260026020526040902054600160a01b90046001600160601b031615610aef5760405162ff2cb560e71b815260040160405180910390fd5b6040805180820182526001600160a01b0380861682526001602080840182815289841660009081526002909252949020925193516001600160601b0316600160a01b0293909116929092179055610b499085908484610e97565b50505050565b6001600160a01b038281166000908152600360209081526040808320858452825291829020825160608101845290549384168152600160a01b84046001600160401b031691810191909152600160e01b90920463ffffffff16908201819052421015610bce5760405163857889f760e01b815260040160405180910390fd5b6064821115610bf057604051630129799f60e21b815260040160405180910390fd5b60208101516040516310b467bd60e21b81526001600160a01b0385811660048301526000917f0000000000000000000000000000000000000000000000000000000000000000909116906342d19ef490602401602060405180830381865afa158015610c60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c849190611769565b60405163152a902d60e11b8152600481018690526001600160401b03841660248201529091506000906001600160a01b03831690632a55205a906044016040805180830381865afa158015610cdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0191906117c6565b5090506000610d116014856117f4565b8551604051630605105f60e41b81523060048201526001600160a01b039182166024820152604481018990526001606482015260a06084820152600060a48201526001600160401b0392909216925084169063605105f09060c401600060405180830381600087803b158015610d8657600080fd5b505af1158015610d9a573d6000803e3d6000fd5b505050506001600160a01b03871660009081526002602052604090208054601490610dd490600160a01b90046001600160601b031661181a565b82546001600160601b039182166101009390930a92830291909202199091161790556001600160a01b03808816600090815260026020526040902054610e2d9116610e28836001600160401b038816611840565b61103c565b610e37828261103c565b8451604080516001600160a01b0392831681526001600160401b0387166020820152889280871692908b16917fcc046dcf7bcab520f180b1ec355cd239f42fc28b0e0a8724875b282c2ee42594910160405180910390a450505050505050565b610ea48430858585611155565b6040516310b467bd60e21b81526001600160a01b0385811660048301526000917f0000000000000000000000000000000000000000000000000000000000000000909116906342d19ef490602401602060405180830381865afa158015610f0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f339190611769565b600154909150600090610f5590600160a01b900465ffffffffffff1642611751565b9050610f6081611025565b6001600160a01b0380881660008181526003602090815260408083208b8452808352818420805463ffffffff98909816600160e01b026001600160e01b038916811782558686526002855283862054958e9052919093526001600160a01b03191667ffffffffffffffff60a01b909616959095179184169190911790559151879291851691907f7b5c62c6d40d7529b5a806d3480360990bb603feb8eefc47d0f213c4d4e6e066906110159086815260200190565b60405180910390a4505050505050565b6000640100000000821061103857600080fd5b5090565b6110468282611242565b61113a5773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561109957600080fd5b505af11580156110ad573d6000803e3d6000fd5b505060405163a9059cbb60e01b81526001600160a01b03861660048201526024810185905273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2935063a9059cbb925060440190506020604051808303816000875af1158015611114573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611138919061186c565b505b5050565b600068010000000000000000821061103857600080fd5b6040516001600160a01b03851660248201526044810184905260009060640160408051601f198184030181529181526020820180516001600160e01b03166340c10f1960e01b1790525163601b8af360e01b81529091506001600160a01b0387169063601b8af3906111f1907f0000000000000000000000000000000000000000000000000000000000000000908590889088906004016118b3565b6000604051808303816000875af1158015611210573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611238919081019061192e565b5050505050505050565b6000826001600160a01b03168261753090604051600060405180830381858888f193505050503d8060008114611294576040519150601f19603f3d011682016040523d82523d6000602084013e611299565b606091505b5090949350505050565b6001600160a01b03811681146112b857600080fd5b50565b6000602082840312156112cd57600080fd5b81356112d8816112a3565b9392505050565b60008083601f8401126112f157600080fd5b5081356001600160401b0381111561130857600080fd5b60208301915083602082850101111561132057600080fd5b9250929050565b60008060008060006080868803121561133f57600080fd5b853561134a816112a3565b9450602086013561135a816112a3565b93506040860135925060608601356001600160401b0381111561137c57600080fd5b611388888289016112df565b969995985093965092949392505050565b60008083601f8401126113ab57600080fd5b5081356001600160401b038111156113c257600080fd5b6020830191508360208260051b850101111561132057600080fd5b6000806000604084860312156113f257600080fd5b83356113fd816112a3565b925060208401356001600160401b0381111561141857600080fd5b61142486828701611399565b9497909650939450505050565b60008060008060008060008060a0898b03121561144d57600080fd5b8835611458816112a3565b97506020890135611468816112a3565b965060408901356001600160401b038082111561148457600080fd5b6114908c838d01611399565b909850965060608b01359150808211156114a957600080fd5b6114b58c838d01611399565b909650945060808b01359150808211156114ce57600080fd5b506114db8b828c016112df565b999c989b5096995094979396929594505050565b80516001600160a01b039081168352602080830151909116908301526040908101516001600160e01b031916910152565b6020808252825182820181905260009190848201906040850190845b818110156115625761154f8385516114ef565b928401926060929092019160010161153c565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156115625783518352928401929184019160010161158a565b600080604083850312156115b957600080fd5b82356115c4816112a3565b946020939093013593505050565b6000602082840312156115e457600080fd5b813565ffffffffffff811681146112d857600080fd5b60008060008060008060a0878903121561161357600080fd5b863561161e816112a3565b9550602087013561162e816112a3565b9450604087013593506060870135925060808701356001600160401b0381111561165757600080fd5b61166389828a016112df565b979a9699509497509295939492505050565b6000806000806060858703121561168b57600080fd5b8435611696816112a3565b935060208501356116a6816112a3565b925060408501356001600160401b038111156116c157600080fd5b6116cd87828801611399565b95989497509550505050565b634e487b7160e01b600052601160045260246000fd5b600060018201611701576117016116d9565b5060010190565b6000816000190483118215151615611722576117226116d9565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261174c5761174c611727565b500490565b60008219821115611764576117646116d9565b500190565b60006020828403121561177b57600080fd5b81516112d8816112a3565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b606081016117c082846114ef565b92915050565b600080604083850312156117d957600080fd5b82516117e4816112a3565b6020939093015192949293505050565b60006001600160401b038084168061180e5761180e611727565b92169190910492915050565b60006001600160601b03808316818103611836576118366116d9565b6001019392505050565b600082821015611852576118526116d9565b500390565b8051801515811461186757600080fd5b919050565b60006020828403121561187e57600080fd5b6112d882611857565b60005b838110156118a257818101518382015260200161188a565b83811115610b495750506000910152565b60018060a01b038516815260606020820152600084518060608401526118e0816080850160208901611887565b601f01601f191682018281036080908101604085015281018490526001600160fb1b0384111561190f57600080fd5b8360051b808660a08401376000910160a0019081529695505050505050565b6000806040838503121561194157600080fd5b61194a83611857565b915060208301516001600160401b038082111561196657600080fd5b818501915085601f83011261197a57600080fd5b81518181111561198c5761198c611786565b604051601f8201601f19908116603f011681019083821181831017156119b4576119b4611786565b816040528281528860208487010111156119cd57600080fd5b6119de836020830160208801611887565b8095505050505050925092905056fea264697066735822122012e532fa71e7781e59e42125c4e76d76c8e573cb0ea48415c2dc81ea476dd4b364736f6c634300080d0033000000000000000000000000086bed3c3566c0c65ec15f35783042823a23dec3000000000000000000000000eff9f41ce7f59c60c4efdb9dedfe322a1c680810

Deployed Bytecode

0x60806040526004361061011f5760003560e01c8063902d55a5116100a0578063cbbb4ac511610064578063cbbb4ac5146103c8578063d1d64216146103ea578063e8c6ec5d1461047e578063f23a6e611461049e578063f31022b6146104cb57600080fd5b8063902d55a5146102e05780639164359a146102f55780639cf5453d14610364578063bc197c8114610377578063c3a07df6146103a657600080fd5b806353653131116100e7578063536531311461024157806354da829a1461025757806376d63eea146102775780637b1039991461028c5780638da5cb5b146102c057600080fd5b8063040141e514610124578063047fc9aa146101695780630fb5a6b41461019d57806313af4035146101da578063150b7a02146101fc575b600080fd5b34801561013057600080fd5b5061014c73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561017557600080fd5b5061014c7f000000000000000000000000eff9f41ce7f59c60c4efdb9dedfe322a1c68081081565b3480156101a957600080fd5b506001546101c390600160a01b900465ffffffffffff1681565b60405165ffffffffffff9091168152602001610160565b3480156101e657600080fd5b506101fa6101f53660046112bb565b6104eb565b005b34801561020857600080fd5b50610228610217366004611327565b630a85bd0160e11b95945050505050565b6040516001600160e01b03199091168152602001610160565b34801561024d57600080fd5b506101c361012c81565b34801561026357600080fd5b506101fa6102723660046113dd565b610585565b34801561028357600080fd5b506101c3600581565b34801561029857600080fd5b5061014c7f000000000000000000000000086bed3c3566c0c65ec15f35783042823a23dec381565b3480156102cc57600080fd5b5060015461014c906001600160a01b031681565b3480156102ec57600080fd5b506101c3606481565b34801561030157600080fd5b5061033d6103103660046112bb565b6002602052600090815260409020546001600160a01b03811690600160a01b90046001600160601b031682565b604080516001600160a01b0390931683526001600160601b03909116602083015201610160565b6101fa6103723660046112bb565b610626565b34801561038357600080fd5b50610228610392366004611431565b63bc197c8160e01b98975050505050505050565b3480156103b257600080fd5b506103bb6108ba565b6040516101609190611520565b3480156103d457600080fd5b506103dd61096d565b604051610160919061156e565b3480156103f657600080fd5b5061044b6104053660046115a6565b60036020908152600092835260408084209091529082529020546001600160a01b03811690600160a01b81046001600160401b031690600160e01b900463ffffffff1683565b604080516001600160a01b0390941684526001600160401b03909216602084015263ffffffff1690820152606001610160565b34801561048a57600080fd5b506101fa6104993660046115d2565b610a36565b3480156104aa57600080fd5b506102286104b93660046115fa565b63f23a6e6160e01b9695505050505050565b3480156104d757600080fd5b506101fa6104e6366004611675565b610aa9565b6001546001600160a01b031633146105395760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b60448201526064015b60405180910390fd5b600180546001600160a01b0319166001600160a01b03831690811790915560405133907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7690600090a350565b6000546001146105c45760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b6044820152606401610530565b600260008181556001600160a01b03851681526020919091526040902054600160a01b90046001600160601b03166105fc8482610b4f565b610605816116ef565b90506064811161061b5761061b84828585610e97565b505060016000555050565b6000546001146106655760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b6044820152606401610530565b600260008181556001600160a01b0383168152602091825260408082205460038452818320600160a01b9091046001600160601b0316808452935290208054600160e01b900463ffffffff16428110156106d257604051630129799f60e21b815260040160405180910390fd5b8154600160a01b90046001600160401b031660646106f1600583611708565b6106fb919061173d565b6107059082611751565b34101561072557604051630c62a72d60e01b815260040160405180910390fd5b6040516310b467bd60e21b81526001600160a01b0386811660048301526000917f000000000000000000000000086bed3c3566c0c65ec15f35783042823a23dec3909116906342d19ef490602401602060405180830381865afa158015610790573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b49190611769565b905060006107c461012c42611751565b9050808410156107f7576107d781611025565b855463ffffffff91909116600160e01b026001600160e01b039091161785555b845461080c906001600160a01b03168461103c565b84546001600160a01b031916331785556108253461113e565b855467ffffffffffffffff60a01b1916600160a01b6001600160401b0392909216919091021780865560408051338152346020820152600160e01b90920463ffffffff169082015286906001600160a01b0384811691908a16907f4f2ba8a69ff33f399774e6b002d84d73ac2da9597030a88251649b17622937e59060600160405180910390a4505060016000555050505050565b604080516001808252818301909252606091816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816108d1575050604080516060810182523081526001600160a01b037f000000000000000000000000eff9f41ce7f59c60c4efdb9dedfe322a1c6808101660208201526340c10f1960e01b91810191909152815191925090829060009061095f5761095f61179c565b602002602001018190525090565b606060006109796108ba565b905080516001600160401b0381111561099457610994611786565b6040519080825280602002602001820160405280156109bd578160200160208202803683370190505b50915060005b8151811015610a31578181815181106109de576109de61179c565b60200260200101516040516020016109f691906117b2565b60405160208183030381529060405280519060200120838281518110610a1e57610a1e61179c565b60209081029190910101526001016109c3565b505090565b6001546001600160a01b03163314610a7f5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610530565b6001805465ffffffffffff909216600160a01b0265ffffffffffff60a01b19909216919091179055565b6001600160a01b038416600090815260026020526040902054600160a01b90046001600160601b031615610aef5760405162ff2cb560e71b815260040160405180910390fd5b6040805180820182526001600160a01b0380861682526001602080840182815289841660009081526002909252949020925193516001600160601b0316600160a01b0293909116929092179055610b499085908484610e97565b50505050565b6001600160a01b038281166000908152600360209081526040808320858452825291829020825160608101845290549384168152600160a01b84046001600160401b031691810191909152600160e01b90920463ffffffff16908201819052421015610bce5760405163857889f760e01b815260040160405180910390fd5b6064821115610bf057604051630129799f60e21b815260040160405180910390fd5b60208101516040516310b467bd60e21b81526001600160a01b0385811660048301526000917f000000000000000000000000086bed3c3566c0c65ec15f35783042823a23dec3909116906342d19ef490602401602060405180830381865afa158015610c60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c849190611769565b60405163152a902d60e11b8152600481018690526001600160401b03841660248201529091506000906001600160a01b03831690632a55205a906044016040805180830381865afa158015610cdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0191906117c6565b5090506000610d116014856117f4565b8551604051630605105f60e41b81523060048201526001600160a01b039182166024820152604481018990526001606482015260a06084820152600060a48201526001600160401b0392909216925084169063605105f09060c401600060405180830381600087803b158015610d8657600080fd5b505af1158015610d9a573d6000803e3d6000fd5b505050506001600160a01b03871660009081526002602052604090208054601490610dd490600160a01b90046001600160601b031661181a565b82546001600160601b039182166101009390930a92830291909202199091161790556001600160a01b03808816600090815260026020526040902054610e2d9116610e28836001600160401b038816611840565b61103c565b610e37828261103c565b8451604080516001600160a01b0392831681526001600160401b0387166020820152889280871692908b16917fcc046dcf7bcab520f180b1ec355cd239f42fc28b0e0a8724875b282c2ee42594910160405180910390a450505050505050565b610ea48430858585611155565b6040516310b467bd60e21b81526001600160a01b0385811660048301526000917f000000000000000000000000086bed3c3566c0c65ec15f35783042823a23dec3909116906342d19ef490602401602060405180830381865afa158015610f0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f339190611769565b600154909150600090610f5590600160a01b900465ffffffffffff1642611751565b9050610f6081611025565b6001600160a01b0380881660008181526003602090815260408083208b8452808352818420805463ffffffff98909816600160e01b026001600160e01b038916811782558686526002855283862054958e9052919093526001600160a01b03191667ffffffffffffffff60a01b909616959095179184169190911790559151879291851691907f7b5c62c6d40d7529b5a806d3480360990bb603feb8eefc47d0f213c4d4e6e066906110159086815260200190565b60405180910390a4505050505050565b6000640100000000821061103857600080fd5b5090565b6110468282611242565b61113a5773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561109957600080fd5b505af11580156110ad573d6000803e3d6000fd5b505060405163a9059cbb60e01b81526001600160a01b03861660048201526024810185905273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2935063a9059cbb925060440190506020604051808303816000875af1158015611114573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611138919061186c565b505b5050565b600068010000000000000000821061103857600080fd5b6040516001600160a01b03851660248201526044810184905260009060640160408051601f198184030181529181526020820180516001600160e01b03166340c10f1960e01b1790525163601b8af360e01b81529091506001600160a01b0387169063601b8af3906111f1907f000000000000000000000000eff9f41ce7f59c60c4efdb9dedfe322a1c680810908590889088906004016118b3565b6000604051808303816000875af1158015611210573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611238919081019061192e565b5050505050505050565b6000826001600160a01b03168261753090604051600060405180830381858888f193505050503d8060008114611294576040519150601f19603f3d011682016040523d82523d6000602084013e611299565b606091505b5090949350505050565b6001600160a01b03811681146112b857600080fd5b50565b6000602082840312156112cd57600080fd5b81356112d8816112a3565b9392505050565b60008083601f8401126112f157600080fd5b5081356001600160401b0381111561130857600080fd5b60208301915083602082850101111561132057600080fd5b9250929050565b60008060008060006080868803121561133f57600080fd5b853561134a816112a3565b9450602086013561135a816112a3565b93506040860135925060608601356001600160401b0381111561137c57600080fd5b611388888289016112df565b969995985093965092949392505050565b60008083601f8401126113ab57600080fd5b5081356001600160401b038111156113c257600080fd5b6020830191508360208260051b850101111561132057600080fd5b6000806000604084860312156113f257600080fd5b83356113fd816112a3565b925060208401356001600160401b0381111561141857600080fd5b61142486828701611399565b9497909650939450505050565b60008060008060008060008060a0898b03121561144d57600080fd5b8835611458816112a3565b97506020890135611468816112a3565b965060408901356001600160401b038082111561148457600080fd5b6114908c838d01611399565b909850965060608b01359150808211156114a957600080fd5b6114b58c838d01611399565b909650945060808b01359150808211156114ce57600080fd5b506114db8b828c016112df565b999c989b5096995094979396929594505050565b80516001600160a01b039081168352602080830151909116908301526040908101516001600160e01b031916910152565b6020808252825182820181905260009190848201906040850190845b818110156115625761154f8385516114ef565b928401926060929092019160010161153c565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156115625783518352928401929184019160010161158a565b600080604083850312156115b957600080fd5b82356115c4816112a3565b946020939093013593505050565b6000602082840312156115e457600080fd5b813565ffffffffffff811681146112d857600080fd5b60008060008060008060a0878903121561161357600080fd5b863561161e816112a3565b9550602087013561162e816112a3565b9450604087013593506060870135925060808701356001600160401b0381111561165757600080fd5b61166389828a016112df565b979a9699509497509295939492505050565b6000806000806060858703121561168b57600080fd5b8435611696816112a3565b935060208501356116a6816112a3565b925060408501356001600160401b038111156116c157600080fd5b6116cd87828801611399565b95989497509550505050565b634e487b7160e01b600052601160045260246000fd5b600060018201611701576117016116d9565b5060010190565b6000816000190483118215151615611722576117226116d9565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261174c5761174c611727565b500490565b60008219821115611764576117646116d9565b500190565b60006020828403121561177b57600080fd5b81516112d8816112a3565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b606081016117c082846114ef565b92915050565b600080604083850312156117d957600080fd5b82516117e4816112a3565b6020939093015192949293505050565b60006001600160401b038084168061180e5761180e611727565b92169190910492915050565b60006001600160601b03808316818103611836576118366116d9565b6001019392505050565b600082821015611852576118526116d9565b500390565b8051801515811461186757600080fd5b919050565b60006020828403121561187e57600080fd5b6112d882611857565b60005b838110156118a257818101518382015260200161188a565b83811115610b495750506000910152565b60018060a01b038516815260606020820152600084518060608401526118e0816080850160208901611887565b601f01601f191682018281036080908101604085015281018490526001600160fb1b0384111561190f57600080fd5b8360051b808660a08401376000910160a0019081529695505050505050565b6000806040838503121561194157600080fd5b61194a83611857565b915060208301516001600160401b038082111561196657600080fd5b818501915085601f83011261197a57600080fd5b81518181111561198c5761198c611786565b604051601f8201601f19908116603f011681019083821181831017156119b4576119b4611786565b816040528281528860208487010111156119cd57600080fd5b6119de836020830160208801611887565b8095505050505050925092905056fea264697066735822122012e532fa71e7781e59e42125c4e76d76c8e573cb0ea48415c2dc81ea476dd4b364736f6c634300080d0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000086bed3c3566c0c65ec15f35783042823a23dec3000000000000000000000000eff9f41ce7f59c60c4efdb9dedfe322a1c680810

-----Decoded View---------------
Arg [0] : _registry (address): 0x086bEd3c3566C0C65EC15f35783042823A23deC3
Arg [1] : _supply (address): 0xEFf9f41CE7f59C60C4EFdb9dedfe322A1c680810

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000086bed3c3566c0c65ec15f35783042823a23dec3
Arg [1] : 000000000000000000000000eff9f41ce7f59c60c4efdb9dedfe322a1c680810


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ 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.