ETH Price: $2,133.02 (+3.04%)

Contract

0xD96Ff9e48f095f5a22Db5bDFFCA080bCC3B98c7f
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Start Party129855332021-08-08 16:25:211678 days ago1628439921IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.0167894650.25671249
Start Party129852672021-08-08 15:24:371678 days ago1628436277IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.0122568236.68762827
Start Party129850492021-08-08 14:42:141678 days ago1628433734IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.011155233.39023276
Start Party129843392021-08-08 12:08:271678 days ago1628424507IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.0092223327
Start Party129798482021-08-07 19:27:561678 days ago1628364476IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.0160309448
Start Party129751872021-08-07 2:20:141679 days ago1628302814IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.0185400455.50877528
Start Party129751732021-08-07 2:16:281679 days ago1628302588IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.016701350
Start Party129734572021-08-06 20:08:291679 days ago1628280509IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.0182581353.4538868
Start Party129724332021-08-06 16:18:541680 days ago1628266734IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.03363475100.7022581
Start Party129709752021-08-06 10:48:201680 days ago1628246900IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.0099911929.2355541
Start Party129708262021-08-06 10:16:021680 days ago1628244962IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.0101040829.56588148
Start Party129706682021-08-06 9:41:321680 days ago1628242892IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.0118780335.54744163
Start Party129694862021-08-06 5:18:101680 days ago1628227090IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.0110232533
Start Party129680582021-08-05 23:58:411680 days ago1628207921IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.011464734.31664046
Start Party129671332021-08-05 20:34:421680 days ago1628195682IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.0217667465.13673501
Start Party129661032021-08-05 16:46:011680 days ago1628181961IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.0231156369.16084872
Start Party129658732021-08-05 15:55:271681 days ago1628178927IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.03690748108
Start Party129653672021-08-05 14:02:041681 days ago1628172124IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.0285256385.40252793
Start Party129649692021-08-05 12:28:361681 days ago1628166516IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.0095548528.6
Start Party129649032021-08-05 12:15:531681 days ago1628165753IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.0162849348.75
Start Party129640072021-08-05 8:55:071681 days ago1628153707IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.015373845
Start Party129636432021-08-05 7:27:201681 days ago1628148440IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.0140366542
Start Party129626542021-08-05 3:40:061681 days ago1628134806IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.0153679546
Start Party129616962021-08-04 23:55:371681 days ago1628121337IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.0122397736.3
Start Party129616162021-08-04 23:37:361681 days ago1628120256IN
0xD96Ff9e4...CC3B98c7f
0 ETH0.0121277536.3
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
-129855332021-08-08 16:25:211678 days ago1628439921
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129852672021-08-08 15:24:371678 days ago1628436277
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129850492021-08-08 14:42:141678 days ago1628433734
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129843392021-08-08 12:08:271678 days ago1628424507
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129798482021-08-07 19:27:561678 days ago1628364476
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129751872021-08-07 2:20:141679 days ago1628302814
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129751732021-08-07 2:16:281679 days ago1628302588
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129734572021-08-06 20:08:291679 days ago1628280509
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129724332021-08-06 16:18:541680 days ago1628266734
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129709752021-08-06 10:48:201680 days ago1628246900
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129708262021-08-06 10:16:021680 days ago1628244962
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129706682021-08-06 9:41:321680 days ago1628242892
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129694862021-08-06 5:18:101680 days ago1628227090
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129680582021-08-05 23:58:411680 days ago1628207921
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129671332021-08-05 20:34:421680 days ago1628195682
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129661032021-08-05 16:46:011680 days ago1628181961
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129658732021-08-05 15:55:271681 days ago1628178927
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129653672021-08-05 14:02:041681 days ago1628172124
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129649692021-08-05 12:28:361681 days ago1628166516
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129649032021-08-05 12:15:531681 days ago1628165753
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129640072021-08-05 8:55:071681 days ago1628153707
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129636432021-08-05 7:27:201681 days ago1628148440
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129626542021-08-05 3:40:061681 days ago1628134806
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129616962021-08-04 23:55:371681 days ago1628121337
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
-129616162021-08-04 23:37:361681 days ago1628120256
0xD96Ff9e4...CC3B98c7f
 Contract Creation0 ETH
View All Internal Transactions
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
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 14 : PartyBidFactory.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.5;

import {InitializedProxy} from "./InitializedProxy.sol";
import {PartyBid} from "./PartyBid.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,
        string name,
        string symbol
    );

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

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

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

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

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

    function startParty(
        address _marketWrapper,
        address _nftContract,
        uint256 _tokenId,
        uint256 _auctionId,
        string memory _name,
        string memory _symbol
    ) external returns (address partyBidProxy) {
        bytes memory _initializationCalldata =
            abi.encodeWithSignature(
                "initialize(address,address,uint256,uint256,string,string)",
                _marketWrapper,
                _nftContract,
                _tokenId,
                _auctionId,
                _name,
                _symbol
            );

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

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

File 2 of 14 : 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
}

