ETH Price: $3,837.45 (+5.70%)

Contract

0x0accf637e4F05eeA8B1D215C8C9e9E576dC63D33
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Age:24H
Reset Filter

Transaction Hash
Method
Block
From
To

There are no matching entries

Update your filters to view other transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
160889632022-12-01 9:08:23741 days ago1669885703
0x0accf637...76dC63D33
 Contract Creation0 ETH
160888922022-12-01 8:53:59741 days ago1669884839
0x0accf637...76dC63D33
 Contract Creation0 ETH
160888742022-12-01 8:50:23741 days ago1669884623
0x0accf637...76dC63D33
 Contract Creation0 ETH
160888322022-12-01 8:41:59741 days ago1669884119
0x0accf637...76dC63D33
 Contract Creation0 ETH
160888052022-12-01 8:36:35741 days ago1669883795
0x0accf637...76dC63D33
 Contract Creation0 ETH
160887752022-12-01 8:30:35741 days ago1669883435
0x0accf637...76dC63D33
 Contract Creation0 ETH
160887302022-12-01 8:21:35741 days ago1669882895
0x0accf637...76dC63D33
 Contract Creation0 ETH
160886962022-12-01 8:14:47741 days ago1669882487
0x0accf637...76dC63D33
 Contract Creation0 ETH
160886402022-12-01 8:03:35741 days ago1669881815
0x0accf637...76dC63D33
 Contract Creation0 ETH
160886042022-12-01 7:56:23741 days ago1669881383
0x0accf637...76dC63D33
 Contract Creation0 ETH
160741512022-11-29 7:27:35743 days ago1669706855
0x0accf637...76dC63D33
 Contract Creation0 ETH
160740842022-11-29 7:14:11743 days ago1669706051
0x0accf637...76dC63D33
 Contract Creation0 ETH
160617982022-11-27 14:03:47745 days ago1669557827
0x0accf637...76dC63D33
 Contract Creation0 ETH
160168722022-11-21 7:23:11751 days ago1669015391
0x0accf637...76dC63D33
 Contract Creation0 ETH
159711002022-11-14 21:55:47758 days ago1668462947
0x0accf637...76dC63D33
 Contract Creation0 ETH
159170782022-11-07 8:53:35765 days ago1667811215
0x0accf637...76dC63D33
 Contract Creation0 ETH
158452902022-10-28 8:13:59775 days ago1666944839
0x0accf637...76dC63D33
 Contract Creation0 ETH
158445762022-10-28 5:50:23775 days ago1666936223
0x0accf637...76dC63D33
 Contract Creation0 ETH
158398872022-10-27 14:03:59776 days ago1666879439
0x0accf637...76dC63D33
 Contract Creation0 ETH
158092952022-10-23 7:23:35780 days ago1666509815
0x0accf637...76dC63D33
 Contract Creation0 ETH
157324462022-10-12 13:51:47791 days ago1665582707
0x0accf637...76dC63D33
 Contract Creation0 ETH
157198782022-10-10 19:46:35793 days ago1665431195
0x0accf637...76dC63D33
 Contract Creation0 ETH
156867352022-10-06 4:39:59797 days ago1665031199
0x0accf637...76dC63D33
 Contract Creation0 ETH
156597232022-10-02 10:00:11801 days ago1664704811
0x0accf637...76dC63D33
 Contract Creation0 ETH
156594402022-10-02 9:03:23801 days ago1664701403
0x0accf637...76dC63D33
 Contract Creation0 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PartyBidFactory

Compiler Version
v0.8.5+commit.a4f2e591

Optimization Enabled:
Yes with 999999 runs

Other Settings:
default evmVersion
File 1 of 17 : PartyBidFactory.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.5;

import {InitializedProxy} from "./InitializedProxy.sol";
import {PartyBid} from "./PartyBid.sol";
import {Structs} from "./Structs.sol";

/**
 * @title PartyBid Factory
 * @author Anna Carroll
 *
 * WARNING: A malicious MarketWrapper contract could be used to steal user funds;
 * A poorly implemented MarketWrapper contract could permanently lose access to the NFT.
 * When deploying a PartyBid, exercise extreme caution.
 * Only use MarketWrapper contracts that have been audited and tested.
 */
contract PartyBidFactory {
    //======== Events ========

    event PartyBidDeployed(
        address partyBidProxy,
        address creator,
        address nftContract,
        uint256 tokenId,
        address marketWrapper,
        uint256 auctionId,
        address splitRecipient,
        uint256 splitBasisPoints,
        address gatedToken,
        uint256 gatedTokenAmount,
        string name,
        string symbol
    );

    //======== Immutable storage =========

    address public immutable logic;
    address public immutable partyDAOMultisig;
    address public immutable tokenVaultFactory;
    address public immutable weth;

    //======== Mutable storage =========

    // PartyBid proxy => block number deployed at
    mapping(address => uint256) public deployedAt;

    //======== Constructor =========

    constructor(
        address _partyDAOMultisig,
        address _tokenVaultFactory,
        address _weth
    ) {
        partyDAOMultisig = _partyDAOMultisig;
        tokenVaultFactory = _tokenVaultFactory;
        weth = _weth;
        // deploy logic contract
        PartyBid _logicContract = new PartyBid(_partyDAOMultisig, _tokenVaultFactory, _weth);
        // store logic contract address
        logic = address(_logicContract);
    }

    //======== Deploy function =========

    function startParty(
        address _marketWrapper,
        address _nftContract,
        uint256 _tokenId,
        uint256 _auctionId,
        Structs.AddressAndAmount calldata _split,
        Structs.AddressAndAmount calldata _tokenGate,
        string memory _name,
        string memory _symbol
    ) external returns (address partyBidProxy) {
        bytes memory _initializationCalldata =
            abi.encodeWithSelector(
                PartyBid.initialize.selector,
                _marketWrapper,
                _nftContract,
                _tokenId,
                _auctionId,
                _split,
                _tokenGate,
                _name,
                _symbol
            );

        partyBidProxy = address(
            new InitializedProxy(
                logic,
                _initializationCalldata
            )
        );

        deployedAt[partyBidProxy] = block.number;

        emit PartyBidDeployed(
            partyBidProxy,
            msg.sender,
            _nftContract,
            _tokenId,
            _marketWrapper,
            _auctionId,
            _split.addr,
            _split.amount,
            _tokenGate.addr,
            _tokenGate.amount,
            _name,
            _symbol
        );
    }
}

File 2 of 17 : InitializedProxy.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.5;

/**
 * @title InitializedProxy
 * @author Anna Carroll
 */
contract InitializedProxy {
    // address of logic contract
    address public immutable logic;

    // ======== Constructor =========

    constructor(
        address _logic,
        bytes memory _initializationCalldata
    ) {
        logic = _logic;
        // Delegatecall into the logic contract, supplying initialization calldata
        (bool _ok, bytes memory returnData) =
            _logic.delegatecall(_initializationCalldata);
        // Revert if delegatecall to implementation reverts
        require(_ok, string(returnData));
    }

    // ======== Fallback =========

    fallback() external payable {
        address _impl = logic;
        assembly {
            let ptr := mload(0x40)
            calldatacopy(ptr, 0, calldatasize())
            let result := delegatecall(gas(), _impl, ptr, calldatasize(), 0, 0)
            let size := returndatasize()
            returndatacopy(ptr, 0, size)

            switch result
                case 0 {
                    revert(ptr, size)
                }
                default {
                    return(ptr, size)
                }
        }
    }

    // ======== Receive =========

    receive() external payable {} // solhint-disable-line no-empty-blocks
}

File 3 of 17 : PartyBid.sol
/*

      ___           ___           ___           ___           ___           ___                       ___
     /\  \         /\  \         /\  \         /\  \         |\__\         /\  \          ___        /\  \
    /::\  \       /::\  \       /::\  \        \:\  \        |:|  |       /::\  \        /\  \      /::\  \
   /:/\:\  \     /:/\:\  \     /:/\:\  \        \:\  \       |:|  |      /:/\:\  \       \:\  \    /:/\:\  \
  /::\~\:\  \   /::\~\:\  \   /::\~\:\  \       /::\  \      |:|__|__   /::\~\:\__\      /::\__\  /:/  \:\__\
 /:/\:\ \:\__\ /:/\:\ \:\__\ /:/\:\ \:\__\     /:/\:\__\     /::::\__\ /:/\:\ \:|__|  __/:/\/__/ /:/__/ \:|__|
 \/__\:\/:/  / \/__\:\/:/  / \/_|::\/:/  /    /:/  \/__/    /:/~~/~    \:\~\:\/:/  / /\/:/  /    \:\  \ /:/  /
      \::/  /       \::/  /     |:|::/  /    /:/  /        /:/  /       \:\ \::/  /  \::/__/      \:\  /:/  /
       \/__/        /:/  /      |:|\/__/     \/__/         \/__/         \:\/:/  /    \:\__\       \:\/:/  /
                   /:/  /       |:|  |                                    \::/__/      \/__/        \::/__/
                   \/__/         \|__|                                     ~~                        ~~

Anna Carroll for PartyDAO
*/

// SPDX-License-Identifier: MIT
pragma solidity 0.8.5;

// ============ Internal Imports ============
import {Party} from "./Party.sol";
import {IMarketWrapper} from "./market-wrapper/IMarketWrapper.sol";
import {Structs} from "./Structs.sol";

contract PartyBid is Party {
    // partyStatus Transitions:
    //   (1) PartyStatus.ACTIVE on deploy
    //   (2) PartyStatus.WON or PartyStatus.LOST on finalize()

    // ============ Internal Constants ============

    // PartyBid version 3
    uint16 public constant VERSION = 3;

    // ============ Public Not-Mutated Storage ============

    // market wrapper contract exposing interface for
    // market auctioning the NFT
    IMarketWrapper public marketWrapper;
    // ID of auction within market contract
    uint256 public auctionId;

    // ============ Public Mutable Storage ============

    // the highest bid submitted by PartyBid
    uint256 public highestBid;

    // ============ Events ============

    event Bid(uint256 amount);

    event Finalized(PartyStatus result, uint256 totalSpent, uint256 fee, uint256 totalContributed);

    // ======== Constructor =========

    constructor(
        address _partyDAOMultisig,
        address _tokenVaultFactory,
        address _weth
    ) Party(_partyDAOMultisig, _tokenVaultFactory, _weth) {}

    // ======== Initializer =========

    function initialize(
        address _marketWrapper,
        address _nftContract,
        uint256 _tokenId,
        uint256 _auctionId,
        Structs.AddressAndAmount calldata _split,
        Structs.AddressAndAmount calldata _tokenGate,
        string memory _name,
        string memory _symbol
    ) external initializer {
        // validate auction exists
        require(
            IMarketWrapper(_marketWrapper).auctionIdMatchesToken(
                _auctionId,
                _nftContract,
                _tokenId
            ),
            "PartyBid::initialize: auctionId doesn't match token"
        );
        // initialize & validate shared Party variables
        __Party_init(_nftContract, _tokenId, _split, _tokenGate, _name, _symbol);
        // set PartyBid-specific state variables
        marketWrapper = IMarketWrapper(_marketWrapper);
        auctionId = _auctionId;
    }

    // ======== External: Contribute =========

    /**
     * @notice Contribute to the Party's treasury
     * while the Party is still active
     * @dev Emits a Contributed event upon success; callable by anyone
     */
    function contribute() external payable nonReentrant {
        _contribute();
    }

    // ======== External: Bid =========

    /**
     * @notice Submit a bid to the Market
     * @dev Reverts if insufficient funds to place the bid and pay PartyDAO fees,
     * or if any external auction checks fail (including if PartyBid is current high bidder)
     * Emits a Bid event upon success.
     * Callable by any contributor
     */
    function bid() external nonReentrant {
        require(
            partyStatus == PartyStatus.ACTIVE,
            "PartyBid::bid: auction not active"
        );
        require(
            totalContributed[msg.sender] > 0,
            "PartyBid::bid: only contributors can bid"
        );
        require(
            address(this) !=
                marketWrapper.getCurrentHighestBidder(
                    auctionId
                ),
            "PartyBid::bid: already highest bidder"
        );
        require(
            !marketWrapper.isFinalized(auctionId),
            "PartyBid::bid: auction already finalized"
        );
        // get the minimum next bid for the auction
        uint256 _bid = marketWrapper.getMinimumBid(auctionId);
        // ensure there is enough ETH to place the bid including PartyDAO fee
        require(
            _bid <= getMaximumBid(),
            "PartyBid::bid: insufficient funds to bid"
        );
        // submit bid to Auction contract using delegatecall
        (bool success, bytes memory returnData) =
            address(marketWrapper).delegatecall(
                abi.encodeWithSignature("bid(uint256,uint256)", auctionId, _bid)
            );
        require(
            success,
            string(
                abi.encodePacked(
                    "PartyBid::bid: place bid failed: ",
                    returnData
                )
            )
        );
        // update highest bid submitted & emit success event
        highestBid = _bid;
        emit Bid(_bid);
    }

    // ======== External: Finalize =========

    /**
     * @notice Finalize the state of the auction
     * @dev Emits a Finalized event upon success; callable by anyone
     */
    function finalize() external nonReentrant {
        require(
            partyStatus == PartyStatus.ACTIVE,
            "PartyBid::finalize: auction not active"
        );
        // finalize auction if it hasn't already been done
        if (!marketWrapper.isFinalized(auctionId)) {
            marketWrapper.finalize(auctionId);
        }
        // after the auction has been finalized,
        // if the NFT is owned by the PartyBid, then the PartyBid won the auction
        address _owner = _getOwner();
        partyStatus = _owner == address(this) ? PartyStatus.WON : PartyStatus.LOST;
        uint256 _ethFee;
        // if the auction was won,
        if (partyStatus == PartyStatus.WON) {
            // record totalSpent,
            // send ETH fees to PartyDAO,
            // fractionalize the Token
            // send Token fees to PartyDAO & split proceeds to split recipient
            _ethFee = _closeSuccessfulParty(highestBid);
        }
        // set the contract status & emit result
        emit Finalized(partyStatus, totalSpent, _ethFee, totalContributedToParty);
    }

    // ======== Public: Utility Calculations =========

    /**
     * @notice The maximum bid that can be submitted
     * while paying the ETH fee to PartyDAO
     * @return _maxBid the maximum bid
     */
    function getMaximumBid() public view returns (uint256 _maxBid) {
        _maxBid = getMaximumSpend();
    }
}

File 4 of 17 : Structs.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.5;

interface Structs {
    struct AddressAndAmount {
        address addr;
        uint256 amount;
    }
}

File 5 of 17 : Party.sol
/*
__/\\\\\\\\\\\\\_____________________________________________________________/\\\\\\\\\\\\________/\\\\\\\\\__________/\\\\\______
 _\/\\\/////////\\\__________________________________________________________\/\\\////////\\\____/\\\\\\\\\\\\\______/\\\///\\\____
  _\/\\\_______\/\\\__________________________________/\\\_________/\\\__/\\\_\/\\\______\//\\\__/\\\/////////\\\___/\\\/__\///\\\__
   _\/\\\\\\\\\\\\\/___/\\\\\\\\\_____/\\/\\\\\\\___/\\\\\\\\\\\___\//\\\/\\\__\/\\\_______\/\\\_\/\\\_______\/\\\__/\\\______\//\\\_
    _\/\\\/////////____\////////\\\___\/\\\/////\\\_\////\\\////_____\//\\\\\___\/\\\_______\/\\\_\/\\\\\\\\\\\\\\\_\/\\\_______\/\\\_
     _\/\\\_______________/\\\\\\\\\\__\/\\\___\///_____\/\\\__________\//\\\____\/\\\_______\/\\\_\/\\\/////////\\\_\//\\\______/\\\__
      _\/\\\______________/\\\/////\\\__\/\\\____________\/\\\_/\\___/\\_/\\\_____\/\\\_______/\\\__\/\\\_______\/\\\__\///\\\__/\\\____
       _\/\\\_____________\//\\\\\\\\/\\_\/\\\____________\//\\\\\___\//\\\\/______\/\\\\\\\\\\\\/___\/\\\_______\/\\\____\///\\\\\/_____
        _\///_______________\////////\//__\///______________\/////_____\////________\////////////_____\///________\///_______\/////_______

Anna Carroll for PartyDAO
*/

// SPDX-License-Identifier: MIT
pragma solidity 0.8.5;

// ============ External Imports: Inherited Contracts ============
// NOTE: we inherit from OpenZeppelin upgradeable contracts
// because of the proxy structure used for cheaper deploys
// (the proxies are NOT actually upgradeable)
import {
ReentrancyGuardUpgradeable
} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
import {
ERC721HolderUpgradeable
} from "@openzeppelin/contracts-upgradeable/token/ERC721/utils/ERC721HolderUpgradeable.sol";
// ============ External Imports: External Contracts & Contract Interfaces ============
import {
IERC721VaultFactory
} from "./external/interfaces/IERC721VaultFactory.sol";
import {ITokenVault} from "./external/interfaces/ITokenVault.sol";
import {IWETH} from "./external/interfaces/IWETH.sol";
import {
IERC721Metadata
} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
import {
IERC20
} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
// ============ Internal Imports ============
import {Structs} from "./Structs.sol";