/*

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

PartyBid v1
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 {
    IERC721Metadata
} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
import {IWETH} from "./external/interfaces/IWETH.sol";

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

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

    // State Transitions:
    //   (1) AUCTION_ACTIVE on deploy
    //   (2) AUCTION_WON or AUCTION_LOST on finalize()
    enum PartyStatus {AUCTION_ACTIVE, AUCTION_WON, AUCTION_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;
    // PartyBid pays a 5% fee to PartyDAO
    uint8 internal constant FEE_PERCENT = 5;

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

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

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

    // market wrapper contract exposing interface for
    // market auctioning the NFT
    address public marketWrapper;
    // NFT contract
    address public nftContract;
    // Fractionalized NFT vault responsible for post-auction value capture
    address public tokenVault;
    // ID of auction within market contract
    uint256 public auctionId;
    // ID of token within NFT contract
    uint256 public tokenId;
    // 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 highest bid submitted by PartyBid
    uint256 public highestBid;
    // the total spent by PartyBid on the auction;
    // 0 if the NFT is lost; highest bid + 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 Bid(uint256 amount);

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

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

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

    constructor(
        address _partyDAOMultisig,
        address _tokenVaultFactory,
        address _weth
    ) {
        partyDAOMultisig = _partyDAOMultisig;
        tokenVaultFactory = _tokenVaultFactory;
        weth = _weth;
    }

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

    function initialize(
        address _marketWrapper,
        address _nftContract,
        uint256 _tokenId,
        uint256 _auctionId,
        string memory _name,
        string memory _symbol
    ) external initializer {
        // initialize ReentrancyGuard and ERC721Holder
        __ReentrancyGuard_init();
        __ERC721Holder_init();
        // set storage variables
        marketWrapper = _marketWrapper;
        nftContract = _nftContract;
        tokenId = _tokenId;
        auctionId = _auctionId;
        name = _name;
        symbol = _symbol;
        // validate token exists (ownerOf should revert if token doesn't exist)
        IERC721Metadata(_nftContract).ownerOf(_tokenId);
        // validate auction exists
        require(
            IMarketWrapper(_marketWrapper).auctionIdMatchesToken(
                _auctionId,
                _nftContract,
                _tokenId
            ),
            "PartyBid::initialize: auctionId doesn't match token"
        );
    }

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

    /**
     * @notice Contribute to the PartyBid's treasury
     * while the auction is still open
     * @dev Emits a Contributed event upon success; callable by anyone
     */
    function contribute() external payable nonReentrant {
        require(
            partyStatus == PartyStatus.AUCTION_ACTIVE,
            "PartyBid::contribute: auction not active"
        );
        address _contributor = msg.sender;
        uint256 _amount = msg.value;
        // 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 = totalContributedToParty + _amount;
        emit Contributed(
            _contributor,
            _amount,
            _previousTotalContributedToParty,
            totalContributed[_contributor]
        );
    }

    // ======== 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.AUCTION_ACTIVE,
            "PartyBid::bid: auction not active"
        );
        require(
            totalContributed[msg.sender] > 0,
            "PartyBid::bid: only contributors can bid"
        );
        require(
            address(this) !=
                IMarketWrapper(marketWrapper).getCurrentHighestBidder(
                    auctionId
                ),
            "PartyBid::bid: already highest bidder"
        );
        require(
            !IMarketWrapper(marketWrapper).isFinalized(auctionId),
            "PartyBid::bid: auction already finalized"
        );
        // get the minimum next bid for the auction
        uint256 _bid = IMarketWrapper(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) =
            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.AUCTION_ACTIVE,
            "PartyBid::finalize: auction not active"
        );
        // finalize auction if it hasn't already been done
        if (!IMarketWrapper(marketWrapper).isFinalized(auctionId)) {
            IMarketWrapper(marketWrapper).finalize(auctionId);
        }
        // after the auction has been finalized,
        // if the NFT is owned by the PartyBid, then the PartyBid won the auction
        partyStatus = IERC721Metadata(nftContract).ownerOf(tokenId) ==
            address(this)
            ? PartyStatus.AUCTION_WON
            : PartyStatus.AUCTION_LOST;
        uint256 _fee;
        // if the auction was won,
        if (partyStatus == PartyStatus.AUCTION_WON) {
            // transfer 5% fee to PartyDAO
            _fee = _getFee(highestBid);
            _transferETHOrWETH(partyDAOMultisig, _fee);
            // record total spent by auction + PartyDAO fees
            totalSpent = highestBid + _fee;
            // deploy fractionalized NFT vault
            // and mint fractional ERC-20 tokens
            _fractionalizeNFT(totalSpent);
        }
        // set the contract status & emit result
        emit Finalized(partyStatus, totalSpent, _fee, totalContributedToParty);
    }

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

    /**
     * @notice Claim the tokens and excess ETH owed
     * to a single contributor after the auction 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 auction has finalized
        require(
            partyStatus != PartyStatus.AUCTION_ACTIVE,
            "PartyBid::claim: auction not finalized"
        );
        // ensure contributor submitted some ETH
        require(
            totalContributed[_contributor] != 0,
            "PartyBid::claim: not a contributor"
        );
        // ensure the contributor hasn't already claimed
        require(
            !claimed[_contributor],
            "PartyBid::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 auction,
        // and the amount of excess ETH owed to the user
        (uint256 _tokenAmount, uint256 _ethAmount) =
            _calculateTokensAndETHOwed(_contributor);
        // transfer tokens to contributor for their portion of ETH used
        if (_tokenAmount > 0) {
            ITokenVault(tokenVault).transfer(_contributor, _tokenAmount);
        }
        // if there is excess ETH, send it back to the contributor
        if (_ethAmount > 0) {
            _transferETHOrWETH(_contributor, _ethAmount);
        }
        emit Claimed(
            _contributor,
            totalContributed[_contributor],
            _ethAmount,
            _tokenAmount
        );
    }

    // ======== External: Recover =========

    /**
     * @notice If the NFT gets stuck in the PartyBid
     * (e.g. because of a faulty MarketWrapper that marks the auction Lost)
     * the PartyDAO Multisig can transfer the NFT to the multisig
     */
    function recover() external {
        require(
            msg.sender == partyDAOMultisig,
            "PartyBid::recover: only PartyDAO multisig can recover NFT"
        );
        require(
            partyStatus == PartyStatus.AUCTION_LOST,
            "PartyBid::recover: auction must be lost to recover NFT"
        );
        IERC721Metadata(nftContract).transferFrom(
            address(this),
            partyDAOMultisig,
            tokenId
        );
    }

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

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

    // ============ Internal: Bid ============

    /**
     * @notice The maximum bid that can be submitted
     * while leaving 5% fee for PartyDAO
     * @return _maxBid the maximum bid
     */
    function _getMaximumBid() internal view returns (uint256 _maxBid) {
        _maxBid = totalContributedToParty - _getFee(totalContributedToParty);
    }

    /**
     * @notice Calculate 5% fee for PartyDAO
     * NOTE: Remove this fee causes a critical vulnerability
     * allowing anyone to exploit a PartyBid via price manipulation.
     * See Security Review in README for more info.
     * @return _fee 5% of the given amount
     */
    function _getFee(uint256 _amount) internal pure returns (uint256 _fee) {
        _fee = (_amount * FEE_PERCENT) / 100;
    }

    // ============ Internal: Finalize ============

    /**
     * @notice Upon winning the auction, transfer the NFT
     * to fractional.art vault & mint fractional ERC-20 tokens
     */
    function _fractionalizeNFT(uint256 _totalSpent) internal {
        // approve fractionalized NFT Factory to withdraw NFT
        IERC721Metadata(nftContract).approve(tokenVaultFactory, tokenId);
        // deploy fractionalized NFT vault
        uint256 vaultNumber =
            IERC721VaultFactory(tokenVaultFactory).mint(
                name,
                symbol,
                nftContract,
                tokenId,
                valueToTokens(_totalSpent),
                _totalSpent,
                0
            );
        // store token vault address to storage
        tokenVault = IERC721VaultFactory(tokenVaultFactory).vaults(vaultNumber);
        // transfer curator to null address
        ITokenVault(tokenVault).updateCurator(address(0));
    }

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

    /**
     * @notice Calculate the amount of fractional NFT tokens owed to the contributor
     * based on how much ETH they contributed towards the auction,
     * and the amount of excess ETH owed to the contributor
     * based on how much ETH they contributed *not* used towards the auction
     * @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 _calculateTokensAndETHOwed(address _contributor)
        internal
        view
        returns (uint256 _tokenAmount, uint256 _ethAmount)
    {
        uint256 _totalContributed = totalContributed[_contributor];
        if (partyStatus == PartyStatus.AUCTION_WON) {
            // calculate the amount of this contributor's ETH
            // that was used for the winning bid
            uint256 _totalUsedForBid = _totalEthUsedForBid(_contributor);
            if (_totalUsedForBid > 0) {
                _tokenAmount = valueToTokens(_totalUsedForBid);
                // guard against rounding errors;
                // if _tokenAmount to send is greater than contract balance,
                // send full contract balance
                uint256 _totalBalance =
                    ITokenVault(tokenVault).balanceOf(address(this));
                if (_tokenAmount > _totalBalance) {
                    _tokenAmount = _totalBalance;
                }
            }
            // the rest of the contributor's ETH should be returned
            _ethAmount = _totalContributed - _totalUsedForBid;
        } else {
            // if the auction was lost, 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 winning auction bid
     * @param _contributor the address of the contributor
     * @return _total the sum of the contributor's funds that were
     * used towards the winning auction bid
     */
    function _totalEthUsedForBid(address _contributor)
        internal
        view
        returns (uint256 _total)
    {
        // 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 = _ethUsedForBid(_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;
        }
    }

    /**
     * @notice Calculate the amount that was used towards
     * the winning auction bid from a single Contribution
     * @param _contribution the Contribution struct
     * @return the amount of funds from this contribution
     * that were used towards the winning auction bid
     */
    function _ethUsedForBid(Contribution memory _contribution)
        internal
        view
        returns (uint256)
    {
        // load total amount spent once from storage
        uint256 _totalSpent = totalSpent;
        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: 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 {
        // 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
            IWETH(weth).deposit{value: _value}();
            IWETH(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;
    }
}

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

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

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

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

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

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

interface IWETH {
    function deposit() external payable;

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

// 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 Determine whether there is an existing auction
     * for this token on the underlying market
     * @return TRUE if the auction exists
     */
    function auctionExists(uint256 auctionId) external view returns (bool);

    /**
     * @notice Determine whether the given auctionId is
     * an auction for the tokenId + nftContract
     * @return TRUE if the auctionId matches the tokenId + nftContract
     */
    function auctionIdMatchesToken(
        uint256 auctionId,
        address nftContract,
        uint256 tokenId
    ) external view returns (bool);

    /**
     * @notice Calculate the minimum next bid for this auction
     * @return minimum bid amount
     */
    function getMinimumBid(uint256 auctionId) external view returns (uint256);

    /**
     * @notice Query the current highest bidder for this auction
     * @return highest bidder
     */
    function getCurrentHighestBidder(uint256 auctionId)
        external
        view
        returns (address);

    /**
     * @notice Submit bid to Market contract
     */
    function bid(uint256 auctionId, uint256 bidAmount) external;

    /**
     * @notice Determine whether the auction has been finalized
     * @return TRUE if the auction has been finalized
     */
    function isFinalized(uint256 auctionId) external view returns (bool);

    /**
     * @notice Finalize the results of the auction
     */
    function finalize(uint256 auctionId) external;
}

File 11 of 14 : 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;
        }
    }
}

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

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