contract Party is ReentrancyGuardUpgradeable, ERC721HolderUpgradeable {
    // ============ Enums ============

    // State Transitions:
    //   (1) ACTIVE on deploy
    //   (2) WON if the Party has won the token
    //   (2) LOST if the Party is over & did not win the token
    enum PartyStatus {ACTIVE, WON, LOST}

    // ============ Structs ============

    struct Contribution {
        uint256 amount;
        uint256 previousTotalContributedToParty;
    }

    // ============ Internal Constants ============

    // tokens are minted at a rate of 1 ETH : 1000 tokens
    uint16 internal constant TOKEN_SCALE = 1000;
    // PartyDAO receives an ETH fee equal to 2.5% of the amount spent
    uint16 internal constant ETH_FEE_BASIS_POINTS = 250;
    // PartyDAO receives a token fee equal to 2.5% of the total token supply
    uint16 internal constant TOKEN_FEE_BASIS_POINTS = 250;
    // token is relisted on Fractional with an
    // initial reserve price equal to 2x the price of the token
    uint8 internal constant RESALE_MULTIPLIER = 2;

    // ============ Immutables ============

    address public immutable partyFactory;
    address public immutable partyDAOMultisig;
    IERC721VaultFactory public immutable tokenVaultFactory;
    IWETH public immutable weth;

    // ============ Public Not-Mutated Storage ============

    // NFT contract
    IERC721Metadata public nftContract;
    // ID of token within NFT contract
    uint256 public tokenId;
    // Fractionalized NFT vault responsible for post-purchase experience
    ITokenVault public tokenVault;
    // the address that will receive a portion of the tokens
    // if the Party successfully buys the token
    address public splitRecipient;
    // percent of the total token supply
    // taken by the splitRecipient
    uint256 public splitBasisPoints;
    // address of token that users need to hold to contribute
    // address(0) if party is not token gated
    IERC20 public gatedToken;
    // amount of token that users need to hold to contribute
    // 0 if party is not token gated
    uint256 public gatedTokenAmount;
    // ERC-20 name and symbol for fractional tokens
    string public name;
    string public symbol;

    // ============ Public Mutable Storage ============

    // state of the contract
    PartyStatus public partyStatus;
    // total ETH deposited by all contributors
    uint256 public totalContributedToParty;
    // the total spent buying the token;
    // 0 if the NFT is not won; price of token + 2.5% PartyDAO fee if NFT is won
    uint256 public totalSpent;
    // contributor => array of Contributions
    mapping(address => Contribution[]) public contributions;
    // contributor => total amount contributed
    mapping(address => uint256) public totalContributed;
    // contributor => true if contribution has been claimed
    mapping(address => bool) public claimed;

    // ============ Events ============

    event Contributed(
        address indexed contributor,
        uint256 amount,
        uint256 previousTotalContributedToParty,
        uint256 totalFromContributor
    );

    event Claimed(
        address indexed contributor,
        uint256 totalContributed,
        uint256 excessContribution,
        uint256 tokenAmount
    );

    // ======== Modifiers =========

    modifier onlyPartyDAO() {
        require(
            msg.sender == partyDAOMultisig,
            "Party:: only PartyDAO multisig"
        );
        _;
    }

    // ======== Constructor =========

    constructor(
        address _partyDAOMultisig,
        address _tokenVaultFactory,
        address _weth
    ) {
        partyFactory = msg.sender;
        partyDAOMultisig = _partyDAOMultisig;
        tokenVaultFactory = IERC721VaultFactory(_tokenVaultFactory);
        weth = IWETH(_weth);
    }

    // ======== Internal: Initialize =========

    function __Party_init(
        address _nftContract,
        uint256 _tokenId,
        Structs.AddressAndAmount calldata _split,
        Structs.AddressAndAmount calldata _tokenGate,
        string memory _name,
        string memory _symbol
    ) internal {
        require(msg.sender == partyFactory, "Party::__Party_init: only factory can init");
        // validate token exists (must set nftContract & tokenId before _getOwner)
        nftContract = IERC721Metadata(_nftContract);
        tokenId = _tokenId;
        require(_getOwner() != address(0), "Party::__Party_init: NFT getOwner failed");
        // if split is non-zero,
        if (_split.addr != address(0) && _split.amount != 0) {
            // validate that party split won't retain the total token supply
            uint256 _remainingBasisPoints = 10000 - TOKEN_FEE_BASIS_POINTS;
            require(_split.amount < _remainingBasisPoints, "Party::__Party_init: basis points can't take 100%");
            splitBasisPoints = _split.amount;
            splitRecipient = _split.addr;
        }
        // if token gating is non-zero
        if (_tokenGate.addr != address(0) && _tokenGate.amount != 0) {
            // call totalSupply to verify that address is ERC-20 token contract
            IERC20(_tokenGate.addr).totalSupply();
            gatedToken = IERC20(_tokenGate.addr);
            gatedTokenAmount = _tokenGate.amount;
        }
        // initialize ReentrancyGuard and ERC721Holder
        __ReentrancyGuard_init();
        __ERC721Holder_init();
        // set storage variables
        name = _name;
        symbol = _symbol;
    }

    // ======== Internal: Contribute =========

    /**
     * @notice Contribute to the Party's treasury
     * while the Party is still active
     * @dev Emits a Contributed event upon success; callable by anyone
     */
    function _contribute() internal {
        require(
            partyStatus == PartyStatus.ACTIVE,
            "Party::contribute: party not active"
        );
        address _contributor = msg.sender;
        uint256 _amount = msg.value;
        // if token gated, require that contributor has balance of gated tokens
        if (address(gatedToken) != address(0)) {
            require(gatedToken.balanceOf(_contributor) >= gatedTokenAmount, "Party::contribute: must hold tokens to contribute");
        }
        require(_amount > 0, "Party::contribute: must contribute more than 0");
        // get the current contract balance
        uint256 _previousTotalContributedToParty = totalContributedToParty;
        // add contribution to contributor's array of contributions
        Contribution memory _contribution =
            Contribution({
                amount: _amount,
                previousTotalContributedToParty: _previousTotalContributedToParty
            });
        contributions[_contributor].push(_contribution);
        // add to contributor's total contribution
        totalContributed[_contributor] = totalContributed[_contributor] + _amount;
        // add to party's total contribution & emit event
        totalContributedToParty = _previousTotalContributedToParty + _amount;
        emit Contributed(
            _contributor,
            _amount,
            _previousTotalContributedToParty,
            totalContributed[_contributor]
        );
    }

    // ======== External: Claim =========

    /**
     * @notice Claim the tokens and excess ETH owed
     * to a single contributor after the party has ended
     * @dev Emits a Claimed event upon success
     * callable by anyone (doesn't have to be the contributor)
     * @param _contributor the address of the contributor
     */
    function claim(address _contributor) external nonReentrant {
        // ensure party has finalized
        require(
            partyStatus != PartyStatus.ACTIVE,
            "Party::claim: party not finalized"
        );
        // ensure contributor submitted some ETH
        require(
            totalContributed[_contributor] != 0,
            "Party::claim: not a contributor"
        );
        // ensure the contributor hasn't already claimed
        require(
            !claimed[_contributor],
            "Party::claim: contribution already claimed"
        );
        // mark the contribution as claimed
        claimed[_contributor] = true;
        // calculate the amount of fractional NFT tokens owed to the user
        // based on how much ETH they contributed towards the party,
        // and the amount of excess ETH owed to the user
        (uint256 _tokenAmount, uint256 _ethAmount) =
        getClaimAmounts(_contributor);
        // transfer tokens to contributor for their portion of ETH used
        _transferTokens(_contributor, _tokenAmount);
        // if there is excess ETH, send it back to the contributor
        _transferETHOrWETH(_contributor, _ethAmount);
        emit Claimed(
            _contributor,
            totalContributed[_contributor],
            _ethAmount,
            _tokenAmount
        );
    }

    // ======== External: Emergency Escape Hatches (PartyDAO Multisig Only) =========

    /**
     * @notice Escape hatch: in case of emergency,
     * PartyDAO can use emergencyWithdrawEth to withdraw
     * ETH stuck in the contract
     */
    function emergencyWithdrawEth(uint256 _value)
        external
        onlyPartyDAO
    {
        _transferETHOrWETH(partyDAOMultisig, _value);
    }

    /**
     * @notice Escape hatch: in case of emergency,
     * PartyDAO can use emergencyCall to call an external contract
     * (e.g. to withdraw a stuck NFT or stuck ERC-20s)
     */
    function emergencyCall(address _contract, bytes memory _calldata)
        external
        onlyPartyDAO
        returns (bool _success, bytes memory _returnData)
    {
        (_success, _returnData) = _contract.call(_calldata);
        require(_success, string(_returnData));
    }

    /**
     * @notice Escape hatch: in case of emergency,
     * PartyDAO can force the Party to finalize with status LOST
     * (e.g. if finalize is not callable)
     */
    function emergencyForceLost()
        external
        onlyPartyDAO
    {
        // set partyStatus to LOST
        partyStatus = PartyStatus.LOST;
    }

    // ======== Public: Utility Calculations =========

    /**
     * @notice Convert ETH value to equivalent token amount
     */
    function valueToTokens(uint256 _value)
        public
        pure
        returns (uint256 _tokens)
    {
        _tokens = _value * TOKEN_SCALE;
    }

    /**
     * @notice The maximum amount that can be spent by the Party
     * while paying the ETH fee to PartyDAO
     * @return _maxSpend the maximum spend
     */
    function getMaximumSpend() public view returns (uint256 _maxSpend) {
        _maxSpend = (totalContributedToParty * 10000) / (10000 + ETH_FEE_BASIS_POINTS);
    }

    /**
     * @notice Calculate the amount of fractional NFT tokens owed to the contributor
     * based on how much ETH they contributed towards buying the token,
     * and the amount of excess ETH owed to the contributor
     * based on how much ETH they contributed *not* used towards buying the token
     * @param _contributor the address of the contributor
     * @return _tokenAmount the amount of fractional NFT tokens owed to the contributor
     * @return _ethAmount the amount of excess ETH owed to the contributor
     */
    function getClaimAmounts(address _contributor)
        public
        view
        returns (uint256 _tokenAmount, uint256 _ethAmount)
    {
        require(partyStatus != PartyStatus.ACTIVE, "Party::getClaimAmounts: party still active; amounts undetermined");
        uint256 _totalContributed = totalContributed[_contributor];
        if (partyStatus == PartyStatus.WON) {
            // calculate the amount of this contributor's ETH
            // that was used to buy the token
            uint256 _totalEthUsed = totalEthUsed(_contributor);
            if (_totalEthUsed > 0) {
                _tokenAmount = valueToTokens(_totalEthUsed);
            }
            // the rest of the contributor's ETH should be returned
            _ethAmount = _totalContributed - _totalEthUsed;
        } else {
            // if the token wasn't bought, no ETH was spent;
            // all of the contributor's ETH should be returned
            _ethAmount = _totalContributed;
        }
    }

    /**
     * @notice Calculate the total amount of a contributor's funds
     * that were used towards the buying the token
     * @dev always returns 0 until the party has been finalized
     * @param _contributor the address of the contributor
     * @return _total the sum of the contributor's funds that were
     * used towards buying the token
     */
    function totalEthUsed(address _contributor)
        public
        view
        returns (uint256 _total)
    {
        require(partyStatus != PartyStatus.ACTIVE, "Party::totalEthUsed: party still active; amounts undetermined");
        // load total amount spent once from storage
        uint256 _totalSpent = totalSpent;
        // get all of the contributor's contributions
        Contribution[] memory _contributions = contributions[_contributor];
        for (uint256 i = 0; i < _contributions.length; i++) {
            // calculate how much was used from this individual contribution
            uint256 _amount = _ethUsed(_totalSpent, _contributions[i]);
            // if we reach a contribution that was not used,
            // no subsequent contributions will have been used either,
            // so we can stop calculating to save some gas
            if (_amount == 0) break;
            _total = _total + _amount;
        }
    }

    // ============ Internal ============

    function _closeSuccessfulParty(uint256 _nftCost) internal returns (uint256 _ethFee) {
        // calculate PartyDAO fee & record total spent
        _ethFee = _getEthFee(_nftCost);
        totalSpent = _nftCost + _ethFee;
        // transfer ETH fee to PartyDAO
        _transferETHOrWETH(partyDAOMultisig, _ethFee);
        // deploy fractionalized NFT vault
        // and mint fractional ERC-20 tokens
        _fractionalizeNFT(_nftCost);
    }

    /**
     * @notice Calculate ETH fee for PartyDAO
     * NOTE: Remove this fee causes a critical vulnerability
     * allowing anyone to exploit a Party via price manipulation.
     * See Security Review in README for more info.
     * @return _fee the portion of _amount represented by scaling to ETH_FEE_BASIS_POINTS
     */
    function _getEthFee(uint256 _amount) internal pure returns (uint256 _fee) {
        _fee = (_amount * ETH_FEE_BASIS_POINTS) / 10000;
    }

    /**
     * @notice Calculate token amount for specified token recipient
     * @return _totalSupply the total token supply
     * @return _partyDAOAmount the amount of tokens for partyDAO fee,
     * which is equivalent to TOKEN_FEE_BASIS_POINTS of total supply
     * @return _splitRecipientAmount the amount of tokens for the token recipient,
     * which is equivalent to splitBasisPoints of total supply
     */
    function _getTokenInflationAmounts(uint256 _amountSpent)
        internal
        view
        returns (uint256 _totalSupply, uint256 _partyDAOAmount, uint256 _splitRecipientAmount)
    {
        // the token supply will be inflated to provide a portion of the
        // total supply for PartyDAO, and a portion for the splitRecipient
        uint256 inflationBasisPoints = TOKEN_FEE_BASIS_POINTS + splitBasisPoints;
        _totalSupply = valueToTokens((_amountSpent * 10000) / (10000 - inflationBasisPoints));
        // PartyDAO receives TOKEN_FEE_BASIS_POINTS of the total supply
        _partyDAOAmount = (_totalSupply * TOKEN_FEE_BASIS_POINTS) / 10000;
        // splitRecipient receives splitBasisPoints of the total supply
        _splitRecipientAmount = (_totalSupply * splitBasisPoints) / 10000;
    }

    /**
    * @notice Query the NFT contract to get the token owner
    * @dev nftContract must implement the ERC-721 token standard exactly:
    * function ownerOf(uint256 _tokenId) external view returns (address);
    * See https://eips.ethereum.org/EIPS/eip-721
    * @dev Returns address(0) if NFT token or NFT contract
    * no longer exists (token burned or contract self-destructed)
    * @return _owner the owner of the NFT
    */
    function _getOwner() internal view returns (address _owner) {
        (bool _success, bytes memory _returnData) =
            address(nftContract).staticcall(
                abi.encodeWithSignature(
                    "ownerOf(uint256)",
                    tokenId
                )
        );
        if (_success && _returnData.length > 0) {
            _owner = abi.decode(_returnData, (address));
        }
    }

    /**
     * @notice Upon winning the token, transfer the NFT
     * to fractional.art vault & mint fractional ERC-20 tokens
     */
    function _fractionalizeNFT(uint256 _amountSpent) internal {
        // approve fractionalized NFT Factory to withdraw NFT
        nftContract.approve(address(tokenVaultFactory), tokenId);
        // Party "votes" for a reserve price on Fractional
        // equal to 2x the price of the token
        uint256 _listPrice = RESALE_MULTIPLIER * _amountSpent;
        // users receive tokens at a rate of 1:TOKEN_SCALE for each ETH they contributed that was ultimately spent
        // partyDAO receives a percentage of the total token supply equivalent to TOKEN_FEE_BASIS_POINTS
        // splitRecipient receives a percentage of the total token supply equivalent to splitBasisPoints
        (uint256 _tokenSupply, uint256 _partyDAOAmount, uint256 _splitRecipientAmount) = _getTokenInflationAmounts(totalSpent);
        // deploy fractionalized NFT vault
        uint256 vaultNumber =
            tokenVaultFactory.mint(
                name,
                symbol,
                address(nftContract),
                tokenId,
                _tokenSupply,
                _listPrice,
                0
            );
        // store token vault address to storage
        tokenVault = ITokenVault(tokenVaultFactory.vaults(vaultNumber));
        // transfer curator to null address (burn the curator role)
        tokenVault.updateCurator(address(0));
        // transfer tokens to PartyDAO multisig
        _transferTokens(partyDAOMultisig, _partyDAOAmount);
        // transfer tokens to token recipient
        if (splitRecipient != address(0)) {
            _transferTokens(splitRecipient, _splitRecipientAmount);
        }
    }

    // ============ Internal: Claim ============

    /**
     * @notice Calculate the amount of a single Contribution
     * that was used towards buying the token
     * @param _contribution the Contribution struct
     * @return the amount of funds from this contribution
     * that were used towards buying the token
     */
    function _ethUsed(uint256 _totalSpent, Contribution memory _contribution)
        internal
        pure
        returns (uint256)
    {
        if (
            _contribution.previousTotalContributedToParty +
            _contribution.amount <=
            _totalSpent
        ) {
            // contribution was fully used
            return _contribution.amount;
        } else if (
            _contribution.previousTotalContributedToParty < _totalSpent
        ) {
            // contribution was partially used
            return _totalSpent - _contribution.previousTotalContributedToParty;
        }
        // contribution was not used
        return 0;
    }

    // ============ Internal: TransferTokens ============

    /**
    * @notice Transfer tokens to a recipient
    * @param _to recipient of tokens
    * @param _value amount of tokens
    */
    function _transferTokens(address _to, uint256 _value) internal {
        // skip if attempting to send 0 tokens
        if (_value == 0) {
            return;
        }
        // guard against rounding errors;
        // if token amount to send is greater than contract balance,
        // send full contract balance
        uint256 _partyBalance = tokenVault.balanceOf(address(this));
        if (_value > _partyBalance) {
            _value = _partyBalance;
        }
        tokenVault.transfer(_to, _value);
    }

    // ============ Internal: TransferEthOrWeth ============

    /**
     * @notice Attempt to transfer ETH to a recipient;
     * if transferring ETH fails, transfer WETH insteads
     * @param _to recipient of ETH or WETH
     * @param _value amount of ETH or WETH
     */
    function _transferETHOrWETH(address _to, uint256 _value) internal {
        // skip if attempting to send 0 ETH
        if (_value == 0) {
            return;
        }
        // guard against rounding errors;
        // if ETH amount to send is greater than contract balance,
        // send full contract balance
        if (_value > address(this).balance) {
            _value = address(this).balance;
        }
        // Try to transfer ETH to the given recipient.
        if (!_attemptETHTransfer(_to, _value)) {
            // If the transfer fails, wrap and send as WETH
            weth.deposit{value: _value}();
            weth.transfer(_to, _value);
            // At this point, the recipient can unwrap WETH.
        }
    }

    /**
     * @notice Attempt to transfer ETH to a recipient
     * @dev Sending ETH is not guaranteed to succeed
     * this method will return false if it fails.
     * We will limit the gas used in transfers, and handle failure cases.
     * @param _to recipient of ETH
     * @param _value amount of ETH
     */
    function _attemptETHTransfer(address _to, uint256 _value)
        internal
        returns (bool)
    {
        // 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.
        (bool success, ) = _to.call{value: _value, gas: 30000}("");
        return success;
    }
}

File 6 of 17 : IMarketWrapper.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.5;

/**
 * @title IMarketWrapper
 * @author Anna Carroll
 * @notice IMarketWrapper provides a common interface for
 * interacting with NFT auction markets.
 * Contracts can abstract their interactions with
 * different NFT markets using IMarketWrapper.
 * NFT markets can become compatible with any contract
 * using IMarketWrapper by deploying a MarketWrapper contract
 * that implements this interface using the logic of their Market.
 *
 * WARNING: MarketWrapper contracts should NEVER write to storage!
 * When implementing a MarketWrapper, exercise caution; a poorly implemented
 * MarketWrapper contract could permanently lose access to the NFT or user funds.
 */
interface IMarketWrapper {
    /**
     * @notice Given the auctionId, nftContract, and tokenId, check that:
     * 1. the auction ID matches the token
     * referred to by tokenId + nftContract
     * 2. the auctionId refers to an *ACTIVE* auction
     * (e.g. an auction that will accept bids)
     * within this market contract
     * 3. any additional validation to ensure that
     * a PartyBid can bid on this auction
     * (ex: if the market allows arbitrary bidding currencies,
     * check that the auction currency is ETH)
     * Note: This function probably should have been named "isValidAuction"
     * @dev Called in PartyBid.sol in `initialize` at line 174
     * @return TRUE if the auction is valid
     */
    function auctionIdMatchesToken(
        uint256 auctionId,
        address nftContract,
        uint256 tokenId
    ) external view returns (bool);

    /**
     * @notice Calculate the minimum next bid for this auction.
     * PartyBid contracts always submit the minimum possible
     * bid that will be accepted by the Market contract.
     * usually, this is either the reserve price (if there are no bids)
     * or a certain percentage increase above the current highest bid
     * @dev Called in PartyBid.sol in `bid` at line 251
     * @return minimum bid amount
     */
    function getMinimumBid(uint256 auctionId) external view returns (uint256);

    /**
     * @notice Query the current highest bidder for this auction
     * It is assumed that there is always 1 winning highest bidder for an auction
     * This is used to ensure that PartyBid cannot outbid itself if it is already winning
     * @dev Called in PartyBid.sol in `bid` at line 241
     * @return highest bidder
     */
    function getCurrentHighestBidder(uint256 auctionId)
        external
        view
        returns (address);