// 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",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"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":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"}],"name":"PartyBidDeployed","type":"event"},{"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"},{"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"}]

61010060405234801561001157600080fd5b50604051613d68380380613d68833981016040819052610030916100e3565b6001600160601b0319606084811b821660a05283811b821660c05282901b1660e052604051839083908390610064906100ba565b6001600160a01b03938416815291831660208301529091166040820152606001604051809103906000f0801580156100a0573d6000803e3d6000fd5b5060601b6001600160601b03191660805250610126915050565b6132c380610aa583390190565b80516001600160a01b03811681146100de57600080fd5b919050565b6000806000606084860312156100f857600080fd5b610101846100c7565b925061010f602085016100c7565b915061011d604085016100c7565b90509250925092565b60805160601c60a05160601c60c05160601c60e05160601c61093661016f600039600060e80152600060710152600060c101526000818161012201526101de01526109366000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80633fc8cef3116100505780633fc8cef3146100e3578063d7d4a9ce1461010a578063d7dfa0dd1461011d57600080fd5b80630b2030231461006c5780633c4d12d9146100bc575b600080fd5b6100937f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100937f000000000000000000000000000000000000000000000000000000000000000081565b6100937f000000000000000000000000000000000000000000000000000000000000000081565b610093610118366004610364565b610144565b6100937f000000000000000000000000000000000000000000000000000000000000000081565b600080878787878787604051602401610162969594939291906104df565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fe001ff5200000000000000000000000000000000000000000000000000000000179052519091507f000000000000000000000000000000000000000000000000000000000000000090829061020990610283565b610214929190610543565b604051809103906000f080158015610230573d6000803e3d6000fd5b5091507f050cc06436bbc2fe72596f120f90651e8b56b2c1fc7b8361f1b043ffc7c2594f823389898c8a8a8a604051610270989796959493929190610466565b60405180910390a1509695505050505050565b610357806105aa83390190565b803573ffffffffffffffffffffffffffffffffffffffff811681146102b457600080fd5b919050565b600082601f8301126102ca57600080fd5b813567ffffffffffffffff808211156102e5576102e561057a565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561032b5761032b61057a565b8160405283815286602085880101111561034457600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060008060008060c0878903121561037d57600080fd5b61038687610290565b955061039460208801610290565b94506040870135935060608701359250608087013567ffffffffffffffff808211156103bf57600080fd5b6103cb8a838b016102b9565b935060a08901359150808211156103e157600080fd5b506103ee89828a016102b9565b9150509295509295509295565b6000815180845260005b8181101561042157602081850181015186830182015201610405565b81811115610433576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061010073ffffffffffffffffffffffffffffffffffffffff808c168452808b166020850152808a1660408501528860608501528088166080850152508560a08401528060c08401526104bc818401866103fb565b905082810360e08401526104d081856103fb565b9b9a5050505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835280881660208401525085604083015284606083015260c0608083015261052460c08301856103fb565b82810360a084015261053681856103fb565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061057260408301846103fb565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfe60a060405234801561001057600080fd5b5060405161035738038061035783398101604081905261002f916100d7565b6001600160601b0319606083901b1660805260405160009081906001600160a01b0385169061005f9085906101a5565b600060405180830381855af49150503d806000811461009a576040519150601f19603f3d011682016040523d82523d6000602084013e61009f565b606091505b50915091508181906100cd5760405162461bcd60e51b81526004016100c491906101c1565b60405180910390fd5b505050505061023a565b600080604083850312156100ea57600080fd5b82516001600160a01b038116811461010157600080fd5b60208401519092506001600160401b038082111561011e57600080fd5b818501915085601f83011261013257600080fd5b81518181111561014457610144610224565b604051601f8201601f19908116603f0116810190838211818310171561016c5761016c610224565b8160405282815288602084870101111561018557600080fd5b6101968360208301602088016101f4565b80955050505050509250929050565b600082516101b78184602087016101f4565b9190910192915050565b60208152600082518060208401526101e08160408501602087016101f4565b601f01601f19169190910160400192915050565b60005b8381101561020f5781810151838201526020016101f7565b8381111561021e576000848401525b50505050565b634e487b7160e01b600052604160045260246000fd5b60805160601c60fc61025b60003960008181602a0152607b015260fc6000f3fe608060405260043610601f5760003560e01c8063d7dfa0dd14606b576025565b36602557005b6040517f00000000000000000000000000000000000000000000000000000000000000009036600082376000803683855af43d806000843e8180156067578184f35b8184fd5b348015607657600080fd5b50609d7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f3fea2646970667358221220a3350e7abb318cfd6c2f0227ef2ec856c01e215d98d5d2e5e2202e41a3c4deaf64736f6c63430008050033a26469706673582212201fb4517a171ffd9cd28a6aa477f0e14f12b32ddefa0ba2b007104ad486f33cf564736f6c6343000805003360e06040523480156200001157600080fd5b50604051620032c3380380620032c3833981016040819052620000349162000079565b6001600160601b0319606093841b811660805291831b821660a05290911b1660c052620000c3565b80516001600160a01b03811681146200007457600080fd5b919050565b6000806000606084860312156200008f57600080fd5b6200009a846200005c565b9250620000aa602085016200005c565b9150620000ba604085016200005c565b90509250925092565b60805160601c60a05160601c60c05160601c61318f620001346000396000818161034b01528181611f1a0152611fe20152600081816101d8015281816120c401528181612134015261224a015260008181610317015281816114ea015281816115f1015261178d015261318f6000f3fe6080604052600436106101965760003560e01c806382a5c69a116100e1578063d56d229d1161008a578063df51c07f11610064578063df51c07f146104fc578063e001ff5214610523578063ef38bf0114610543578063fb346eab1461057057600080fd5b8063d56d229d146104b1578063d57bde79146104de578063d7bb99ba146104f457600080fd5b8063a0f243b8116100bb578063a0f243b81461042f578063c884ef831461045c578063ce7460241461049c57600080fd5b806382a5c69a146103e457806395d89b41146103fa5780639744b8dc1461040f57600080fd5b80631e83409a116101435780634bb278f31161011d5780634bb278f31461036d578063550b521c146103825780635bc789d9146103b757600080fd5b80631e83409a146102e55780633c4d12d9146103055780633fc8cef31461033957600080fd5b8063150b7a0211610174578063150b7a021461024357806317d70f7c146102b85780631998aeef146102ce57600080fd5b806306fdde031461019b5780630b203023146101c657806310782f8f1461021f575b600080fd5b3480156101a757600080fd5b506101b0610586565b6040516101bd9190612e64565b60405180910390f35b3480156101d257600080fd5b506101fa7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bd565b34801561022b57600080fd5b5061023560685481565b6040519081526020016101bd565b34801561024f57600080fd5b5061028761025e366004612af9565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016101bd565b3480156102c457600080fd5b5061023560695481565b3480156102da57600080fd5b506102e3610614565b005b3480156102f157600080fd5b506102e3610300366004612abf565b610d45565b34801561031157600080fd5b506101fa7f000000000000000000000000000000000000000000000000000000000000000081565b34801561034557600080fd5b506101fa7f000000000000000000000000000000000000000000000000000000000000000081565b34801561037957600080fd5b506102e3611158565b34801561038e57600080fd5b506103a261039d366004612c14565b61157c565b604080519283526020830191909152016101bd565b3480156103c357600080fd5b506067546101fa9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103f057600080fd5b50610235606d5481565b34801561040657600080fd5b506101b06115b8565b34801561041b57600080fd5b5061023561042a366004612c62565b6115c5565b34801561043b57600080fd5b5061023561044a366004612abf565b60716020526000908152604090205481565b34801561046857600080fd5b5061048c610477366004612abf565b60726020526000908152604090205460ff1681565b60405190151581526020016101bd565b3480156104a857600080fd5b506102e36115d9565b3480156104bd57600080fd5b506066546101fa9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104ea57600080fd5b50610235606e5481565b6102e36117fb565b34801561050857600080fd5b50606c546105169060ff1681565b6040516101bd9190612e2d565b34801561052f57600080fd5b506102e361053e366004612b79565b611a1f565b34801561054f57600080fd5b506065546101fa9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561057c57600080fd5b50610235606f5481565b606a805461059390612fee565b80601f01602080910402602001604051908101604052809291908181526020018280546105bf90612fee565b801561060c5780601f106105e15761010080835404028352916020019161060c565b820191906000526020600020905b8154815290600101906020018083116105ef57829003601f168201915b505050505081565b60026001541415610686576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b60026001556000606c5460ff1660028111156106a4576106a46130aa565b14610731576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f50617274794269643a3a6269643a2061756374696f6e206e6f7420616374697660448201527f6500000000000000000000000000000000000000000000000000000000000000606482015260840161067d565b336000908152607160205260409020546107cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f50617274794269643a3a6269643a206f6e6c7920636f6e7472696275746f727360448201527f2063616e20626964000000000000000000000000000000000000000000000000606482015260840161067d565b6065546068546040517f456b09c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9092169163456b09c1916108289160040190815260200190565b60206040518083038186803b15801561084057600080fd5b505afa158015610854573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108789190612adc565b73ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff161415610933576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50617274794269643a3a6269643a20616c72656164792068696768657374206260448201527f6964646572000000000000000000000000000000000000000000000000000000606482015260840161067d565b6065546068546040517f33727c4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909216916333727c4d9161098e9160040190815260200190565b60206040518083038186803b1580156109a657600080fd5b505afa1580156109ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109de9190612c40565b15610a6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f50617274794269643a3a6269643a2061756374696f6e20616c7265616479206660448201527f696e616c697a6564000000000000000000000000000000000000000000000000606482015260840161067d565b6065546068546040517f0600d4eb000000000000000000000000000000000000000000000000000000008152600481019190915260009173ffffffffffffffffffffffffffffffffffffffff1690630600d4eb9060240160206040518083038186803b158015610ada57600080fd5b505afa158015610aee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b129190612c7b565b9050610b1c611daa565b811115610bab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f50617274794269643a3a6269643a20696e73756666696369656e742066756e6460448201527f7320746f20626964000000000000000000000000000000000000000000000000606482015260840161067d565b606554606854604051602481019190915260448101839052600091829173ffffffffffffffffffffffffffffffffffffffff90911690606401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f598647f80000000000000000000000000000000000000000000000000000000017905251610c659190612da6565b600060405180830381855af49150503d8060008114610ca0576040519150601f19603f3d011682016040523d82523d6000602084013e610ca5565b606091505b50915091508181604051602001610cbc9190612dc2565b60405160208183030381529060405290610d03576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161067d9190612e64565b50606e8390556040518381527f7a183e84509e3fe5b0b3aac15347fd1c7d71fd1503001f1a1d7c9658077eb35f9060200160405180910390a150506001805550565b60026001541415610db2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161067d565b60026001556000606c5460ff166002811115610dd057610dd06130aa565b1415610e5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f50617274794269643a3a636c61696d3a2061756374696f6e206e6f742066696e60448201527f616c697a65640000000000000000000000000000000000000000000000000000606482015260840161067d565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260716020526040902054610f10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f50617274794269643a3a636c61696d3a206e6f74206120636f6e74726962757460448201527f6f72000000000000000000000000000000000000000000000000000000000000606482015260840161067d565b73ffffffffffffffffffffffffffffffffffffffff811660009081526072602052604090205460ff1615610fc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f50617274794269643a3a636c61696d3a20636f6e747269627574696f6e20616c60448201527f726561647920636c61696d656400000000000000000000000000000000000000606482015260840161067d565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260726020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558061101e83611dc9565b909250905081156110d7576067546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590529091169063a9059cbb90604401602060405180830381600087803b15801561109d57600080fd5b505af11580156110b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d59190612c40565b505b80156110e7576110e78382611eff565b73ffffffffffffffffffffffffffffffffffffffff83166000818152607160209081526040918290205482519081529081018490529081018490527f9cdcf2f7714cca3508c7f0110b04a90a80a3a8dd0e35de99689db74d28c5383e9060600160405180910390a250506001805550565b600260015414156111c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161067d565b60026001556000606c5460ff1660028111156111e3576111e36130aa565b14611270576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f50617274794269643a3a66696e616c697a653a2061756374696f6e206e6f742060448201527f6163746976650000000000000000000000000000000000000000000000000000606482015260840161067d565b6065546068546040517f33727c4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909216916333727c4d916112cb9160040190815260200190565b60206040518083038186803b1580156112e357600080fd5b505afa1580156112f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061131b9190612c40565b6113ad576065546068546040517f05261aea00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909216916305261aea9161137a9160040190815260200190565b600060405180830381600087803b15801561139457600080fd5b505af11580156113a8573d6000803e3d6000fd5b505050505b6066546069546040517f6352211e0000000000000000000000000000000000000000000000000000000081526004810191909152309173ffffffffffffffffffffffffffffffffffffffff1690636352211e9060240160206040518083038186803b15801561141b57600080fd5b505afa15801561142f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114539190612adc565b73ffffffffffffffffffffffffffffffffffffffff1614611475576002611478565b60015b606c80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660018360028111156114b2576114b26130aa565b021790555060006001606c5460ff1660028111156114d2576114d26130aa565b141561152b576114e3606e54612068565b905061150f7f000000000000000000000000000000000000000000000000000000000000000082611eff565b80606e5461151d9190612f1b565b606f81905561152b90612081565b606c54606f54606d546040517f9a2087478f16b801ecd568a6676f5db758bda2a01b954b2c754257d11eb3770b9361156d9360ff909116929091869190612e3b565b60405180910390a15060018055565b6070602052816000526040600020818154811061159857600080fd5b600091825260209091206002909102018054600190910154909250905082565b606b805461059390612fee565b60006115d36103e883612f6e565b92915050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461169e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50617274794269643a3a7265636f7665723a206f6e6c7920506172747944414f60448201527f206d756c74697369672063616e207265636f766572204e465400000000000000606482015260840161067d565b6002606c5460ff1660028111156116b7576116b76130aa565b14611744576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f50617274794269643a3a7265636f7665723a2061756374696f6e206d7573742060448201527f6265206c6f737420746f207265636f766572204e465400000000000000000000606482015260840161067d565b6066546069546040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602483015260448201929092529116906323b872dd90606401600060405180830381600087803b1580156117e157600080fd5b505af11580156117f5573d6000803e3d6000fd5b50505050565b60026001541415611868576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161067d565b60026001556000606c5460ff166002811115611886576118866130aa565b14611913576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f50617274794269643a3a636f6e747269627574653a2061756374696f6e206e6f60448201527f7420616374697665000000000000000000000000000000000000000000000000606482015260840161067d565b606d5460408051808201825234808252602080830185815233600081815260708452868120805460018181018355918352858320885160029092020190815593519301929092558082526071909252939093205492939092909190611979908490612f1b565b73ffffffffffffffffffffffffffffffffffffffff8516600090815260716020526040902055606d546119ad908490612f1b565b606d5573ffffffffffffffffffffffffffffffffffffffff84166000818152607160209081526040918290205482518781529182018690528183015290517fb2623081601722547aae8781994e01a1974d95b0ad9ce6a0cfbe17487556257f9181900360600190a25050600180555050565b600054610100900460ff1680611a38575060005460ff16155b611ac4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161067d565b600054610100900460ff16158015611b0357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b611b0b61238b565b611b136124a9565b6065805473ffffffffffffffffffffffffffffffffffffffff808a167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556066805492891692909116919091179055606985905560688490558251611b8590606a906020860190612972565b508151611b9990606b906020850190612972565b506040517f6352211e0000000000000000000000000000000000000000000000000000000081526004810186905273ffffffffffffffffffffffffffffffffffffffff871690636352211e9060240160206040518083038186803b158015611c0057600080fd5b505afa158015611c14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c389190612adc565b506040517f97e2d3800000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff8781166024830152604482018790528816906397e2d3809060640160206040518083038186803b158015611cae57600080fd5b505afa158015611cc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ce69190612c40565b611d72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f50617274794269643a3a696e697469616c697a653a2061756374696f6e49642060448201527f646f65736e2774206d6174636820746f6b656e00000000000000000000000000606482015260840161067d565b8015611da157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050505050565b6000611db7606d54612068565b606d54611dc49190612fab565b905090565b73ffffffffffffffffffffffffffffffffffffffff811660009081526071602052604081205481906001606c5460ff166002811115611e0a57611e0a6130aa565b1415611ef5576000611e1b85612595565b90508015611ee357611e2c816115c5565b6067546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015291955060009173ffffffffffffffffffffffffffffffffffffffff909116906370a082319060240160206040518083038186803b158015611e9b57600080fd5b505afa158015611eaf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ed39190612c7b565b905080851115611ee1578094505b505b611eed8183612fab565b925050611ef9565b8091505b50915091565b47811115611f0a5750475b611f148282612685565b612064577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015611f8057600080fd5b505af1158015611f94573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152602482018690527f000000000000000000000000000000000000000000000000000000000000000016935063a9059cbb92506044019050602060405180830381600087803b15801561202a57600080fd5b505af115801561203e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120629190612c40565b505b5050565b60006064612077600584612f6e565b6115d39190612f33565b6066546069546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166004830152602482019290925291169063095ea7b390604401600060405180830381600087803b15801561211857600080fd5b505af115801561212c573d6000803e3d6000fd5b5050505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663bdc01110606a606b606660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166069546121a1886115c5565b8860006040518863ffffffff1660e01b81526004016121c69796959493929190612eb5565b602060405180830381600087803b1580156121e057600080fd5b505af11580156121f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122189190612c7b565b6040517f8c64ea4a000000000000000000000000000000000000000000000000000000008152600481018290529091507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690638c64ea4a90602401602060405180830381600087803b1580156122a357600080fd5b505af11580156122b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122db9190612adc565b606780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691821790556040517f0c6a62dd00000000000000000000000000000000000000000000000000000000815260006004820152630c6a62dd90602401600060405180830381600087803b15801561236f57600080fd5b505af1158015612383573d6000803e3d6000fd5b505050505050565b600054610100900460ff16806123a4575060005460ff16155b612430576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161067d565b600054610100900460ff1615801561246f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b6124776126f5565b80156124a657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50565b600054610100900460ff16806124c2575060005460ff16155b61254e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161067d565b600054610100900460ff1615801561258d57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b61247761280e565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260706020908152604080832080548251818502810185019093528083528493849084015b8282101561261b578382906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050815260200190600101906125d5565b50505050905060005b815181101561267e576000612651838381518110612644576126446130d9565b6020026020010151612922565b90508061265e575061267e565b6126688185612f1b565b935050808061267690613042565b915050612624565b5050919050565b6000808373ffffffffffffffffffffffffffffffffffffffff168361753090604051600060405180830381858888f193505050503d80600081146126e5576040519150601f19603f3d011682016040523d82523d6000602084013e6126ea565b606091505b509095945050505050565b600054610100900460ff168061270e575060005460ff16155b61279a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161067d565b600054610100900460ff161580156127d957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b6001805580156124a657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b600054610100900460ff1680612827575060005460ff16155b6128b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161067d565b600054610100900460ff1615801561247757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661010117905580156124a657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b606f548151602083015160009291829161293c9190612f1b565b116129475750505190565b80836020015110156129695760208301516129629082612fab565b9392505050565b50600092915050565b82805461297e90612fee565b90600052602060002090601f0160209004810192826129a057600085556129e6565b82601f106129b957805160ff19168380011785556129e6565b828001600101855582156129e6579182015b828111156129e65782518255916020019190600101906129cb565b506129f29291506129f6565b5090565b5b808211156129f257600081556001016129f7565b600067ffffffffffffffff80841115612a2657612a26613108565b604051601f85017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612a6c57612a6c613108565b81604052809350858152868686011115612a8557600080fd5b858560208301376000602087830101525050509392505050565b600082601f830112612ab057600080fd5b61296283833560208501612a0b565b600060208284031215612ad157600080fd5b813561296281613137565b600060208284031215612aee57600080fd5b815161296281613137565b60008060008060808587031215612b0f57600080fd5b8435612b1a81613137565b93506020850135612b2a81613137565b925060408501359150606085013567ffffffffffffffff811115612b4d57600080fd5b8501601f81018713612b5e57600080fd5b612b6d87823560208401612a0b565b91505092959194509250565b60008060008060008060c08789031215612b9257600080fd5b8635612b9d81613137565b95506020870135612bad81613137565b94506040870135935060608701359250608087013567ffffffffffffffff80821115612bd857600080fd5b612be48a838b01612a9f565b935060a0890135915080821115612bfa57600080fd5b50612c0789828a01612a9f565b9150509295509295509295565b60008060408385031215612c2757600080fd5b8235612c3281613137565b946020939093013593505050565b600060208284031215612c5257600080fd5b8151801515811461296257600080fd5b600060208284031215612c7457600080fd5b5035919050565b600060208284031215612c8d57600080fd5b5051919050565b60038110612ccb577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8054600090600181811c9080831680612ce957607f831692505b6020808410821415612d24577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b83885260208801828015612d3f5760018114612d6e57612d99565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00871682528282019750612d99565b60008981526020902060005b87811015612d9357815484820152908601908401612d7a565b83019850505b5050505050505092915050565b60008251612db8818460208701612fc2565b9190910192915050565b7f50617274794269643a3a6269643a20706c61636520626964206661696c65643a81527f2000000000000000000000000000000000000000000000000000000000000000602082015260008251612e20816021850160208701612fc2565b9190910160210192915050565b602081016115d38284612c94565b60808101612e498287612c94565b84602083015283604083015282606083015295945050505050565b6020815260008251806020840152612e83816040850160208701612fc2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60e081526000612ec860e083018a612ccf565b8281036020840152612eda818a612ccf565b73ffffffffffffffffffffffffffffffffffffffff98909816604084015250506060810194909452608084019290925260a083015260c09091015292915050565b60008219821115612f2e57612f2e61307b565b500190565b600082612f69577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612fa657612fa661307b565b500290565b600082821015612fbd57612fbd61307b565b500390565b60005b83811015612fdd578181015183820152602001612fc5565b838111156117f55750506000910152565b600181811c9082168061300257607f821691505b6020821081141561303c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156130745761307461307b565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff811681146124a657600080fdfea2646970667358221220088fc7ed0c7815fd03a4ed3c69ca57727f774cbfeb2f1d9daf64d2acfdcd22f564736f6c63430008050033000000000000000000000000f7f52dd34bc21eda08c0b804c7c1dbc48375820f00000000000000000000000085aa7f78bdb2de8f3e0c0010d99ad5853ffcfc63000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100675760003560e01c80633fc8cef3116100505780633fc8cef3146100e3578063d7d4a9ce1461010a578063d7dfa0dd1461011d57600080fd5b80630b2030231461006c5780633c4d12d9146100bc575b600080fd5b6100937f00000000000000000000000085aa7f78bdb2de8f3e0c0010d99ad5853ffcfc6381565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100937f000000000000000000000000f7f52dd34bc21eda08c0b804c7c1dbc48375820f81565b6100937f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b610093610118366004610364565b610144565b6100937f00000000000000000000000018b9f4ad986a0e0777a2e1a652a4499c8ee3e07781565b600080878787878787604051602401610162969594939291906104df565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fe001ff5200000000000000000000000000000000000000000000000000000000179052519091507f00000000000000000000000018b9f4ad986a0e0777a2e1a652a4499c8ee3e07790829061020990610283565b610214929190610543565b604051809103906000f080158015610230573d6000803e3d6000fd5b5091507f050cc06436bbc2fe72596f120f90651e8b56b2c1fc7b8361f1b043ffc7c2594f823389898c8a8a8a604051610270989796959493929190610466565b60405180910390a1509695505050505050565b610357806105aa83390190565b803573ffffffffffffffffffffffffffffffffffffffff811681146102b457600080fd5b919050565b600082601f8301126102ca57600080fd5b813567ffffffffffffffff808211156102e5576102e561057a565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561032b5761032b61057a565b8160405283815286602085880101111561034457600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060008060008060c0878903121561037d57600080fd5b61038687610290565b955061039460208801610290565b94506040870135935060608701359250608087013567ffffffffffffffff808211156103bf57600080fd5b6103cb8a838b016102b9565b935060a08901359150808211156103e157600080fd5b506103ee89828a016102b9565b9150509295509295509295565b6000815180845260005b8181101561042157602081850181015186830182015201610405565b81811115610433576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061010073ffffffffffffffffffffffffffffffffffffffff808c168452808b166020850152808a1660408501528860608501528088166080850152508560a08401528060c08401526104bc818401866103fb565b905082810360e08401526104d081856103fb565b9b9a5050505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835280881660208401525085604083015284606083015260c0608083015261052460c08301856103fb565b82810360a084015261053681856103fb565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061057260408301846103fb565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfe60a060405234801561001057600080fd5b5060405161035738038061035783398101604081905261002f916100d7565b6001600160601b0319606083901b1660805260405160009081906001600160a01b0385169061005f9085906101a5565b600060405180830381855af49150503d806000811461009a576040519150601f19603f3d011682016040523d82523d6000602084013e61009f565b606091505b50915091508181906100cd5760405162461bcd60e51b81526004016100c491906101c1565b60405180910390fd5b505050505061023a565b600080604083850312156100ea57600080fd5b82516001600160a01b038116811461010157600080fd5b60208401519092506001600160401b038082111561011e57600080fd5b818501915085601f83011261013257600080fd5b81518181111561014457610144610224565b604051601f8201601f19908116603f0116810190838211818310171561016c5761016c610224565b8160405282815288602084870101111561018557600080fd5b6101968360208301602088016101f4565b80955050505050509250929050565b600082516101b78184602087016101f4565b9190910192915050565b60208152600082518060208401526101e08160408501602087016101f4565b601f01601f19169190910160400192915050565b60005b8381101561020f5781810151838201526020016101f7565b8381111561021e576000848401525b50505050565b634e487b7160e01b600052604160045260246000fd5b60805160601c60fc61025b60003960008181602a0152607b015260fc6000f3fe608060405260043610601f5760003560e01c8063d7dfa0dd14606b576025565b36602557005b6040517f00000000000000000000000000000000000000000000000000000000000000009036600082376000803683855af43d806000843e8180156067578184f35b8184fd5b348015607657600080fd5b50609d7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f3fea2646970667358221220a3350e7abb318cfd6c2f0227ef2ec856c01e215d98d5d2e5e2202e41a3c4deaf64736f6c63430008050033a26469706673582212201fb4517a171ffd9cd28a6aa477f0e14f12b32ddefa0ba2b007104ad486f33cf564736f6c63430008050033

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 Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.