    /**
     * @notice Submit bid to Market contract
     * @dev Called in PartyBid.sol in `bid` at line 259
     */
    function bid(uint256 auctionId, uint256 bidAmount) external;

    /**
     * @notice Determine whether the auction has been finalized
     * Used to check if it is still possible to bid
     * And to determine whether the PartyBid should finalize the auction
     * @dev Called in PartyBid.sol in `bid` at line 247
     * @dev and in `finalize` at line 288
     * @return TRUE if the auction has been finalized
     */
    function isFinalized(uint256 auctionId) external view returns (bool);

    /**
     * @notice Finalize the results of the auction
     * on the Market contract
     * It is assumed  that this operation is performed once for each auction,
     * that after it is done the auction is over and the NFT has been
     * transferred to the auction winner.
     * @dev Called in PartyBid.sol in `finalize` at line 289
     */
    function finalize(uint256 auctionId) external;
}

File 7 of 17 : ReentrancyGuardUpgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuardUpgradeable is Initializable {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    function __ReentrancyGuard_init() internal initializer {
        __ReentrancyGuard_init_unchained();
    }

    function __ReentrancyGuard_init_unchained() internal initializer {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
    uint256[49] private __gap;
}

File 8 of 17 : ERC721HolderUpgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../IERC721ReceiverUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";

  /**
   * @dev Implementation of the {IERC721Receiver} interface.
   *
   * Accepts all token transfers.
   * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.
   */
contract ERC721HolderUpgradeable is Initializable, IERC721ReceiverUpgradeable {
    function __ERC721Holder_init() internal initializer {
        __ERC721Holder_init_unchained();
    }

    function __ERC721Holder_init_unchained() internal initializer {
    }

    /**
     * @dev See {IERC721Receiver-onERC721Received}.
     *
     * Always returns `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {
        return this.onERC721Received.selector;
    }
    uint256[50] private __gap;
}

File 9 of 17 : IERC721VaultFactory.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.5;

interface IERC721VaultFactory {
    /// @notice the mapping of vault number to vault address
    function vaults(uint256) external returns (address);

    /// @notice the function to mint a new vault
    /// @param _name the desired name of the vault
    /// @param _symbol the desired sumbol of the vault
    /// @param _token the ERC721 token address fo the NFT
    /// @param _id the uint256 ID of the token
    /// @param _listPrice the initial price of the NFT
    /// @return the ID of the vault
    function mint(string memory _name, string memory _symbol, address _token, uint256 _id, uint256 _supply, uint256 _listPrice, uint256 _fee) external returns(uint256);
}

File 10 of 17 : ITokenVault.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.5;

interface ITokenVault {
    /// @notice allow curator to update the curator address
    /// @param _curator the new curator
    function updateCurator(address _curator) external;

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) external view returns (uint256);
}

File 11 of 17 : IWETH.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.5;

interface IWETH {
    function deposit() external payable;

    function transfer(address to, uint256 value) external returns (bool);
}

File 12 of 17 : IERC721Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {

    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

File 13 of 17 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 14 of 17 : Initializable.sol
// SPDX-License-Identifier: MIT

// solhint-disable-next-line compiler-version
pragma solidity ^0.8.0;

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 */
abstract contract Initializable {

    /**
     * @dev Indicates that the contract has been initialized.
     */
    bool private _initialized;

    /**
     * @dev Indicates that the contract is in the process of being initialized.
     */
    bool private _initializing;

    /**
     * @dev Modifier to protect an initializer function from being invoked twice.
     */
    modifier initializer() {
        require(_initializing || !_initialized, "Initializable: contract is already initialized");

        bool isTopLevelCall = !_initializing;
        if (isTopLevelCall) {
            _initializing = true;
            _initialized = true;
        }

        _;

        if (isTopLevelCall) {
            _initializing = false;
        }
    }
}

File 15 of 17 : IERC721ReceiverUpgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721ReceiverUpgradeable {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);
}

File 16 of 17 : IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
      * @dev Safely transfers `tokenId` token from `from` to `to`.
      *
      * Requirements:
      *
      * - `from` cannot be the zero address.
      * - `to` cannot be the zero address.
      * - `tokenId` token must exist and be owned by `from`.
      * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
      * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
      *
      * Emits a {Transfer} event.
      */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
}

File 17 of 17 : IERC165.sol
// SPDX-License-Identifier: MIT

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);
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 999999
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_partyDAOMultisig","type":"address"},{"internalType":"address","name":"_tokenVaultFactory","type":"address"},{"internalType":"address","name":"_weth","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"partyBidProxy","type":"address"},{"indexed":false,"internalType":"address","name":"creator","type":"address"},{"indexed":false,"internalType":"address","name":"nftContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"marketWrapper","type":"address"},{"indexed":false,"internalType":"uint256","name":"auctionId","type":"uint256"},{"indexed":false,"internalType":"address","name":"splitRecipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"splitBasisPoints","type":"uint256"},{"indexed":false,"internalType":"address","name":"gatedToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"gatedTokenAmount","type":"uint256"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"}],"name":"PartyBidDeployed","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"deployedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"logic","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"partyDAOMultisig","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_marketWrapper","type":"address"},{"internalType":"address","name":"_nftContract","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_auctionId","type":"uint256"},{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Structs.AddressAndAmount","name":"_split","type":"tuple"},{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Structs.AddressAndAmount","name":"_tokenGate","type":"tuple"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"startParty","outputs":[{"internalType":"address","name":"partyBidProxy","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenVaultFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

61010060405234801561001157600080fd5b50604051614b8b380380614b8b833981016040819052610030916100e7565b6001600160601b0319606084811b821660a05283811b821660c05282901b1660e052604051600090849084908490610067906100be565b6001600160a01b03938416815291831660208301529091166040820152606001604051809103906000f0801580156100a3573d6000803e3d6000fd5b5060601b6001600160601b0319166080525061012a92505050565b613f8a80610c0183390190565b80516001600160a01b03811681146100e257600080fd5b919050565b6000806000606084860312156100fc57600080fd5b610105846100cb565b9250610113602085016100cb565b9150610121604085016100cb565b90509250925092565b60805160601c60a05160601c60c05160601c60e05160601c610a8e610173600039600060f401526000607c0152600060cd01526000818161015c01526102090152610a8e6000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c806357dbdf541161005057806357dbdf5414610116578063c82816cb14610144578063d7dfa0dd1461015757600080fd5b80630b203023146100775780633c4d12d9146100c85780633fc8cef3146100ef575b600080fd5b61009e7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61009e7f000000000000000000000000000000000000000000000000000000000000000081565b61009e7f000000000000000000000000000000000000000000000000000000000000000081565b610136610124366004610403565b60006020819052908152604090205481565b6040519081526020016100bf565b61009e610152366004610425565b61017e565b61009e7f000000000000000000000000000000000000000000000000000000000000000081565b600080631d4667fa60e01b8a8a8a8a8a8a8a8a6040516024016101a8989796959493929190610616565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090507f0000000000000000000000000000000000000000000000000000000000000000816040516102359061030a565b61024092919061069b565b604051809103906000f08015801561025c573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff81166000908152602081815260409091204390559092507f2e13a1db67858d419104348669d9bb778dcbefae90d4c5b743825c5ddba7b09b90839033908c908c908f908d906102c3908e018e610403565b6020808f0135906102d6908f018f610403565b8e602001358e8e6040516102f59c9b9a9998979695949392919061057a565b60405180910390a15098975050505050505050565b6103578061070283390190565b803573ffffffffffffffffffffffffffffffffffffffff8116811461033b57600080fd5b919050565b600082601f83011261035157600080fd5b813567ffffffffffffffff8082111561036c5761036c6106d2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156103b2576103b26106d2565b816040528381528660208588010111156103cb57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000604082840312156103fd57600080fd5b50919050565b60006020828403121561041557600080fd5b61041e82610317565b9392505050565b600080600080600080600080610140898b03121561044257600080fd5b61044b89610317565b975061045960208a01610317565b965060408901359550606089013594506104768a60808b016103eb565b93506104858a60c08b016103eb565b925061010089013567ffffffffffffffff808211156104a357600080fd5b6104af8c838d01610340565b93506101208b01359150808211156104c657600080fd5b506104d38b828c01610340565b9150509295985092959890939650565b6000815180845260005b81811015610509576020818501810151868301820152016104ed565b8181111561051b576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff61056c82610317565b168252602090810135910152565b600073ffffffffffffffffffffffffffffffffffffffff808f168352808e166020840152808d1660408401528b6060840152808b1660808401528960a084015280891660c08401528760e084015280871661010084015250846101208301526101806101408301526105f06101808301856104e3565b82810361016084015261060381856104e3565b9f9e505050505050505050505050505050565b600061014073ffffffffffffffffffffffffffffffffffffffff808c168452808b16602085015250886040840152876060840152610657608084018861054e565b61066460c084018761054e565b80610100840152610677818401866104e3565b905082810361012084015261068c81856104e3565b9b9a5050505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006106ca60408301846104e3565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfe60a060405234801561001057600080fd5b5060405161035738038061035783398101604081905261002f916100d7565b6001600160601b0319606083901b1660805260405160009081906001600160a01b0385169061005f9085906101a5565b600060405180830381855af49150503d806000811461009a576040519150601f19603f3d011682016040523d82523d6000602084013e61009f565b606091505b50915091508181906100cd5760405162461bcd60e51b81526004016100c491906101c1565b60405180910390fd5b505050505061023a565b600080604083850312156100ea57600080fd5b82516001600160a01b038116811461010157600080fd5b60208401519092506001600160401b038082111561011e57600080fd5b818501915085601f83011261013257600080fd5b81518181111561014457610144610224565b604051601f8201601f19908116603f0116810190838211818310171561016c5761016c610224565b8160405282815288602084870101111561018557600080fd5b6101968360208301602088016101f4565b80955050505050509250929050565b600082516101b78184602087016101f4565b9190910192915050565b60208152600082518060208401526101e08160408501602087016101f4565b601f01601f19169190910160400192915050565b60005b8381101561020f5781810151838201526020016101f7565b8381111561021e576000848401525b50505050565b634e487b7160e01b600052604160045260246000fd5b60805160601c60fc61025b60003960008181602a0152607b015260fc6000f3fe608060405260043610601f5760003560e01c8063d7dfa0dd14606b576025565b36602557005b6040517f00000000000000000000000000000000000000000000000000000000000000009036600082376000803683855af43d806000843e8180156067578184f35b8184fd5b348015607657600080fd5b50609d7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f3fea2646970667358221220a3350e7abb318cfd6c2f0227ef2ec856c01e215d98d5d2e5e2202e41a3c4deaf64736f6c63430008050033a2646970667358221220ae1d5b1be7b488b2d1931b20c2071b2080ebb4da4ead609cdb5431a08849890c64736f6c634300080500336101006040523480156200001257600080fd5b5060405162003f8a38038062003f8a833981016040819052620000359162000080565b33606090811b6080526001600160601b031993811b841660a05291821b831660c052901b1660e052620000ca565b80516001600160a01b03811681146200007b57600080fd5b919050565b6000806000606084860312156200009657600080fd5b620000a18462000063565b9250620000b16020850162000063565b9150620000c16040850162000063565b90509250925092565b60805160601c60a05160601c60c05160601c60e05160601c613e26620001646000396000818161048a01528181612593015261265b0152600081816102ac01528181612f1c01528181612ff901526130c10152600081816104560152818161089a0152818161181d015281816118a901528181611def0152818161287601526132030152600081816105cf0152611fc60152613e266000f3fe60806040526004361061026a5760003560e01c80636971524f11610153578063c4bf0220116100cb578063dd06ba1a1161007f578063ef38bf0111610064578063ef38bf0114610789578063fb346eab146107b6578063ffa1ad74146107cc57600080fd5b8063dd06ba1a1461074d578063df51c07f1461076257600080fd5b8063d56d229d116100b0578063d56d229d14610702578063d57bde791461072f578063d7bb99ba1461074557600080fd5b8063c4bf022014610694578063c884ef83146106c257600080fd5b80638d42ecd6116101225780639744b8dc116101075780639744b8dc14610632578063a0f243b814610652578063acd13c591461067f57600080fd5b80638d42ecd61461060757806395d89b411461061d57600080fd5b80636971524f146105705780637a2ba9c4146105905780637ca67b62146105bd57806382a5c69a146105f157600080fd5b806325b42a26116101e6578063429093cc116101b55780634bb278f31161019a5780634bb278f3146104f9578063550b521c1461050e5780635bc789d91461054357600080fd5b8063429093cc146104ac5780634367a029146104cc57600080fd5b806325b42a261461040e5780632bbce5e61461042e5780633c4d12d9146104445780633fc8cef31461047857600080fd5b806317821fdc1161023d5780631998aeef116102225780631998aeef146103b95780631d4667fa146103ce5780631e83409a146103ee57600080fd5b806317821fdc1461038c57806317d70f7c146103a357600080fd5b806306fdde031461026f5780630b2030231461029a57806310782f8f146102f3578063150b7a0214610317575b600080fd5b34801561027b57600080fd5b506102846107f4565b6040516102919190613af6565b60405180910390f35b3480156102a657600080fd5b506102ce7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610291565b3480156102ff57600080fd5b5061030960755481565b604051908152602001610291565b34801561032357600080fd5b5061035b6103323660046136bb565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610291565b34801561039857600080fd5b506103a1610882565b005b3480156103af57600080fd5b5061030960665481565b3480156103c557600080fd5b506103a1610953565b3480156103da57600080fd5b506103a16103e9366004613727565b61107f565b3480156103fa57600080fd5b506103a161040936600461367a565b611329565b34801561041a57600080fd5b5061030961042936600461367a565b611665565b34801561043a57600080fd5b5061030960695481565b34801561045057600080fd5b506102ce7f000000000000000000000000000000000000000000000000000000000000000081565b34801561048457600080fd5b506102ce7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104b857600080fd5b506103a16104c7366004613887565b611805565b3480156104d857600080fd5b506068546102ce9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561050557600080fd5b506103a16118d1565b34801561051a57600080fd5b5061052e610529366004613839565b611c19565b60408051928352602083019190915201610291565b34801561054f57600080fd5b506067546102ce9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561057c57600080fd5b5061052e61058b36600461367a565b611c55565b34801561059c57600080fd5b50606a546102ce9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156105c957600080fd5b506102ce7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105fd57600080fd5b50610309606f5481565b34801561061357600080fd5b50610309606b5481565b34801561062957600080fd5b50610284611d80565b34801561063e57600080fd5b5061030961064d366004613887565b611d8d565b34801561065e57600080fd5b5061030961066d36600461367a565b60726020526000908152604090205481565b34801561068b57600080fd5b50610309611da1565b3480156106a057600080fd5b506106b46106af3660046137e9565b611dd3565b604051610291929190613a9c565b3480156106ce57600080fd5b506106f26106dd36600461367a565b60736020526000908152604090205460ff1681565b6040519015158152602001610291565b34801561070e57600080fd5b506065546102ce9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561073b57600080fd5b5061030960765481565b6103a1611f24565b34801561075957600080fd5b50610309611fa4565b34801561076e57600080fd5b50606e5461077c9060ff1681565b6040516102919190613abf565b34801561079557600080fd5b506074546102ce9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156107c257600080fd5b5061030960705481565b3480156107d857600080fd5b506107e1600381565b60405161ffff9091168152602001610291565b606c805461080190613c8b565b80601f016020809104026020016040519081016040528092919081815260200182805461082d90613c8b565b801561087a5780601f1061084f5761010080835404028352916020019161087a565b820191906000526020600020905b81548152906001019060200180831161085d57829003601f168201915b505050505081565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610926576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f50617274793a3a206f6e6c7920506172747944414f206d756c7469736967000060448201526064015b60405180910390fd5b606e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166002179055565b600260015414156109c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161091d565b60026001556000606e5460ff1660028111156109de576109de613d41565b14610a6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f50617274794269643a3a6269643a2061756374696f6e206e6f7420616374697660448201527f6500000000000000000000000000000000000000000000000000000000000000606482015260840161091d565b33600090815260726020526040902054610b07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f50617274794269643a3a6269643a206f6e6c7920636f6e7472696275746f727360448201527f2063616e20626964000000000000000000000000000000000000000000000000606482015260840161091d565b6074546075546040517f456b09c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9092169163456b09c191610b629160040190815260200190565b60206040518083038186803b158015610b7a57600080fd5b505afa158015610b8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb2919061369e565b73ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff161415610c6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50617274794269643a3a6269643a20616c72656164792068696768657374206260448201527f6964646572000000000000000000000000000000000000000000000000000000606482015260840161091d565b6074546075546040517f33727c4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909216916333727c4d91610cc89160040190815260200190565b60206040518083038186803b158015610ce057600080fd5b505afa158015610cf4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d189190613865565b15610da5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f50617274794269643a3a6269643a2061756374696f6e20616c7265616479206660448201527f696e616c697a6564000000000000000000000000000000000000000000000000606482015260840161091d565b6074546075546040517f0600d4eb000000000000000000000000000000000000000000000000000000008152600481019190915260009173ffffffffffffffffffffffffffffffffffffffff1690630600d4eb9060240160206040518083038186803b158015610e1457600080fd5b505afa158015610e28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4c91906138a0565b9050610e56611fa4565b811115610ee5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f50617274794269643a3a6269643a20696e73756666696369656e742066756e6460448201527f7320746f20626964000000000000000000000000000000000000000000000000606482015260840161091d565b607454607554604051602481019190915260448101839052600091829173ffffffffffffffffffffffffffffffffffffffff90911690606401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f598647f80000000000000000000000000000000000000000000000000000000017905251610f9f9190613a15565b600060405180830381855af49150503d8060008114610fda576040519150601f19603f3d011682016040523d82523d6000602084013e610fdf565b606091505b50915091508181604051602001610ff69190613a31565b6040516020818303038152906040529061103d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091d9190613af6565b5060768390556040518381527f7a183e84509e3fe5b0b3aac15347fd1c7d71fd1503001f1a1d7c9658077eb35f9060200160405180910390a150506001805550565b600054610100900460ff1680611098575060005460ff16155b611124576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091d565b600054610100900460ff1615801561116357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b6040517f97e2d3800000000000000000000000000000000000000000000000000000000081526004810187905273ffffffffffffffffffffffffffffffffffffffff8981166024830152604482018990528a16906397e2d3809060640160206040518083038186803b1580156111d857600080fd5b505afa1580156111ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112109190613865565b61129c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f50617274794269643a3a696e697469616c697a653a2061756374696f6e49642060448201527f646f65736e2774206d6174636820746f6b656e00000000000000000000000000606482015260840161091d565b6112aa888887878787611fae565b607480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8b161790556075869055801561131e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b505050505050505050565b60026001541415611396576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161091d565b60026001556000606e5460ff1660028111156113b4576113b4613d41565b1415611442576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f50617274793a3a636c61696d3a207061727479206e6f742066696e616c697a6560448201527f6400000000000000000000000000000000000000000000000000000000000000606482015260840161091d565b73ffffffffffffffffffffffffffffffffffffffff81166000908152607260205260409020546114ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f50617274793a3a636c61696d3a206e6f74206120636f6e7472696275746f7200604482015260640161091d565b73ffffffffffffffffffffffffffffffffffffffff811660009081526073602052604090205460ff1615611584576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f50617274793a3a636c61696d3a20636f6e747269627574696f6e20616c72656160448201527f647920636c61696d656400000000000000000000000000000000000000000000606482015260840161091d565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260736020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055806115dc83611c55565b915091506115ea8383612404565b6115f4838261256f565b73ffffffffffffffffffffffffffffffffffffffff83166000818152607260209081526040918290205482519081529081018490529081018490527f9cdcf2f7714cca3508c7f0110b04a90a80a3a8dd0e35de99689db74d28c5383e9060600160405180910390a250506001805550565b600080606e5460ff16600281111561167f5761167f613d41565b141561170d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f50617274793a3a746f74616c457468557365643a207061727479207374696c6c60448201527f206163746976653b20616d6f756e747320756e64657465726d696e6564000000606482015260840161091d565b60705473ffffffffffffffffffffffffffffffffffffffff8316600090815260716020908152604080832080548251818502810185019093528083529192909190849084015b8282101561179957838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190611753565b50505050905060005b81518110156117fd5760006117d0848484815181106117c3576117c3613d70565b60200260200101516126e1565b9050806117dd57506117fd565b6117e78186613b95565b94505080806117f590613cd9565b9150506117a2565b505050919050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146118a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f50617274793a3a206f6e6c7920506172747944414f206d756c74697369670000604482015260640161091d565b6118ce7f00000000000000000000000000000000000000000000000000000000000000008261256f565b50565b6002600154141561193e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161091d565b60026001556000606e5460ff16600281111561195c5761195c613d41565b146119e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f50617274794269643a3a66696e616c697a653a2061756374696f6e206e6f742060448201527f6163746976650000000000000000000000000000000000000000000000000000606482015260840161091d565b6074546075546040517f33727c4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909216916333727c4d91611a449160040190815260200190565b60206040518083038186803b158015611a5c57600080fd5b505afa158015611a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a949190613865565b611b26576074546075546040517f05261aea00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909216916305261aea91611af39160040190815260200190565b600060405180830381600087803b158015611b0d57600080fd5b505af1158015611b21573d6000803e3d6000fd5b505050505b6000611b30612730565b905073ffffffffffffffffffffffffffffffffffffffff81163014611b56576002611b59565b60015b606e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836002811115611b9357611b93613d41565b021790555060006001606e5460ff166002811115611bb357611bb3613d41565b1415611bc757611bc4607654612857565b90505b606e54607054606f546040517f9a2087478f16b801ecd568a6676f5db758bda2a01b954b2c754257d11eb3770b93611c099360ff909116929091869190613acd565b60405180910390a1505060018055565b60716020528160005260406000208181548110611c3557600080fd5b600091825260209091206002909102018054600190910154909250905082565b60008080606e5460ff166002811115611c7057611c70613d41565b1415611d0057604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f50617274793a3a676574436c61696d416d6f756e74733a20706172747920737460448201527f696c6c206163746976653b20616d6f756e747320756e64657465726d696e6564606482015260840161091d565b73ffffffffffffffffffffffffffffffffffffffff83166000908152607260205260409020546001606e5460ff166002811115611d3f57611d3f613d41565b1415611d76576000611d5085611665565b90508015611d6457611d6181611d8d565b93505b611d6e8183613c48565b925050611d7a565b8091505b50915091565b606d805461080190613c8b565b6000611d9b6103e883613be8565b92915050565b6000611db060fa612710613b6f565b61ffff16606f54612710611dc49190613be8565b611dce9190613bad565b905090565b600060603373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611e76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f50617274793a3a206f6e6c7920506172747944414f206d756c74697369670000604482015260640161091d565b8373ffffffffffffffffffffffffffffffffffffffff1683604051611e9b9190613a15565b6000604051808303816000865af19150503d8060008114611ed8576040519150601f19603f3d011682016040523d82523d6000602084013e611edd565b606091505b5090925090508082611f1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091d9190613af6565b509250929050565b60026001541415611f91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161091d565b6002600155611f9e6128a9565b60018055565b6000611dce611da1565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614612073576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f50617274793a3a5f5f50617274795f696e69743a206f6e6c7920666163746f7260448201527f792063616e20696e697400000000000000000000000000000000000000000000606482015260840161091d565b606580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8816179055606685905560006120c2612730565b73ffffffffffffffffffffffffffffffffffffffff161415612166576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f50617274793a3a5f5f50617274795f696e69743a204e4654206765744f776e6560448201527f72206661696c6564000000000000000000000000000000000000000000000000606482015260840161091d565b6000612175602086018661367a565b73ffffffffffffffffffffffffffffffffffffffff161415801561219c5750602084013515155b156122a35760006121b060fa612710613c25565b61ffff16905080856020013510612249576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f50617274793a3a5f5f50617274795f696e69743a20626173697320706f696e7460448201527f732063616e27742074616b652031303025000000000000000000000000000000606482015260840161091d565b60208501803560695561225c908661367a565b606880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055505b60006122b2602085018561367a565b73ffffffffffffffffffffffffffffffffffffffff16141580156122d95750602083013515155b156123c4576122eb602084018461367a565b73ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561233057600080fd5b505afa158015612344573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061236891906138a0565b50612376602084018461367a565b606a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790556020830135606b555b6123cc612c46565b6123d4612d63565b81516123e790606c90602085019061351e565b5080516123fb90606d90602084019061351e565b50505050505050565b8061240d575050565b6067546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a082319060240160206040518083038186803b15801561247757600080fd5b505afa15801561248b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124af91906138a0565b9050808211156124bd578091505b6067546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590529091169063a9059cbb90604401602060405180830381600087803b15801561253157600080fd5b505af1158015612545573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125699190613865565b50505050565b80612578575050565b478111156125835750475b61258d8282612e4f565b6126dd577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156125f957600080fd5b505af115801561260d573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152602482018690527f000000000000000000000000000000000000000000000000000000000000000016935063a9059cbb92506044019050602060405180830381600087803b1580156126a357600080fd5b505af11580156126b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126db9190613865565b505b5050565b600082826000015183602001516126f89190613b95565b1161270557508051611d9b565b82826020015110156127275760208201516127209084613c48565b9050611d9b565b50600092915050565b60655460665460405160248101919091526000918291829173ffffffffffffffffffffffffffffffffffffffff1690604401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f6352211e00000000000000000000000000000000000000000000000000000000179052516127e39190613a15565b600060405180830381855afa9150503d806000811461281e576040519150601f19603f3d011682016040523d82523d6000602084013e612823565b606091505b5091509150818015612836575060008151115b15612852578080602001905181019061284f919061369e565b92505b505090565b600061286282612ebf565b905061286e8183613b95565b60705561289b7f00000000000000000000000000000000000000000000000000000000000000008261256f565b6128a482612ed9565b919050565b6000606e5460ff1660028111156128c2576128c2613d41565b1461294f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f50617274793a3a636f6e747269627574653a207061727479206e6f742061637460448201527f6976650000000000000000000000000000000000000000000000000000000000606482015260840161091d565b606a543390349073ffffffffffffffffffffffffffffffffffffffff1615612aa557606b54606a546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152909116906370a082319060240160206040518083038186803b1580156129df57600080fd5b505afa1580156129f3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a1791906138a0565b1015612aa5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f50617274793a3a636f6e747269627574653a206d75737420686f6c6420746f6b60448201527f656e7320746f20636f6e74726962757465000000000000000000000000000000606482015260840161091d565b60008111612b35576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f50617274793a3a636f6e747269627574653a206d75737420636f6e747269627560448201527f7465206d6f7265207468616e2030000000000000000000000000000000000000606482015260840161091d565b606f54604080518082018252838152602080820184815273ffffffffffffffffffffffffffffffffffffffff871660008181526071845285812080546001818101835591835285832087516002909202019081559351930192909255815260729091529190912054612ba8908490613b95565b73ffffffffffffffffffffffffffffffffffffffff8516600090815260726020526040902055612bd88383613b95565b606f5573ffffffffffffffffffffffffffffffffffffffff84166000818152607260209081526040918290205482518781529182018690528183015290517fb2623081601722547aae8781994e01a1974d95b0ad9ce6a0cfbe17487556257f9181900360600190a250505050565b600054610100900460ff1680612c5f575060005460ff16155b612ceb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091d565b600054610100900460ff16158015612d2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b612d32613271565b80156118ce57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b600054610100900460ff1680612d7c575060005460ff16155b612e08576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091d565b600054610100900460ff16158015612e4757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b612d3261338a565b6000808373ffffffffffffffffffffffffffffffffffffffff168361753090604051600060405180830381858888f193505050503d8060008114612eaf576040519150601f19603f3d011682016040523d82523d6000602084013e612eb4565b606091505b509095945050505050565b6000612710612ecf60fa84613be8565b611d9b9190613bad565b6065546066546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166004830152602482019290925291169063095ea7b390604401600060405180830381600087803b158015612f7057600080fd5b505af1158015612f84573d6000803e3d6000fd5b5060009250612f9891508390506002613be8565b90506000806000612faa60705461349e565b6065546066546040517fbdc0111000000000000000000000000000000000000000000000000000000000815294975092955090935060009273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081169363bdc011109361303d93606c93606d93921691908b908d908a90600401613b09565b602060405180830381600087803b15801561305757600080fd5b505af115801561306b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061308f91906138a0565b6040517f8c64ea4a000000000000000000000000000000000000000000000000000000008152600481018290529091507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690638c64ea4a90602401602060405180830381600087803b15801561311a57600080fd5b505af115801561312e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613152919061369e565b606780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691821790556040517f0c6a62dd00000000000000000000000000000000000000000000000000000000815260006004820152630c6a62dd90602401600060405180830381600087803b1580156131e657600080fd5b505af11580156131fa573d6000803e3d6000fd5b505050506132287f000000000000000000000000000000000000000000000000000000000000000084612404565b60685473ffffffffffffffffffffffffffffffffffffffff1615613269576068546132699073ffffffffffffffffffffffffffffffffffffffff1683612404565b505050505050565b600054610100900460ff168061328a575060005460ff16155b613316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091d565b600054610100900460ff1615801561335557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b6001805580156118ce57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b600054610100900460ff16806133a3575060005460ff16155b61342f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091d565b600054610100900460ff16158015612d3257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661010117905580156118ce57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b60008060008060695460fa61ffff166134b79190613b95565b90506134de6134c882612710613c48565b6134d487612710613be8565b61064d9190613bad565b93506127106134ee60fa86613be8565b6134f89190613bad565b92506127106069548561350b9190613be8565b6135159190613bad565b93959294505050565b82805461352a90613c8b565b90600052602060002090601f01602090048101928261354c5760008555613592565b82601f1061356557805160ff1916838001178555613592565b82800160010185558215613592579182015b82811115613592578251825591602001919060010190613577565b5061359e9291506135a2565b5090565b5b8082111561359e57600081556001016135a3565b600082601f8301126135c857600080fd5b813567ffffffffffffffff808211156135e3576135e3613d9f565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561362957613629613d9f565b8160405283815286602085880101111561364257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006040828403121561367457600080fd5b50919050565b60006020828403121561368c57600080fd5b813561369781613dce565b9392505050565b6000602082840312156136b057600080fd5b815161369781613dce565b600080600080608085870312156136d157600080fd5b84356136dc81613dce565b935060208501356136ec81613dce565b925060408501359150606085013567ffffffffffffffff81111561370f57600080fd5b61371b878288016135b7565b91505092959194509250565b600080600080600080600080610140898b03121561374457600080fd5b883561374f81613dce565b9750602089013561375f81613dce565b9650604089013595506060890135945061377c8a60808b01613662565b935061378b8a60c08b01613662565b925061010089013567ffffffffffffffff808211156137a957600080fd5b6137b58c838d016135b7565b93506101208b01359150808211156137cc57600080fd5b506137d98b828c016135b7565b9150509295985092959890939650565b600080604083850312156137fc57600080fd5b823561380781613dce565b9150602083013567ffffffffffffffff81111561382357600080fd5b61382f858286016135b7565b9150509250929050565b6000806040838503121561384c57600080fd5b823561385781613dce565b946020939093013593505050565b60006020828403121561387757600080fd5b8151801515811461369757600080fd5b60006020828403121561389957600080fd5b5035919050565b6000602082840312156138b257600080fd5b5051919050565b600081518084526138d1816020860160208601613c5f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6003811061393a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8054600090600181811c908083168061395857607f831692505b6020808410821415613993577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b838852602088018280156139ae57600181146139dd57613a08565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00871682528282019750613a08565b60008981526020902060005b87811015613a02578154848201529086019084016139e9565b83019850505b5050505050505092915050565b60008251613a27818460208701613c5f565b9190910192915050565b7f50617274794269643a3a6269643a20706c61636520626964206661696c65643a81527f2000000000000000000000000000000000000000000000000000000000000000602082015260008251613a8f816021850160208701613c5f565b9190910160210192915050565b8215158152604060208201526000613ab760408301846138b9565b949350505050565b60208101611d9b8284613903565b60808101613adb8287613903565b84602083015283604083015282606083015295945050505050565b60208152600061369760208301846138b9565b60e081526000613b1c60e083018a61393e565b8281036020840152613b2e818a61393e565b73ffffffffffffffffffffffffffffffffffffffff98909816604084015250506060810194909452608084019290925260a083015260c09091015292915050565b600061ffff808316818516808303821115613b8c57613b8c613d12565b01949350505050565b60008219821115613ba857613ba8613d12565b500190565b600082613be3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613c2057613c20613d12565b500290565b600061ffff83811690831681811015613c4057613c40613d12565b039392505050565b600082821015613c5a57613c5a613d12565b500390565b60005b83811015613c7a578181015183820152602001613c62565b838111156125695750506000910152565b600181811c90821680613c9f57607f821691505b60208210811415613674577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613d0b57613d0b613d12565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff811681146118ce57600080fdfea264697066735822122070a1c15b33f33ab742236d689fc23f810556f5ca4d7fd641e283b6467dc40c5164736f6c63430008050033000000000000000000000000f7f52dd34bc21eda08c0b804c7c1dbc48375820f00000000000000000000000085aa7f78bdb2de8f3e0c0010d99ad5853ffcfc63000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100725760003560e01c806357dbdf541161005057806357dbdf5414610116578063c82816cb14610144578063d7dfa0dd1461015757600080fd5b80630b203023146100775780633c4d12d9146100c85780633fc8cef3146100ef575b600080fd5b61009e7f00000000000000000000000085aa7f78bdb2de8f3e0c0010d99ad5853ffcfc6381565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61009e7f000000000000000000000000f7f52dd34bc21eda08c0b804c7c1dbc48375820f81565b61009e7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b610136610124366004610403565b60006020819052908152604090205481565b6040519081526020016100bf565b61009e610152366004610425565b61017e565b61009e7f000000000000000000000000744c2be04d079eddb21c1a9bb13bb5259a36861481565b600080631d4667fa60e01b8a8a8a8a8a8a8a8a6040516024016101a8989796959493929190610616565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090507f000000000000000000000000744c2be04d079eddb21c1a9bb13bb5259a368614816040516102359061030a565b61024092919061069b565b604051809103906000f08015801561025c573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff81166000908152602081815260409091204390559092507f2e13a1db67858d419104348669d9bb778dcbefae90d4c5b743825c5ddba7b09b90839033908c908c908f908d906102c3908e018e610403565b6020808f0135906102d6908f018f610403565b8e602001358e8e6040516102f59c9b9a9998979695949392919061057a565b60405180910390a15098975050505050505050565b6103578061070283390190565b803573ffffffffffffffffffffffffffffffffffffffff8116811461033b57600080fd5b919050565b600082601f83011261035157600080fd5b813567ffffffffffffffff8082111561036c5761036c6106d2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156103b2576103b26106d2565b816040528381528660208588010111156103cb57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000604082840312156103fd57600080fd5b50919050565b60006020828403121561041557600080fd5b61041e82610317565b9392505050565b600080600080600080600080610140898b03121561044257600080fd5b61044b89610317565b975061045960208a01610317565b965060408901359550606089013594506104768a60808b016103eb565b93506104858a60c08b016103eb565b925061010089013567ffffffffffffffff808211156104a357600080fd5b6104af8c838d01610340565b93506101208b01359150808211156104c657600080fd5b506104d38b828c01610340565b9150509295985092959890939650565b6000815180845260005b81811015610509576020818501810151868301820152016104ed565b8181111561051b576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff61056c82610317565b168252602090810135910152565b600073ffffffffffffffffffffffffffffffffffffffff808f168352808e166020840152808d1660408401528b6060840152808b1660808401528960a084015280891660c08401528760e084015280871661010084015250846101208301526101806101408301526105f06101808301856104e3565b82810361016084015261060381856104e3565b9f9e505050505050505050505050505050565b600061014073ffffffffffffffffffffffffffffffffffffffff808c168452808b16602085015250886040840152876060840152610657608084018861054e565b61066460c084018761054e565b80610100840152610677818401866104e3565b905082810361012084015261068c81856104e3565b9b9a5050505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006106ca60408301846104e3565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfe60a060405234801561001057600080fd5b5060405161035738038061035783398101604081905261002f916100d7565b6001600160601b0319606083901b1660805260405160009081906001600160a01b0385169061005f9085906101a5565b600060405180830381855af49150503d806000811461009a576040519150601f19603f3d011682016040523d82523d6000602084013e61009f565b606091505b50915091508181906100cd5760405162461bcd60e51b81526004016100c491906101c1565b60405180910390fd5b505050505061023a565b600080604083850312156100ea57600080fd5b82516001600160a01b038116811461010157600080fd5b60208401519092506001600160401b038082111561011e57600080fd5b818501915085601f83011261013257600080fd5b81518181111561014457610144610224565b604051601f8201601f19908116603f0116810190838211818310171561016c5761016c610224565b8160405282815288602084870101111561018557600080fd5b6101968360208301602088016101f4565b80955050505050509250929050565b600082516101b78184602087016101f4565b9190910192915050565b60208152600082518060208401526101e08160408501602087016101f4565b601f01601f19169190910160400192915050565b60005b8381101561020f5781810151838201526020016101f7565b8381111561021e576000848401525b50505050565b634e487b7160e01b600052604160045260246000fd5b60805160601c60fc61025b60003960008181602a0152607b015260fc6000f3fe608060405260043610601f5760003560e01c8063d7dfa0dd14606b576025565b36602557005b6040517f00000000000000000000000000000000000000000000000000000000000000009036600082376000803683855af43d806000843e8180156067578184f35b8184fd5b348015607657600080fd5b50609d7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f3fea2646970667358221220a3350e7abb318cfd6c2f0227ef2ec856c01e215d98d5d2e5e2202e41a3c4deaf64736f6c63430008050033a2646970667358221220ae1d5b1be7b488b2d1931b20c2071b2080ebb4da4ead609cdb5431a08849890c64736f6c63430008050033

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

000000000000000000000000f7f52dd34bc21eda08c0b804c7c1dbc48375820f00000000000000000000000085aa7f78bdb2de8f3e0c0010d99ad5853ffcfc63000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2

-----Decoded View---------------
Arg [0] : _partyDAOMultisig (address): 0xF7f52Dd34bc21eDA08c0b804C7c1dbc48375820f
Arg [1] : _tokenVaultFactory (address): 0x85Aa7f78BdB2DE8F3e0c0010d99AD5853fFcfC63
Arg [2] : _weth (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000f7f52dd34bc21eda08c0b804c7c1dbc48375820f
Arg [1] : 00000000000000000000000085aa7f78bdb2de8f3e0c0010d99ad5853ffcfc63
Arg [2] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2


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  ]

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.