ETH Price: $1,800.71 (+10.62%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
_Process ETH And...191705932024-02-06 17:10:59441 days ago1707239459IN
0xE86825bC...A7f95c22e
0 ETH0.0851634835.44730045
New Bid191705412024-02-06 17:00:23441 days ago1707238823IN
0xE86825bC...A7f95c22e
4 ETH0.0121245638.33346153
New Bid191705152024-02-06 16:55:11441 days ago1707238511IN
0xE86825bC...A7f95c22e
4.19999999 ETH0.0099890734.29971621
New Bid191705062024-02-06 16:53:23441 days ago1707238403IN
0xE86825bC...A7f95c22e
4.19999999 ETH0.010201536.59744569
New Bid191705042024-02-06 16:52:59441 days ago1707238379IN
0xE86825bC...A7f95c22e
4 ETH0.0105001737.4423386
New Bid191704872024-02-06 16:49:35441 days ago1707238175IN
0xE86825bC...A7f95c22e
4 ETH0.0095927336.78493589
New Bid191704812024-02-06 16:48:23441 days ago1707238103IN
0xE86825bC...A7f95c22e
4 ETH0.0118003642.97605118
New Bid191704472024-02-06 16:41:35441 days ago1707237695IN
0xE86825bC...A7f95c22e
4 ETH0.0173208855.79246385
New Bid191703712024-02-06 16:26:23441 days ago1707236783IN
0xE86825bC...A7f95c22e
4.1 ETH0.0162229359.455831
New Bid191697542024-02-06 14:21:35441 days ago1707229295IN
0xE86825bC...A7f95c22e
4 ETH0.0135594651.99600852
New Bid191683812024-02-06 9:42:23441 days ago1707212543IN
0xE86825bC...A7f95c22e
5.49999999 ETH0.0094790130.53058335
New Bid191646272024-02-05 21:06:35442 days ago1707167195IN
0xE86825bC...A7f95c22e
4.39999999 ETH0.0079514430.49114082
New Bid191645872024-02-05 20:58:35442 days ago1707166715IN
0xE86825bC...A7f95c22e
4.19999999 ETH0.0089027232.43344751
New Bid191643122024-02-05 20:02:59442 days ago1707163379IN
0xE86825bC...A7f95c22e
4.19999999 ETH0.009772531.47577151
New Bid191642932024-02-05 19:58:59442 days ago1707163139IN
0xE86825bC...A7f95c22e
4.29999999 ETH0.0043152116.54740127
New Bid191637922024-02-05 18:18:23442 days ago1707157103IN
0xE86825bC...A7f95c22e
4.19999999 ETH0.0057215720.051292
New Bid191634672024-02-05 17:11:47442 days ago1707153107IN
0xE86825bC...A7f95c22e
4 ETH0.0065047824.94366536
New Bid191634302024-02-05 17:04:23442 days ago1707152663IN
0xE86825bC...A7f95c22e
4.19999999 ETH0.0063012222.95378887
New Bid191634122024-02-05 17:00:47442 days ago1707152447IN
0xE86825bC...A7f95c22e
4.1 ETH0.005686624.52137628
_Change Discount...191591232024-02-05 2:32:23443 days ago1707100343IN
0xE86825bC...A7f95c22e
0 ETH0.0004722513.44886553
____Launchpad Ov...191590592024-02-05 2:19:23443 days ago1707099563IN
0xE86825bC...A7f95c22e
0 ETH0.00062813.46864268

Latest 16 internal transactions

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer191705932024-02-06 17:10:59441 days ago1707239459
0xE86825bC...A7f95c22e
67.6 ETH
Transfer191705932024-02-06 17:10:59441 days ago1707239459
0xE86825bC...A7f95c22e
0.2 ETH
Transfer191705932024-02-06 17:10:59441 days ago1707239459
0xE86825bC...A7f95c22e
0.59999999 ETH
Transfer191705932024-02-06 17:10:59441 days ago1707239459
0xE86825bC...A7f95c22e
0.59999999 ETH
Transfer191705932024-02-06 17:10:59441 days ago1707239459
0xE86825bC...A7f95c22e
0.4 ETH
Transfer191705932024-02-06 17:10:59441 days ago1707239459
0xE86825bC...A7f95c22e
0.4 ETH
Transfer191705932024-02-06 17:10:59441 days ago1707239459
0xE86825bC...A7f95c22e
0.2 ETH
Transfer191705932024-02-06 17:10:59441 days ago1707239459
0xE86825bC...A7f95c22e
0.5 ETH
Transfer191705932024-02-06 17:10:59441 days ago1707239459
0xE86825bC...A7f95c22e
1.69999999 ETH
Transfer191705932024-02-06 17:10:59441 days ago1707239459
0xE86825bC...A7f95c22e
0.39999999 ETH
Transfer191705932024-02-06 17:10:59441 days ago1707239459
0xE86825bC...A7f95c22e
0.59999999 ETH
Transfer191705932024-02-06 17:10:59441 days ago1707239459
0xE86825bC...A7f95c22e
0.39999999 ETH
Transfer191705932024-02-06 17:10:59441 days ago1707239459
0xE86825bC...A7f95c22e
0.29999999 ETH
Transfer191705932024-02-06 17:10:59441 days ago1707239459
0xE86825bC...A7f95c22e
0.59999999 ETH
Transfer191705932024-02-06 17:10:59441 days ago1707239459
0xE86825bC...A7f95c22e
0.59999999 ETH
Transfer191705932024-02-06 17:10:59441 days ago1707239459
0xE86825bC...A7f95c22e
0.5 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
EnglishMarketplace

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 10000 runs

Other Settings:
default evmVersion
File 1 of 5 : EnglishMarketplace.sol
//SPDX-License-Identifier: MIT
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                           @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@           @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@              @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@              @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@           @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                           @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/**
 * @title EnglishMarketplace
 * @author @brougkr
 * @notice A Smart Contract To Facilitate Ascending Rebate Auctions (With Ascending Rebate Reserve Floor) For Multiple NFTs (Or Whatever Else You Want To Sell) 
 */
pragma solidity 0.8.19;
import { MissionControl } from "./MissionControl.sol";
import { DelegateCashEnabled } from "./DelegateCashEnabled.sol";
import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import { MerkleProof } from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
contract EnglishMarketplace is MissionControl, DelegateCashEnabled, ReentrancyGuard
{
    struct Bid
    {
        uint _OGBidIndex; // [0] -> Original Bid Index
        uint _Priority;   // [1] -> Priority Of Bid (Merkle Rank)
        uint _Allocation; // [2] -> Allocation For Provided Priority Tier
        uint _ETHValue;   // [3] -> ETH Value Of Bid
        uint _Timestamp;  // [4] -> Unix Timestamp Of Bid Confirmation
        address _Bidder;  // [5] -> Wallet Address Of Bidder
        address _Vault;   // [6] -> Wallet Address Of Vault (optional `delegate.cash` support)
        bool _Rebated;    // [7] -> If Bidder Rebated ETH From Bid
        bool _Winner;     // [8] -> If Bidder Is A Winner (Top Placing) In The Auction
        bool _NFTSent;    // [9] -> If Bidder Has Received Their NFT
    }

    struct Params
    {
        string _Name;                // [0] -> Name Of Auction
        bool _SettlementEnabled;     // [1] -> If Rebate Last Price Is Enabled (Everyone Pays Lowest Leaderboard Price)
        bool _UserSettlementEnabled; // [2] -> If Self-Service User Settlement Is Enabled (Bidders Can Settle Their Own Bids ETH & NFTs)
        uint _LeaderboardSize;       // [3] -> The Bid Threshold For NewMinimumBid (eg. 50 Valid Bids)
        uint _UnixStartTime;         // [4] -> Unix Start Time Of Auction
        uint _UnixEndTime;           // [5] -> Unix End Time Of Auction
        uint _MinBIPSIncrease;       // [6] -> Minimum BIPS (%) Increase On Each Subsequent Bid After Configured LeaderboardSize 
        uint _SecondsExtension;      // [7] -> # Of Second(s) Of Extension For Auction (Input In Seconds)
        uint _SecondsThreshold;      // [8] -> # Of Seconds Within Auction End Time To Be Eligible For Auction Extension
        uint _InitialMinimumBid;     // [9] -> Initial Minimum Bid
        uint _ProjectIDMintPass;     // [10] -> The Factory MintPass ProjectID
        uint _MintPackAmount;        // [11] -> The Amount Of Mint Passes To Disperse Per Bid
        address _NFT;                // [12] -> Address Of NFT Contract
        address _Operator;           // [13] -> Wallet Holding NFTs To Disperse
    }

    struct State
    {
        bool _Active;           // [0] -> _Active
        bool _NFTsDispersed;    // [1] -> _NFTsDispersed
        uint _LastMinBid;       // [2] -> _LastMinBid
        uint _GlobalUniqueBids; // [3] -> _GlobalUniqueBids
    }

    struct AllAuctionParams
    {
        string _Name;            // [0] -> Name Of Auction
        bool _Active;            // [1] -> If Sale Is Active
        bool _NFTsDispersed;     // [2] -> If NFTs Have Been Dispersed
        bool _SettlementEnabled; // [3] -> If Rebate Last Price Is Enabled (Everyone Pays Lowest Leaderboard Price)
        uint _LeaderboardSize;   // [4] -> The Bid Threshold For NewMinimumBid (eg. 50 Valid Bids)
        uint _UnixStartTime;     // [5] -> Unix Start Time Of Auction
        uint _UnixEndTime;       // [6] -> Unix End Time Of Auction
        uint _MinBIPSIncrease;   // [7] -> Minimum BIPS (%) Increase On Each Subsequent Bid After 50 Unique Bids 
        uint _SecondsExtension;  // [8] -> # Of Seconds(s) Of Extension For Auction (Input In # Of Seconds)
        uint _SecondsThreshold;  // [9] -> # Of Seconds Within Auction End Time To Be Eligible For Auction Extension
        uint _LastMinBid;        // [10] -> Value Of The Last Minimum Bid
        uint _GlobalUniqueBids;  // [11] -> # Of Global Unique Bids
        uint _ProjectIDMintPass; // [12] -> The Factory MintPass ProjectID
        uint _MintPackAmount;    // [13] -> The Amount Of Mint Passes To Disperse Per Bid
        address _NFT;            // [14] -> Address Of NFT Contract
    }

    /*-----------
     * MAPPINGS *
    ------------*/

    mapping(uint=>Params) public AuctionParams;                                         // [SaleIndex] => Auction Params
    mapping(uint=>State) public SaleState;                                              // [SaleIndex] => Sale State
    mapping(uint=>mapping(uint=>Bid)) public Bids;                                      // [SaleIndex][BidIndex] => Bid
    mapping(uint=>mapping(uint=>uint)) public Leaderboard;                              // [SaleIndex][LeaderboardIndex] => BidIndex
    mapping(uint=>mapping(address=>uint[])) public UserBidIndexes;                      // [SaleIndex][Wallet] => BidIndexes
    mapping(uint=>mapping(uint=>bool)) public NFTTokenIDHasBeenSent;                    // [SaleIndex][TokenID] => HasBeenSent
    mapping(uint=>uint[]) public Discounts;                                             // [SaleIndex] => Discount Amounts
    mapping(uint=>bytes32[]) public MerkleRootsEligibility;                             // [SaleIndex] => Merkle Roots For Priority Eligibility
    mapping(uint=>bytes32[]) public MerkleRootsAmounts;                                 // [SaleIndex] => Merkle Roots For Priority Allocation
    mapping(uint=>mapping(address=>mapping(uint=>uint))) public PriorityPurchaseAmount; // [SaleIndex][Wallet][Priority] => Purchased Amount For Priority Level

    /*------------------
     * STATE VARIABLES *
    -------------------*/

    address private constant _BRT_MULTISIG = 0x0BC56e3c1397e4570069e89C07936A5c6020e3BE; // `sales.brightmoments.eth`
    uint public _GLOBAL_UNIQUE_SALES = 1;                                                    // Global Unique Sales

    /*---------
     * EVENTS *
    ----------*/

    /**
     * @dev Emitted When A New Bid Is Submitted
     */
    event NewBidComplete(uint SaleIndex, uint BidIndex, address Bidder, uint MessageValue, uint Unixtimestamp, address Vault);

    /**
     * @dev Emitted When A Bid Is Topped Up
     */
    event BidToppedUp(uint SaleIndex, uint BidIndex, uint ETHForBid, uint Unixtimestamp, address Bidder);

    /**
     * @dev Emitted When A Bid Reclaim Fails
     */
    event BidReclaimFailed(uint BidIndex);

    /**
     * @dev Emitted When A Bid Reclaim Succeeds
     */
    event BidReclaimSuccess(uint BidIndex);

    /**
     * @dev Emitted When A Bidder's ETH Is Rebated (The Bid They Are Trying To Top Up Was Frontran)
     */
    event BidTopupRefunded(uint Rebate);

    /**
     * @dev Emitted When The Auction End Time Is Extended
     */
    event AuctionExtended();

    /**
     * @dev Emitted When A Bid Is Refunded (Kicked Back To Losing Bidder)
     */
    event BidRefunded(uint BidIndex);

    /**
     * @dev Emitted When A Sale Is Started
     */
    event SaleStarted(uint SaleIndex);

    constructor() 
    { 
        _OWNER = msg.sender;
        SaleState[0]._Active = true; // activates auction
        SaleState[0]._LastMinBid = 4 ether; // starts auction specified ETH value
        AuctionParams[0]._Name = 'Paris Golden Pack'; // sets auction name
        AuctionParams[0]._SettlementEnabled = true; // enables rebate last price
        AuctionParams[0]._LeaderboardSize = 20; // (max # of bids on leaderboard)
        AuctionParams[0]._UnixStartTime = 1707152400; // sets auction start time
        AuctionParams[0]._UnixEndTime = AuctionParams[0]._UnixStartTime + 86400 seconds; // sets auction end time 1 day after start
        AuctionParams[0]._MinBIPSIncrease = 110; // The Increase On Each Subsequent Bid After 50 Unique Bids
        AuctionParams[0]._SecondsExtension = 600 seconds; // # Of Seconds Of Extension
        AuctionParams[0]._SecondsThreshold = 600 seconds; // # Of Seconds Within Auction End Time Where Auction Extension Is Enabled
        AuctionParams[0]._InitialMinimumBid = 4 ether; // sets initial minimum bid
        AuctionParams[0]._MintPackAmount = 19; // sets mint pass transfer amount
        AuctionParams[0]._NFT = 0xb642F85D2B23b16aC310cC0D462716d80608B25C; // NFT Contract Address 
        MerkleRootsEligibility[0].push(0x9d68dac65c6a727c9df669d2cdd4f0aba1686eaa708148cb03e3a590ad1622e7); // Merkle Root Priority Eligibility Full Set
        MerkleRootsEligibility[0].push(0x6e03f1a95ca9713b999315f45ebd86a518ac26e25a8ce4faed4f36a05d3a23da); // Merkle Root Priority Eligibility Citizen
        MerkleRootsAmounts[0].push(0x75ffaea20827ac2efdbb92096c519fc34f1ea2c377f9736b46905db7405e3207); // Merkle Root Priority Allocation Full Set
        MerkleRootsAmounts[0].push(0xd4a4248680d3ed1008af3ffe64a6dce5907ae2b6c27df6f700864078a1db99ad); // Merkle Root Priority Allocation Citizen
        Discounts[0].push(90); // 10% Discount
        Discounts[0].push(95); // 5% Discount
    }

    /*-----------------
     * USER FUNCTIONS *
    ------------------*/
    
    /**
     * @dev Submits A New Bid To The Auction
     * @param SaleIndex The Sale Index To Target
     * @param MaxAmount The Maximum Merkle Priority Allocation Amount | note: Input 0 If Not Applicable
     * @param Vault Optional delegate.xyz Integration | note: Input 0x0000000000000000000000000000000000000000 If No Delegate
     * @param ProofEligibility The Merkle Proof For The Bidder's Priority | note: Input [0x0000000000000000000000000000000000000000000000000000000000000000] If No Merkle Proof
     * @param ProofAmount The Merkle Proof For The Bidder's Priority Allocation | note: Input [0x0000000000000000000000000000000000000000000000000000000000000000] If No Merkle Proof
     */
    function NewBid ( uint SaleIndex, uint MaxAmount, address Vault, bytes32[] calldata ProofEligibility, bytes32[] calldata ProofAmount ) external payable nonReentrant
    {
        require(tx.origin == msg.sender, "Auction: EOA Only, Use `delegate.cash` For Wallet Delegation"); // Requires `msg.sender` Is A Valid EOA
        require(SaleState[SaleIndex]._Active, "Auction: Auction Is Not Active"); // Requires The Auction Is Active
        require(block.timestamp >= AuctionParams[SaleIndex]._UnixStartTime, "Auction: Auction Has Not Started"); // Requires The Auction Has Started
        require(block.timestamp < AuctionParams[SaleIndex]._UnixEndTime, "Auction: Auction Has Concluded"); // Requires The Auction Has Not Ended
        address Recipient = msg.sender;
        if(Vault != address(0)) { if(DelegateCash.checkDelegateForAll(msg.sender, Vault)) { Recipient = Vault; } } // `delegate.cash` Integration
        __FinalizeNewBid(SaleIndex, msg.value); // Auto-Calculates The Required Reserve Price For The Bid
        __CheckAndSeedAuctionEndTime(SaleIndex); // Checks If Auction End Time Should Be Extended And Extends If Necessary
        uint Priority = _ValidateMerkleProofs(SaleIndex, MaxAmount, Recipient, ProofEligibility, ProofAmount); // Validates Merkle Proof And Returns Merkle Priority
        uint CurrentBidIndex = SaleState[SaleIndex]._GlobalUniqueBids; // Current Bid Index
        Bids[SaleIndex][CurrentBidIndex] = Bid (
            CurrentBidIndex, // [0] -> Original Bid Index
            Priority,        // [1] -> Priority Of Bid (Merkle Rank)
            MaxAmount,       // [2] -> Allocation For Provided Priority Tier
            msg.value,       // [3] -> ETH Value Of Bid
            block.timestamp, // [4] -> Unix Timestamp Of Bid Confirmation
            msg.sender,      // [5] -> Wallet Address Of Bidder
            Recipient,       // [6] -> Wallet Address Of Vault (optional `delegate.cash` support)
            false,           // [7] -> If Bidder Rebated ETH From Bid
            false,           // [8] -> If Bidder Is A Winner (Top Placing) In The Auction
            false            // [9] -> If Bidder Has Received Their NFT
        ); // Registers New Bid
        UserBidIndexes[SaleIndex][msg.sender].push(CurrentBidIndex); // Appends Bid Index To User's Bid Indexes
        SaleState[SaleIndex]._GlobalUniqueBids = CurrentBidIndex + 1; // Increments Global Unique Bids
        emit NewBidComplete(SaleIndex, CurrentBidIndex, msg.sender, msg.value, block.timestamp, Recipient); // Emits Bid Event
    }

    /**
     * @dev Tops Up Bid(s) With Additional ETH
     * @param SaleIndex The Sale Index To Target
     * @param BidIndexes[] The Bid Indexes To Top Up
     * @param Amounts[] The Amounts (In WEI) To Top Up The Corresponding Bid Indexes By
     */
    function IncreaseBid ( uint SaleIndex, uint[] calldata BidIndexes, uint[] calldata Amounts ) external payable nonReentrant
    {
        require(tx.origin == msg.sender, "Auction: EOA Only, Use `delegate.cash` For Wallet Delegation"); // Requires `msg.sender` Is A Valid EOA
        require(SaleState[SaleIndex]._Active, "Auction: Auction Is Not Active"); // Requires The Auction Is Active
        require(block.timestamp >= AuctionParams[SaleIndex]._UnixStartTime, "Auction: Auction Has Not Started"); // Requires The Auction Has Started
        require(block.timestamp < AuctionParams[SaleIndex]._UnixEndTime, "Auction: Auction Has Concluded"); // Requires The Auction Has Not Ended
        require(BidIndexes.length == Amounts.length, "Auction: BidIndexes And Amounts Array Length Mismatch"); // Requires BidIndexes And Amounts Length Match
        require(BidIndexes.length > 0, "Auction: User Has Input No Bids To Top Up"); // Requires User Has Bids To Top Up
        if(!AuctionParams[SaleIndex]._SettlementEnabled) { __CheckAndSeedAuctionEndTime(SaleIndex); } // Checks If Auction End Time Should Be Extended And Extends If Necessary
        Bid memory _Bid;
        uint Total;
        uint BidValue;
        for(uint x; x < BidIndexes.length; x++)
        { 
            _Bid = Bids[SaleIndex][BidIndexes[x]];
            BidValue = _Bid._ETHValue;
            if(!_Bid._Rebated && !_Bid._Winner)
            {
                require(msg.sender == _Bid._Bidder, "Auction: `msg.sender` Is Not The Bidder Of Desired Bid Index");
                require(BidValue + Amounts[x] >= (BidValue * AuctionParams[SaleIndex]._MinBIPSIncrease) / 100, "Auction: Bid Amount Topup Requires >= 5% Increase");
                Bids[SaleIndex][BidIndexes[x]]._ETHValue += Amounts[x];
                Bids[SaleIndex][BidIndexes[x]]._Timestamp = block.timestamp;
                Total += Amounts[x];
                emit BidToppedUp(SaleIndex, BidIndexes[x], Amounts[x], block.timestamp, msg.sender);
            }
        }
        require(msg.value >= Total, "Auction: Invalid ETH Values");
        uint Rebate = msg.value - Total; // Rebates Excess ETH (If Total > msg.value This Will Revert)
        if(Rebate > 0)
        {
            (bool Success, ) = msg.sender.call { value: Rebate }("");
            require(Success, "Auction: Failed To Rebate Excess ETH To Bidder, Resubmit Transaction");
            emit BidTopupRefunded(Rebate);
        }
    }

    /**
     * @dev Rebates ETH From Bid(s) If Bidder Is Not A Winner & Disperses NFTs If Winner
     * @param SaleIndex The Sale Index To Finalize
     */
    function UserSettleAuction ( uint SaleIndex ) external nonReentrant
    {
        require(tx.origin == msg.sender, "Auction: EOA Only, Use `delegate.cash` For Wallet Delegation"); // Requires `msg.sender` Is A Valid EOA
        require(!SaleState[SaleIndex]._NFTsDispersed, "Auction: NFTs Have Been Dispersed");
        require(AuctionParams[SaleIndex]._UserSettlementEnabled, "Auction: User Settlement Is Not Enabled");
        require(UserBidIndexes[SaleIndex][msg.sender].length > 0, "Auction: User Has No Bids To Settle");
        require(block.timestamp > AuctionParams[SaleIndex]._UnixEndTime, "Auction: Cannot Finalize, Auction Is Still Active");
        address Bidder = msg.sender;
        __UserDisperseETH(SaleIndex, Bidder);
        __UserDisperseNFT(SaleIndex, Bidder);
    }

    /*------------------
     * ADMIN FUNCTIONS *
    -------------------*/

    /**
     * @dev Starts Auction
     * @param AuctionInfo The Struct Of Auction Info 
     * @param RootsEligibility The Merkle Roots For Priority Eligibility
     * @param RootsAmounts The Merkle Roots For Priority Allocation 
     * @param DiscountAmounts The Discount Amounts For The Auction ([80,90,95] = 20% Discount, 10% Discount, 5% Discount)
     */
    function _StartAuction (
        Params memory AuctionInfo, 
        bytes32[] calldata RootsEligibility, 
        bytes32[] calldata RootsAmounts,
        uint[] calldata DiscountAmounts
    ) external onlyOperator returns ( uint SaleIndex ) { 
        // require(AuctionInfo._UnixStartTime >= block.timestamp, "Auction: Start Time Must Be In The Future");
        require(RootsEligibility.length == RootsAmounts.length && RootsAmounts.length == DiscountAmounts.length, "Auction: Array Lengths Must Match");
        require(AuctionInfo._MinBIPSIncrease >= 100, "Auction: Minimum BIPS Increase Must Be >= 100");
        SaleIndex = _GLOBAL_UNIQUE_SALES;
        AuctionParams[SaleIndex] = AuctionInfo; 
        SaleState[SaleIndex]._LastMinBid = AuctionParams[SaleIndex]._InitialMinimumBid;
        SaleState[SaleIndex]._Active = true;
        Discounts[SaleIndex] = DiscountAmounts;
        MerkleRootsEligibility[SaleIndex] = RootsEligibility;
        MerkleRootsAmounts[SaleIndex] = RootsAmounts;
        _GLOBAL_UNIQUE_SALES = SaleIndex + 1;
        for(uint x; x < DiscountAmounts.length; x++) { require(DiscountAmounts[x] <= 100 && DiscountAmounts[x] > 0, "Invalid Discount Amounts"); }
        emit SaleStarted(SaleIndex);
        return SaleIndex;
    }

    /**
     * @dev Changes The Sale Roots
     * @param SaleIndex The Sale Index To Change
     * @param RootsEligibility The New Merkle Roots For Priority Eligibility
     * @param RootsAmounts The New Merkle Roots For Max Priority Allocation
     */
    function _ChangeRoots(uint SaleIndex, bytes32[] calldata RootsEligibility, bytes32[] calldata RootsAmounts) external onlyOperator 
    { 
        MerkleRootsEligibility[SaleIndex] = RootsEligibility; 
        MerkleRootsAmounts[SaleIndex] = RootsAmounts;
    }

    /**
     * @dev Changes The Sale Discounts
     * @param SaleIndex The Sale Index To Change
     * @param NewDiscountAmounts The New Discount Amounts To Change
     * note: True Discount Amount = 100 - DiscountAmounts[x] eg. (DiscountAmounts[80,90,95] = 20% Discount, 10% Discount, 5% Discount)
     */
    function _ChangeDiscountAmounts(uint SaleIndex, uint[] calldata NewDiscountAmounts) external onlyOperator 
    { 
        for(uint x; x < NewDiscountAmounts.length; x++) { require(NewDiscountAmounts[x] <= 100 && NewDiscountAmounts[x] > 0, "Invalid Discount Amounts"); }
        Discounts[SaleIndex] = NewDiscountAmounts; 
    }

    /**
     * @dev Changes The Mint Pack Amount
     */
    function _ChangeMintPackAmount(uint SaleIndex, uint NewAmount) external onlyOperator { AuctionParams[SaleIndex]._MintPackAmount = NewAmount; }

    /**
     * @dev Changes The MintPass ProjectID
     * @param SaleIndex The Sale Index To Change
     * @param MintPassProjectID The New MintPass ProjectID To Change
     */
    function _ChangeMintPassProjectID(uint SaleIndex, uint MintPassProjectID) external onlyOperator { AuctionParams[SaleIndex]._ProjectIDMintPass = MintPassProjectID;}

    /**
     * @dev Changes The Auction Global Pause State At `SaleIndex`
     * @param SaleIndex The Sale Index To Change
     */
    function _ChangeActiveState(uint SaleIndex) external onlyOperator { SaleState[SaleIndex]._Active = !SaleState[SaleIndex]._Active; }

    /**
     * @dev Changes Min Bid
     * @param SaleIndex The Sale Index To Change
     * @param NewMinBid The New Minimum Bid 
     */
    function _ChangeMinBid(uint SaleIndex, uint NewMinBid) external onlyOperator { SaleState[SaleIndex]._LastMinBid = NewMinBid; }
    
    /**
     * @dev Changes If The Lowest Valid Leaderboard Bid Is What Everyone Pays
     * @param SaleIndex The Sale Index To Change
     * @param NewState The New State (Boolean) (True = Everyone Pays Lowest Leaderboard Bid, False = Everyone Pays Their Bid ETH Value) 
     */
    function _ChangeSettlementEnabled(uint SaleIndex, bool NewState) external onlyOperator { AuctionParams[SaleIndex]._SettlementEnabled = NewState; }
    
    /**
     * @dev Changes The Bid Threshold (Controls The Leaderboard Size)
     * @param SaleIndex The Sale Index To Change
     * @param NewLeaderboardSize The New Leaderboard Size
     */
    function _ChangeLeaderboardSize(uint SaleIndex, uint NewLeaderboardSize) external onlyOperator { AuctionParams[SaleIndex]._LeaderboardSize = NewLeaderboardSize; }

    /**
     * @dev Changes The Unix Start Time
     * @param SaleIndex The Sale Index To Change
     * @param NewUnixStartTime The New Unix Start Time
     */
    function _ChangeUnixStartTime(uint SaleIndex, uint NewUnixStartTime) external onlyOperator { AuctionParams[SaleIndex]._UnixStartTime = NewUnixStartTime; }

    /**
     * @dev Changes The Unix End Time
     * @param SaleIndex The Sale Index To Change
     * @param NewUnixEndTime The New Unix End Time
     */
    function _ChangeUnixEndTime(uint SaleIndex, uint NewUnixEndTime) external onlyOperator { AuctionParams[SaleIndex]._UnixEndTime = NewUnixEndTime; }

    /**
     * @dev Changes The Minimum BIPs Increase
     * @param SaleIndex The Sale Index To Change
     * @param NewMinBIPSIncrease The New Minimum BIPs Increase (In BIPS) (105 = 5% Increase, 150 = 50% Increase etc...)
     */
    function _ChangeMinBIPSIncrease(uint SaleIndex, uint NewMinBIPSIncrease) external onlyOperator 
    { 
        require(NewMinBIPSIncrease >= 100, "Auction: Minimum BIPS Increase Must Be >= 100");
        AuctionParams[SaleIndex]._MinBIPSIncrease = NewMinBIPSIncrease; 
    }

    /**
     * @dev Changes The # Of Seconds The Auction Is Extended By If Auction End Time Is Within `AuctionParams[SaleIndex]._SecondsThreshold`
     * @param SaleIndex The Sale Index To Change
     * @param Seconds The New # Of Seconds To Extend Auction By
     */
    function _ChangeSecondsExtension(uint SaleIndex, uint Seconds) external onlyOperator { AuctionParams[SaleIndex]._SecondsExtension = Seconds; }

    /**
     * @dev Changes The # Of Seconsd Within Auction End Time To Be Eligible For Auction Extension
     * @param SaleIndex The Sale Index To Change
     * @param Seconds The New # Of Seconds Within Auction End Time To Be Eligible For Auction Extension
     */
    function _ChangeSecondsThreshold(uint SaleIndex, uint Seconds) external onlyOperator { AuctionParams[SaleIndex]._SecondsThreshold = Seconds; }

    /**
     * @dev Changes The Current NFT Address
     * @param SaleIndex The Sale Index To Change
     * @param NewAddress The New NFT Address
     */
    function _ChangeNFTAddress(uint SaleIndex, address NewAddress) external onlyOperator { AuctionParams[SaleIndex]._NFT = NewAddress; }

    /**
     * @dev Changes The Current Operator Address (Address That Holds NFTs To Disperse)
     * @param SaleIndex The Sale Index To Change
     * @param Operator The New Operator Address (Address Holding NFTs To Disperse)
     */
    function _ChangeOperator(uint SaleIndex, address Operator) external onlyOperator { AuctionParams[SaleIndex]._Operator = Operator; }

    /**
     * @dev Rebate All Discounts For Leaderboard Bids & Sends Remaining ETH To Multisig
     * @param SaleIndex The Sale Index To Trigger Disbursement
     */
    function _InitiateRebateAndProceeds(uint SaleIndex) external onlyOperator 
    { 
        SaleState[SaleIndex]._Active = false; // Ends Auction
        __AdminInitiateProceeds(SaleIndex); // Initiates Admin Withdraw Of Proceeds (MUST BE CALLED FIRST)
    }

    /**
     * @dev Initiates Withdrawl Proceeds & Disperses NFTs To The Top Bidders On The Leaderboard (First-Come-First-Serve) (When TokenID Is Ambiguous)
     * @param SaleIndex The Sale Index To Trigger Disbursement
     */
    function _ProcessETHAndNFTsTokenIDsAmbiguous(uint SaleIndex) external onlyOperator
    {
        SaleState[SaleIndex]._Active = false;     // Ends Auction
        __AdminInitiateProceeds(SaleIndex);       // Initiates Admin Withdraw Of Proceeds (MUST BE CALLED FIRST)
        __DisperseNFTsByFCFSAmbiguous(SaleIndex); // Initiates Admin Disperse Of NFTs (MUST BE CALLED LAST)
    }

    /**
     * @dev Initiates Withdrawl Proceeds & Disperses NFTs To The Top Bidders On The Leaderboard (Ascending Ranking) (When TokenID Matters)
     * @param SaleIndex The Sale Index To Trigger Disbursement
     */
    function _ProcessETHAndNFTsTokenIDsDistinct(uint SaleIndex) external onlyOperator
    {
        SaleState[SaleIndex]._Active = false;     // Ends Auction
        __AdminInitiateProceeds(SaleIndex);       // Initiates Admin Withdraw Of Proceeds (MUST BE CALLED FIRST)
        __DisperseNFTsByAscendingRank(SaleIndex); // Initiates Admin Disperse Of NFTs (MUST BE CALLED LAST)
    }

    /**
     * @dev Initiates Withdrawl Proceeds & Disperses NFTs To The Top Bidders On The Leaderboard With Specific TokenIDs (Ascending Ranking)
     * @param SaleIndex The Sale Index To Trigger Disbursement
     * @param TokenIDs The TokenIDs To Disperse
     */
    function _ProcessETHAndNFTsTokenIDsSpecificRanked(uint SaleIndex, uint[] calldata TokenIDs) external onlyOperator
    {
        SaleState[SaleIndex]._Active = false;                         // Ends Auction
        __AdminInitiateProceeds(SaleIndex);                           // Initiates Admin Withdraw Of Proceeds (MUST BE CALLED FIRST)
        __DisperseNFTsByUniqueTokenIDsAscending(SaleIndex, TokenIDs); // Initiates Admin Disperse Of NFTs (MUST BE CALLED LAST)
    }

    /**
     * @dev Initiates Withdrawl Proceeds & Disperses NFTs To The Top Bidders On The Leaderboard With Mint Pack Amounts (Ascending Ranking)
     * @param SaleIndex The Sale Index To Trigger Disbursement
     */
    function _ProcessETHAndNFTsMintPacksRanked(uint SaleIndex) external onlyOperator
    {
        SaleState[SaleIndex]._Active = false; // Ends Auction
        __AdminInitiateProceeds(SaleIndex);   // Initiates Admin Withdraw Of Proceeds (MUST BE CALLED FIRST)
        __DisperseNFTsMintPacks(SaleIndex);   // Initiates Admin Disperse Of NFTs (MUST BE CALLED LAST)
    }

    /*------------------
     * ADMIN FUNCTIONS *
    -------------------*/

    /**
     * @dev Withdraws Ether From Contract To Address With An Amount
     * @notice This Is A Safety Function To Prevent Ether Locking, Only Use In An Emergency
     */
    function __WithdrawETHToMultisig() external onlyAdmin
    {
        (bool Success, ) = _BRT_MULTISIG.call{value: address(this).balance}("");
        require(Success, "Unable to Withdraw, Recipient May Have Reverted");
    }

    /*------------------
     * OWNER FUNCTIONS *
    -------------------*/

    /**
     * @dev Initiates Withdrawl Proceeds
     */
    function ___WithdrawETH() external onlyOwner
    {
        (bool Success, ) = msg.sender.call{value: address(this).balance}("");
        require(Success, "Unable to Withdraw, Recipient May Have Reverted");
    }

    /*---------------------
     * INTERNAL FUNCTIONS *
    ----------------------*/

    /**
     * @dev Calculates The Minimum Valid Bid And Seeds The Leaderboard
     * @param SaleIndex The Sale Index To Calculate The Minimum Valid Bid For
     * @param MsgValue The Message Value (In WEI) To Calculate The Minimum Valid Bid For
     */
    function __FinalizeNewBid(uint SaleIndex, uint MsgValue) internal
    {
        (uint MinBid, uint LeaderboardIndex) = _ViewMinimumValidBidAndIndex(SaleIndex);
        require(MsgValue >= MinBid, "Auction: Bid Amount Must Be >= Current Leaderboard Floor * 1.05"); // Requires Min Bid
        bool Valid = (SaleState[SaleIndex]._GlobalUniqueBids >= AuctionParams[SaleIndex]._LeaderboardSize);
        if(Valid) 
        { 
            __KickbackETH(SaleIndex, LeaderboardIndex); // Rebate ETH To Previous Bidder
            SaleState[SaleIndex]._LastMinBid = MinBid; // Stores Minimum Bid
        }
        Leaderboard[SaleIndex][LeaderboardIndex] = SaleState[SaleIndex]._GlobalUniqueBids; // Kicks Old Bid Index Out Of Leaderboard
    }

    /**
     * @dev Kicks Losing Bidder's ETH Back To Them
     * @param SaleIndex The Sale Index To Trigger Disbursement
     * @param LeaderboardIndex The Leaderboard Index To Kickback ETH To
     */
    function __KickbackETH(uint SaleIndex, uint LeaderboardIndex) internal 
    {
        if(!Bids[SaleIndex][Leaderboard[SaleIndex][LeaderboardIndex]]._Rebated)
        {
            Bids[SaleIndex][Leaderboard[SaleIndex][LeaderboardIndex]]._Rebated = true;
            (bool Success,) = Bids[SaleIndex][Leaderboard[SaleIndex][LeaderboardIndex]]._Bidder.call 
            { value: Bids[SaleIndex][Leaderboard[SaleIndex][LeaderboardIndex]]._ETHValue }("");
            require(Success, "Auction: Kickback Failed");
            emit BidRefunded(Bids[SaleIndex][Leaderboard[SaleIndex][LeaderboardIndex]]._OGBidIndex);
        } 
    }

    /**
     * @dev Finalizes ETH From User's Pending Bid(s)
     * @param SaleIndex The Sale Index To Trigger Disbursement
     * @param Bidder The Bidder To Disperse ETH To
     */
    function __UserDisperseETH(uint SaleIndex, address Bidder) internal
    {
        uint[] memory _UserBidIndexes = UserBidIndexes[SaleIndex][Bidder];
        uint LLB = _ViewLowestLeaderboardBid(SaleIndex);
        uint TotalRebate;
        uint TotalPaid;
        uint CurrentRebate;
        uint CurrentPaid;
        uint Discount;
        for(uint x; x < UserBidIndexes[SaleIndex][Bidder].length; x++) 
        { 
            if (
                !Bids[SaleIndex][_UserBidIndexes[x]]._Winner // Bid Is Not Winner
                && 
                !Bids[SaleIndex][_UserBidIndexes[x]]._Rebated // Bid Has Not Been Rebated
                && 
                Bids[SaleIndex][_UserBidIndexes[x]]._ETHValue >= LLB // Bid Is Valid ETH Value
            )
            {
                Bids[SaleIndex][UserBidIndexes[SaleIndex][Bidder][x]]._Winner = true; 
                Bids[SaleIndex][_UserBidIndexes[x]]._Rebated = true;
                if(Bids[SaleIndex][_UserBidIndexes[x]]._Priority == 69420) { Discount = 100; }
                else { Discount = Discounts[SaleIndex][Bids[SaleIndex][_UserBidIndexes[x]]._Priority]; }    
                if(AuctionParams[SaleIndex]._SettlementEnabled)
                {
                    CurrentRebate = Bids[SaleIndex][_UserBidIndexes[x]]._ETHValue - ((LLB * Discount) / 100);
                    CurrentPaid = Bids[SaleIndex][_UserBidIndexes[x]]._ETHValue - CurrentRebate;
                    TotalRebate += CurrentRebate;
                }
                else { CurrentPaid = Bids[SaleIndex][_UserBidIndexes[x]]._ETHValue; }
                TotalPaid += (CurrentPaid * Discount) / 100;
            }
        }
        (bool MultisigWithdraw, ) = _BRT_MULTISIG.call { value: TotalPaid }("");
        require(MultisigWithdraw, "Auction: Multisig Withdraw Failed");
        if(TotalRebate > 0)
        {
            (bool UserWithdraw, ) = Bidder.call { value: TotalRebate }("");
            require(UserWithdraw, "Auction: User Withdraw Failed");
        }
    }

    /**
     * @dev Disperses NFTs
     * @param SaleIndex The Sale Index To Trigger Disbursement
     * @param Bidder The Bidder To Disperse NFTs To
     */
    function __UserDisperseNFT(uint SaleIndex, address Bidder) internal
    {
        IERC721 _NFT = IERC721(AuctionParams[SaleIndex]._NFT);
        for(uint x; x < UserBidIndexes[SaleIndex][Bidder].length; x++) 
        { 
            if(
                Bids[SaleIndex][UserBidIndexes[SaleIndex][Bidder][x]]._Winner 
                && 
                !Bids[SaleIndex][UserBidIndexes[SaleIndex][Bidder][x]]._NFTSent
            )
            {
                Bids[SaleIndex][UserBidIndexes[SaleIndex][Bidder][x]]._NFTSent = true;
                _NFT._MintToFactory(Bidder, 1); 
            }
        }
    }

    /**
     * @dev Initiates Proceeds From The Leaderboard
     * @param SaleIndex The Sale Index To Trigger Disbursement
     */
    function __AdminInitiateProceeds(uint SaleIndex) internal
    {
        if(AuctionParams[SaleIndex]._LeaderboardSize > SaleState[SaleIndex]._GlobalUniqueBids) 
        { 
            AuctionParams[SaleIndex]._LeaderboardSize = SaleState[SaleIndex]._GlobalUniqueBids; // If Sale Did Not Sell Out, Sets Leaderboard Size To # Of Bids
        } 
        uint TotalProceeds;
        uint LLB = _ViewLowestLeaderboardBid(SaleIndex);
        uint RebateAmount;
        uint Discount;
        uint Priority;
        uint ETHValue;
        for(uint x; x < AuctionParams[SaleIndex]._LeaderboardSize; x++)
        {
            if (
                !Bids[SaleIndex][Leaderboard[SaleIndex][x]]._Rebated 
                && 
                !Bids[SaleIndex][Leaderboard[SaleIndex][x]]._Winner 
                && 
                Bids[SaleIndex][Leaderboard[SaleIndex][x]]._ETHValue >= LLB
            ) {
                Bids[SaleIndex][Leaderboard[SaleIndex][x]]._Winner = true;
                Bids[SaleIndex][Leaderboard[SaleIndex][x]]._Rebated = true;
                Priority = Bids[SaleIndex][Leaderboard[SaleIndex][x]]._Priority;
                ETHValue = Bids[SaleIndex][Leaderboard[SaleIndex][x]]._ETHValue;
                if(Priority == 69420) { Discount = 100; } // No Merkle Priority
                else { Discount = Discounts[SaleIndex][Priority]; } // Merkle Priority
                if(AuctionParams[SaleIndex]._SettlementEnabled) { RebateAmount = ETHValue - ((LLB * Discount) / 100); }
                else { RebateAmount = ETHValue - ((ETHValue * Discount) / 100); }
                if(RebateAmount > 0)
                {
                    (bool Rebate, ) = Bids[SaleIndex][Leaderboard[SaleIndex][x]]._Bidder.call { value: RebateAmount }("");                    
                    require(Rebate, "Auction: Failed To Rebate ETH To Bidder, Use Failsafe Withdraw");
                }
                TotalProceeds += (ETHValue - RebateAmount);
            }
        }
        (bool MultisigWithdraw, ) = _BRT_MULTISIG.call { value: TotalProceeds }("");
        require(MultisigWithdraw, "Auction: Admin Failed To Withdraw ETH To Multisig, Use Failsafe Withdraw");
    }

    /**
     * @dev Validates The Auction End Time & Extends If Necessary
     * @param SaleIndex The Sale Index To Check
     */
    function __CheckAndSeedAuctionEndTime(uint SaleIndex) internal 
    {
        // Extends Auction If Rebate Last Price (Settlement Price) Is Not Enabled (For Sales Where Leaderboard Placement Matters)
        if((AuctionParams[SaleIndex]._UnixEndTime - block.timestamp) < AuctionParams[SaleIndex]._SecondsThreshold) // If Bid Placed In Last 5 Minutes
        { 
            AuctionParams[SaleIndex]._UnixEndTime = block.timestamp + AuctionParams[SaleIndex]._SecondsExtension; // Extends Auction By The # Of Configured Seconds 
            emit AuctionExtended();
        }
    }

    /**
     * @dev Disperses NFTs With Unique TokenIDs
     * @param SaleIndex The Sale Index To Trigger Disbursement
     * @param TokenIDs Array Of TokenIDs To Be Dispersed
     */
    function __DisperseNFTsByUniqueTokenIDsAscending(uint SaleIndex, uint[] calldata TokenIDs) internal
    {
        require(!SaleState[SaleIndex]._Active, "Auction: Auction Is Still Active, Must Disperse Funds & Finalize Auction First");
        require(!SaleState[SaleIndex]._NFTsDispersed, "Auction: NFTs Already Dispersed");
        require(TokenIDs.length == AuctionParams[SaleIndex]._LeaderboardSize, "Auction: TokenIDs Array Length Must Match Leaderboard Size");
        uint[] memory _Ind = _ViewSortedLeaderboardBidIndexes(SaleIndex);
        address _Op = AuctionParams[SaleIndex]._Operator;
        IERC721 _NFT = IERC721(AuctionParams[SaleIndex]._NFT);
        for(uint x; x < TokenIDs.length; x++)
        {
            require(!NFTTokenIDHasBeenSent[SaleIndex][TokenIDs[x]], "Auction: TokenID Already Sent");
            NFTTokenIDHasBeenSent[SaleIndex][TokenIDs[x]] = true;
            _NFT.transferFrom(_Op, Bids[SaleIndex][_Ind[x]]._Bidder, TokenIDs[x]);
        }
    }

    /**
     * @dev Disperses NFTs To The Top Bidders On The Leaderboard (First-Come-First-Serve) (Use When TokenID Is Ambiguous)
     * @param SaleIndex The Sale Index To Trigger Disbursement
     */
    function __DisperseNFTsByFCFSAmbiguous(uint SaleIndex) internal
    {
        require(!SaleState[SaleIndex]._Active, "Auction: Auction Is Still Active, Must Disperse Funds & Finalize Auction First");
        require(!SaleState[SaleIndex]._NFTsDispersed, "Auction: NFTs Already Dispersed");
        SaleState[SaleIndex]._NFTsDispersed = true;
        IERC721 _NFT = IERC721(AuctionParams[SaleIndex]._NFT);
        for(uint x; x < AuctionParams[SaleIndex]._LeaderboardSize; x++) 
        { 
            if(Bids[SaleIndex][Leaderboard[SaleIndex][x]]._Winner && !Bids[SaleIndex][Leaderboard[SaleIndex][x]]._NFTSent)
            {
                Bids[SaleIndex][Leaderboard[SaleIndex][x]]._NFTSent = true;
                _NFT._MintToFactory(Bids[SaleIndex][Leaderboard[SaleIndex][x]]._Bidder, 1); 
            }
        }
    }

    /**
     * @dev Disperses NFTs By Ascending Ranking Of The Leaderboard (Use When TokenID Matters)
     * @param SaleIndex The Sale Index To Trigger Disbursement
     */ 
    function __DisperseNFTsByAscendingRank(uint SaleIndex) internal
    {
        require(SaleState[SaleIndex]._Active == false, "Auction: Auction Is Still Active, Must Disperse Funds First");
        require(!SaleState[SaleIndex]._NFTsDispersed, "Auction: NFTs Already Dispersed");
        SaleState[SaleIndex]._NFTsDispersed = true;
        IERC721 _NFT = IERC721(AuctionParams[SaleIndex]._NFT);
        uint[] memory _Ind = _ViewSortedLeaderboardBidIndexes(SaleIndex);
        for(uint x; x < _Ind.length; x++)
        { 
            if(Bids[SaleIndex][_Ind[x]]._Winner && !Bids[SaleIndex][_Ind[x]]._NFTSent)
            {
                Bids[SaleIndex][_Ind[x]]._NFTSent = true;
                _NFT._MintToFactory(Bids[SaleIndex][_Ind[x]]._Bidder, 1); 
            }
        }
    }

    /**
     * @dev Disperses NFTs To The Top Bidders On The Leaderboard (With Mint Pack Amounts) (With Ranking Enabled)
     * @param SaleIndex The Sale Index To Trigger Disbursement
     */
    function __DisperseNFTsMintPacks(uint SaleIndex) internal
    {
        require(!SaleState[SaleIndex]._Active, "Auction: Auction Is Still Active, Must Disperse Funds & Finalize Auction First");
        require(!SaleState[SaleIndex]._NFTsDispersed, "Auction: NFTs Already Dispersed");
        require(AuctionParams[SaleIndex]._MintPackAmount > 1, "Auction: Mint Pack Amount Must Be > 1");
        SaleState[SaleIndex]._NFTsDispersed = true;
        IERC721 _NFT = IERC721(AuctionParams[SaleIndex]._NFT);
        uint[] memory _Ind = _ViewSortedLeaderboardBidIndexes(SaleIndex);
        uint _MintPackAmount = AuctionParams[SaleIndex]._MintPackAmount;
        for(uint x; x < _Ind.length; x++)
        {
            if(Bids[SaleIndex][_Ind[x]]._Winner && !Bids[SaleIndex][_Ind[x]]._NFTSent)
            {
                Bids[SaleIndex][_Ind[x]]._NFTSent = true;
                _NFT._MintToFactory(Bids[SaleIndex][_Ind[x]]._Bidder, _MintPackAmount); 
            }
        }
    }

    /*------------------------
     * PUBLIC VIEW FUNCTIONS *
    -------------------------*/

    /**
     * @dev Returns All Necessary Leaderboard Components
     * @param SaleIndex The Sale Index To View
     * @param Wallet The Wallet Address Of The Bidder ('0x0000000000000000000000000000000000000000') If No Wallet
     * @return _LowestLeaderboardBid The Lowest Current Leaderboard Bid
     * @return _MinimumNewBid The Minimum Viable Bid That Can Be Submitted To The Auction
     * @return _AuctionParams The Auction Parameters
     * @return _RankedLeaderboard The Ranked Leaderboard
     * @return _UserBidIndexes The Bid Indexes Of The User
     * @return _DiscountAmounts The Discount Amounts For Brightlist Priority Tiers ([80,90,95] = 20% Discount, 10% Discount, 5% Discount)
     * @return _MerkleRootsEligibility The Merkle Roots For Priority Eligibility
     * @return _MerkleRootsAmounts The Merkle Roots For Priority Allocation
     */
    function ViewFrontend ( uint SaleIndex, address Wallet ) public view returns (
        uint _LowestLeaderboardBid, 
        uint _MinimumNewBid, 
        AllAuctionParams memory _AuctionParams, 
        Bid[] memory _RankedLeaderboard,
        uint[] memory _UserBidIndexes,
        uint[] memory _DiscountAmounts,
        bytes32[] memory _MerkleRootsEligibility,
        bytes32[] memory _MerkleRootsAmounts
    ) {
        uint LLB = _ViewLowestLeaderboardBid(SaleIndex);
        _RankedLeaderboard = _ViewLeaderboardRanked(SaleIndex);
        uint MVB = LLB * (AuctionParams[SaleIndex]._MinBIPSIncrease) / 100;
        if(SaleState[SaleIndex]._GlobalUniqueBids < AuctionParams[SaleIndex]._LeaderboardSize) 
        { (LLB, MVB) = (SaleState[SaleIndex]._LastMinBid, SaleState[SaleIndex]._LastMinBid); }
        return (
            LLB,
            MVB,
            ViewAuctionParams(SaleIndex),
            ViewLeaderboardRanked(SaleIndex),
            UserBidIndexes[SaleIndex][Wallet],
            Discounts[SaleIndex],
            MerkleRootsEligibility[SaleIndex],
            MerkleRootsAmounts[SaleIndex]
        );
    }

    /**
     * @dev Returns All Bid Values In The Leaderboard
     * @param SaleIndex The Sale Index To View
     */
    function ViewLeaderboardBids(uint SaleIndex) public view returns (uint[] memory)
    {
        uint[] memory _Indexes = ViewLeaderboardIndexes(SaleIndex);
        uint[] memory _BidValues = new uint[](AuctionParams[SaleIndex]._LeaderboardSize);
        for(uint x; x < AuctionParams[SaleIndex]._LeaderboardSize; x++) { _BidValues[x] = Bids[SaleIndex][_Indexes[x]]._ETHValue; }
        return _BidValues;
    }

    /**
     * @dev Returns A Bid Array Of Ranked Top Bids
     * @param SaleIndex The Sale Index To View
     */
    function ViewLeaderboardRanked(uint SaleIndex) public view returns(Bid[] memory) { return _ViewLeaderboardRanked(SaleIndex); }

    /**
     * @dev Returns All Bid Indexes In The Leaderboard
     * @param SaleIndex The Sale Index To View
     */
    function ViewLeaderboardIndexes(uint SaleIndex) public view returns (uint[] memory)
    {
        uint[] memory _LeaderboardIndexes = new uint[](AuctionParams[SaleIndex]._LeaderboardSize);
        for(uint x; x < AuctionParams[SaleIndex]._LeaderboardSize; x++) { _LeaderboardIndexes[x] = Leaderboard[SaleIndex][x]; }
        return _LeaderboardIndexes;
    }

    /**
     * @dev Returns The Minimum Valid Bid 
     * @param SaleIndex The Sale Index To View
     */
    function ViewMinimumValidBid(uint SaleIndex) public view returns (uint ValidBid) 
    { 
        (ValidBid,) = _ViewMinimumValidBidAndIndex(SaleIndex);
        return ValidBid;
    }

    /**
     * @dev Returns A 'Bid' Struct Array Corresponding To Input Indexes
     * @param SaleIndex The Sale Index To View
     */
    function ViewBidsUnique(uint SaleIndex) public view returns ( Bid[] memory )
    {
        Bid[] memory _Bids = new Bid[](SaleState[SaleIndex]._GlobalUniqueBids);
        for(uint x; x < SaleState[SaleIndex]._GlobalUniqueBids; x++) { _Bids[x] = Bids[SaleIndex][x]; }
        return _Bids;
    }

    /**
     * @dev Returns A 'Bid' Struct Array Corresponding To Input Indexes
     * @param SaleIndex The Sale Index To View
     * @param Indexes The Indexes To Return
     */
    function ViewBidsAtIndexes(uint SaleIndex, uint[] calldata Indexes) public view returns(Bid[] memory) 
    {
        Bid[] memory _Bids = new Bid[](Indexes.length);
        for(uint x; x < Indexes.length; x++) { _Bids[x] = Bids[SaleIndex][Indexes[x]]; }
        return _Bids;
    }

    /**
     * @dev Returns A `Bid` Struct Array Of All Unique Bids In The Auction Submitted By `Wallet`
     * @param SaleIndex The Sale Index To View
     * @param Wallet The Wallet Address To View
     */
    function ViewWalletBids(uint SaleIndex, address Wallet) public view returns(Bid[] memory)
    {
        uint[] memory _Indexes = UserBidIndexes[SaleIndex][Wallet];
        Bid[] memory _Bids = new Bid[](_Indexes.length);
        for(uint x; x < _Indexes.length; x++) { _Bids[x] = Bids[SaleIndex][_Indexes[x]]; }
        return _Bids;
    }

    /**
     * @dev Returns An Array Of `Wallet` Submitted Bid Indexes
     * @param SaleIndex The Sale Index To View
     * @param Wallet The Wallet Address To View
     */
    function ViewWalletBidIndexes(uint SaleIndex, address Wallet) public view returns(uint[] memory) { return UserBidIndexes[SaleIndex][Wallet]; }

    /**
     * @dev Returns All Of The Current Auction Parameters
     * @param SaleIndex The Sale Index To View
     */
    function ViewAuctionParams(uint SaleIndex) public view returns (AllAuctionParams memory)
    {
        return AllAuctionParams (
            AuctionParams[SaleIndex]._Name,
            SaleState[SaleIndex]._Active,
            SaleState[SaleIndex]._NFTsDispersed,
            AuctionParams[SaleIndex]._SettlementEnabled,
            AuctionParams[SaleIndex]._LeaderboardSize,
            AuctionParams[SaleIndex]._UnixStartTime,
            AuctionParams[SaleIndex]._UnixEndTime,
            AuctionParams[SaleIndex]._MinBIPSIncrease,
            AuctionParams[SaleIndex]._SecondsExtension,
            AuctionParams[SaleIndex]._SecondsThreshold,
            SaleState[SaleIndex]._LastMinBid,
            SaleState[SaleIndex]._GlobalUniqueBids,
            AuctionParams[SaleIndex]._ProjectIDMintPass,
            AuctionParams[SaleIndex]._MintPackAmount,
            AuctionParams[SaleIndex]._NFT
        );
    }

    /**
     * @dev Returns Merkle Roots For A Specific Sale
     * @param SaleIndex The Sale Index To View
     */
    function ViewRoots(uint SaleIndex) public view returns (bytes32[] memory) { return MerkleRootsEligibility[SaleIndex]; }

    /*--------------------------
     * INTERNAL VIEW FUNCTIONS *
    ---------------------------*/

    /**
     * @dev Validates Merkle Proof And Returns Merkle Priority
     * @param SaleIndex The Sale Index To View
     * @param MaxAmount The Maximum Allocation For Merkle Priority
     * @param Bidder The Bidder To Validate
     * @param ProofEligibility The Merkle Proof To Validate For Priority Eligibilty Tier
     * @param ProofAmount The Merkle Proof To Validate For Maximum Merkle Amount
     */
    function _ValidateMerkleProofs (
        uint SaleIndex, 
        uint MaxAmount, 
        address Bidder, 
        bytes32[] calldata ProofEligibility, 
        bytes32[] calldata ProofAmount
    ) internal view returns (uint) {
        bytes32 Leaf = keccak256(abi.encodePacked(Bidder));
        for(uint Priority; Priority < Discounts[SaleIndex].length; Priority++) 
        { 
            if(MerkleProof.verify(ProofEligibility, MerkleRootsEligibility[SaleIndex][Priority], Leaf))
            {
                require (
                    MerkleProof.verify (
                        ProofAmount, 
                        MerkleRootsAmounts[SaleIndex][Priority], 
                        keccak256(abi.encodePacked(Bidder, MaxAmount))
                    ), 
                    "Auction: Invalid Merkle Amount"
                );
                return ( Priority ); // Returns Valid Priority
            } 
        }
        return ( 69420 ); // Returns Default Out Of Bounds Priority
    }

    /**
     * @dev Returns The Leaderboard Index Of The Smallest Bid In The Leaderboard 
     * @param SaleIndex The Sale Index To View
     */
    function _ViewMinimumValidLeaderboardIndex(uint SaleIndex) internal view returns (uint)
    {
        uint CurrentMinBid = type(uint).max;
        uint LeaderboardIndexToReplace;
        uint ETHValue;
        if(SaleState[SaleIndex]._GlobalUniqueBids < AuctionParams[SaleIndex]._LeaderboardSize) { return SaleState[SaleIndex]._GlobalUniqueBids; }
        for(uint IndexLeaderboard; IndexLeaderboard < AuctionParams[SaleIndex]._LeaderboardSize; IndexLeaderboard++)
        {
            ETHValue = Bids[SaleIndex][Leaderboard[SaleIndex][IndexLeaderboard]]._ETHValue;
            if(ETHValue <= CurrentMinBid)
            { 
                CurrentMinBid = ETHValue;
                LeaderboardIndexToReplace = IndexLeaderboard; 
            }
        }
        return LeaderboardIndexToReplace;
    }

    /**
     * @dev Returns The Lowest Bid In The Leaderboard
     * @param SaleIndex The Sale Index To View
     */
    function _ViewLowestLeaderboardBid(uint SaleIndex) internal view returns (uint LLB)
    {
        LLB = type(uint).max;
        for(uint x; x < AuctionParams[SaleIndex]._LeaderboardSize; x++)
        {
            if(Bids[SaleIndex][Leaderboard[SaleIndex][x]]._ETHValue < LLB) { LLB = Bids[SaleIndex][Leaderboard[SaleIndex][x]]._ETHValue; }
        }
        return LLB;
    }

    /**
     * @dev Returns The Minimum Valid Bid Which Is The Current Lowest Bid In The Leaderboard * 1.05
     * @param SaleIndex The Sale Index To View
     */
    function _ViewMinimumValidBidAndIndex(uint SaleIndex) internal view returns (uint, uint) 
    {
        uint LeaderboardIndex = _ViewMinimumValidLeaderboardIndex(SaleIndex);
        return (        
            SaleState[SaleIndex]._GlobalUniqueBids < AuctionParams[SaleIndex]._LeaderboardSize 
            ? // If Unique Bids Less Than LeaderboardSize Return NewMinimumBid & Eligible LeaderboardIndex
            (SaleState[SaleIndex]._LastMinBid, LeaderboardIndex) 
            : // Else Return NewMinimumBid & Eligible LeaderboardIndex
            ((Bids[SaleIndex][Leaderboard[SaleIndex][LeaderboardIndex]]._ETHValue * AuctionParams[SaleIndex]._MinBIPSIncrease) / 100, LeaderboardIndex) 
        );
    }

    /**
     * @dev Returns A 'Bid' Struct Array Of All Unique Bids In The Auction
     * @param SaleIndex The Sale Index To View
     * note: this will throw `out of gas` after 1648~ unique bids because block gas limit is 30M, use `ViewBids()` with indexes after 1648~ unique bids
     */
    function _ViewBidsUnique(uint SaleIndex) internal view returns(Bid[] memory)
    {
        uint GlobalUniqueBids = SaleState[SaleIndex]._GlobalUniqueBids;
        Bid[] memory _Bids = new Bid[](GlobalUniqueBids);
        for(uint x; x < GlobalUniqueBids; x++) { _Bids[x] = Bids[SaleIndex][x]; }
        return _Bids;
    }
    
    /**
     * @dev Returns A Bid Array Of Ranked Top Bids
     * @param SaleIndex The Sale Index To View
     */
    function _ViewLeaderboardRanked(uint SaleIndex) internal view returns(Bid[] memory)
    {
        uint[] memory _Ind = _ViewSortedLeaderboardBidIndexes(SaleIndex);
        Bid[] memory _Leaderboard = new Bid[](_Ind.length);
        for(uint x; x < _Ind.length; x++) { _Leaderboard[x] = Bids[SaleIndex][_Ind[x]]; }
        return _Leaderboard;
    }

    /**
     * @dev Returns A Sorted List Of ETH Bids @ '[n][0]' & The Indexes Of The Original Bids @ '[n][1]' & The Timestamps @ '[n][2]'
     * @param SaleIndex The Sale Index To View
     * note: This Will Give Priority To Earlier Bid Indexes & Timestamps
     * note: insertion sort O(n^2) seemed like best approach because english auction bids increase as auction progresses, otherwise quicksort prob better O(nlogn)
     * note: because block gas limit is 30M, this will `out-of-gas` dependant on how much sorting needs done if you have a more eloquent way of doing this hmu
     * note: you should (in general) not sort large things in solidity (as of 0.8~) because it is very gas inefficient, this is just for demonstration purposes
     */
    function _ViewSortedLeaderboardBidIndexes(uint SaleIndex) internal view returns (uint[] memory)
    {
        uint Size;
        if(SaleState[SaleIndex]._GlobalUniqueBids < AuctionParams[SaleIndex]._LeaderboardSize) { Size = SaleState[SaleIndex]._GlobalUniqueBids; }
        else { Size = AuctionParams[SaleIndex]._LeaderboardSize; }
        uint[][] memory BidsAndIndexes = new uint[][](Size);
        for(uint x; x < BidsAndIndexes.length; x++) 
        {
            BidsAndIndexes[x] = new uint[](3);                                            // Init Sub-Array
            BidsAndIndexes[x][0] = Bids[SaleIndex][Leaderboard[SaleIndex][x]]._ETHValue;  // Assign [x][0] -> ETHValue
            BidsAndIndexes[x][1] = Leaderboard[SaleIndex][x];                             // Assign [x][1] -> Original Index
            BidsAndIndexes[x][2] = Bids[SaleIndex][Leaderboard[SaleIndex][x]]._Timestamp; // Assign [x][2] -> Timestamp
        }
        for(uint i; i < BidsAndIndexes.length; i++)
        {
            uint ETHValue = BidsAndIndexes[i][0];   // Preserve ETHValue
            uint OGBidIndex = BidsAndIndexes[i][1]; // Preserve OGBidIndex
            uint Timestamp = BidsAndIndexes[i][2];  // Preserve Timestamp
            uint j = i;
            while(j > 0 && BidsAndIndexes[j-1][0] >= ETHValue)
            {
                if(
                    BidsAndIndexes[j-1][0] == ETHValue && BidsAndIndexes[j-1][1] > OGBidIndex // Preserve Lower Original Index
                    ||                                                                        // Or
                    BidsAndIndexes[j-1][0] == ETHValue && BidsAndIndexes[j-1][2] > Timestamp  // Preserve Lower Timestamp
                ) { break; } 
                BidsAndIndexes[j][0] = BidsAndIndexes[j-1][0]; // Move Larger Element To The Right
                BidsAndIndexes[j][1] = BidsAndIndexes[j-1][1]; // Move OG Index
                BidsAndIndexes[j][2] = BidsAndIndexes[j-1][2]; // Move Timestamp
                j--;
            }
            BidsAndIndexes[j][0] = ETHValue;   // Insert ETHValue In Correct Location
            BidsAndIndexes[j][1] = OGBidIndex; // Insert OGBidIndex In Correct Location
            BidsAndIndexes[j][2] = Timestamp;  // Insert Timestamp In Correct Location
        } 
        uint[] memory SortedBidIndexes = new uint[](Size);
        for(uint y; y < BidsAndIndexes.length; y++) { SortedBidIndexes[Size - 1 - y] = BidsAndIndexes[y][1]; }
        return SortedBidIndexes;
    }
}

/**
 * @dev Interface For ERC721 Contracts
 */
interface IERC721 
{ 
    /**
     * @dev Mints A NFT From Custom Smart Contract Directly
     */
    function _MintToFactory(address Recipient, uint Amount) external; 

    /**
     * @dev Transfers An Already Minted NFT
     */
    function transferFrom(address from, address to, uint tokenID) external;
}

File 2 of 5 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @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 ReentrancyGuard {
    // 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;

    constructor() {
        _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 making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

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

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == _ENTERED;
    }
}

File 3 of 5 : MerkleProof.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.2) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The tree and the proofs can be generated using our
 * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
 * You will find a quickstart guide in the readme.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 * OpenZeppelin's JavaScript library generates merkle trees that are safe
 * against this attack out of the box.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Calldata version of {verify}
     *
     * _Available since v4.7._
     */
    function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Calldata version of {processProof}
     *
     * _Available since v4.7._
     */
    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerify(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProof(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Calldata version of {multiProofVerify}
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerifyCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
     * respectively.
     *
     * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
     *
     * _Available since v4.7._
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 proofLen = proof.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i]
                ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
                : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            require(proofPos == proofLen, "MerkleProof: invalid multiproof");
            unchecked {
                return hashes[totalHashes - 1];
            }
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 proofLen = proof.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i]
                ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
                : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            require(proofPos == proofLen, "MerkleProof: invalid multiproof");
            unchecked {
                return hashes[totalHashes - 1];
            }
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

File 4 of 5 : DelegateCashEnabled.sol
//SPDX-License-Identifier: MIT
/**
 * @title DelegateCashEnabled
 * @author @brougkr
 * @notice For Easily Integrating `delegate.cash`
 */
pragma solidity ^0.8.19;
abstract contract DelegateCashEnabled
{
    address private constant _DN = 0x00000000000076A84feF008CDAbe6409d2FE638B;
    IDelegation public constant DelegateCash = IDelegation(_DN);
}

interface IDelegation
{
    /**
     * @dev Returns If A Vault Has Delegated To The Delegate
     */
    function checkDelegateForAll(address delegate, address vault) external view returns (bool);
}

File 5 of 5 : MissionControl.sol
//SPDX-License-Identifier: MIT
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                           @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@           @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@              @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@              @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@           @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                           @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/**
 * @dev: @brougkr
 * @title MissionControl
 * @notice Smart Contract To Facilitate Owner, Admin, & Operator Management & Access Control
 */
pragma solidity 0.8.19;
contract MissionControl
{
    address public _OWNER;                              // Owner Of The Contract        
    address public _LAUNCHPAD;                          // Address Of The Launchpad Contract
    mapping(address => bool) public AuthorizedAdmin;    // [Address] -> [IsAdmin?]
    mapping(address => bool) public AuthorizedOperator; // [Address] -> [IsOperator?]

    /*-----------------------------------------------------*/
    /*------------------ * CONSTRUCTOR * ------------------*/
    /*-----------------------------------------------------*/

    constructor()
    {
        _OWNER = 0xe06F5FAE754e81Bc050215fF89B03d9e9FF20700;                // `operator.brightmoments.eth`
        AuthorizedAdmin[msg.sender] = true;                                 // `deployer.brightmoments.eth`
        AuthorizedAdmin[0x90D98d5A1fD21B7cEa4D5c18341607ed1a8345c0] = true; // `gitpancake.brightmoments.eth`
        AuthorizedAdmin[0x18B7511938FBe2EE08ADf3d4A24edB00A5C9B783] = true; // `phil.brightmoments.eth`
        AuthorizedAdmin[0x91594b5E5d74FCCB3f71674eE74C5F4D44f333D5] = true; // `future.brightmoments.eth`
    }

    /*---------------------------------------------------------*/
    /*------------------ * ADMIN FUNCTIONS * ------------------*/
    /*---------------------------------------------------------*/

    /**
     * @dev Changes The Launchpad Address
     */
    function __AdminChangeOperatorState(address _Address) external onlyAdmin { AuthorizedOperator[_Address] = !AuthorizedOperator[_Address]; }
    
    /*---------------------------------------------------------*/
    /*------------------ * OWNER FUNCTIONS * ------------------*/
    /*---------------------------------------------------------*/

    /**
     * @dev Authorizes Or Deauthorizes An Address's Admin Status
     * @param _Address: Address To Authorize Or Deauthorize
     */
    function ___OwnerChangeAdminState(address _Address) external onlyOwner { AuthorizedAdmin[_Address] = !AuthorizedAdmin[_Address]; }

    /**
     * @dev Transfers Ownership Of The Contract
     * @param _NewOwner: Address To Transfer Ownership To
     */
    function ___OwnerTransferOwnership(address _NewOwner) external onlyOwner { _OWNER = _NewOwner; }

    /*-------------------------------------------------------------*/
    /*------------------ * LAUNCHPAD FUNCTIONS * ------------------*/
    /*-------------------------------------------------------------*/

    /**
     * @dev Overrides The Launchpad Address
     * @param _Address: Address To Override The Launchpad Address With
     * @notice This Function Is Only Accessible By The Launchpad Contract Or An Authorized Admin
     */
    function ____LaunchpadOverrideAddress(address _Address) external onlyLaunchpad { _LAUNCHPAD = _Address; }

    /*----------------------------------------------------------*/
    /*------------------ * ACCESS MODIFIERS * ------------------*/
    /*----------------------------------------------------------*/

    /**
     * @dev onlyOperator Access Modifier
     */
    modifier onlyOperator
    {
        require(AuthorizedOperator[msg.sender] || AuthorizedAdmin[msg.sender] || msg.sender == _LAUNCHPAD, "MissionControl | onlyOperator | Caller Is Not Operator Or Admin");
        _;
    }

    /**
     * @dev onlyAdmin Access Modifier
     */
    modifier onlyAdmin
    {   
        require(AuthorizedAdmin[msg.sender], "MissionControl | onlyAdmin | Caller Is Not Admin");
        _;
    }

    /**
     * @dev onlyOwner Access Modifier
     */
    modifier onlyOwner
    {
        require(_OWNER == msg.sender, "MissionControl | onlyOwner | Caller Is Not Owner");
        _;
    }

    /**
     * @dev onlyLaunchpad Access Modifier
     */
    modifier onlyLaunchpad
    {
        require(_LAUNCHPAD == msg.sender || AuthorizedAdmin[msg.sender], "MissionControl | onlyLaunchpad | Caller Is Not Launchpad");
        _;
    }
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[],"name":"AuctionExtended","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"BidIndex","type":"uint256"}],"name":"BidReclaimFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"BidIndex","type":"uint256"}],"name":"BidReclaimSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"BidIndex","type":"uint256"}],"name":"BidRefunded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"BidIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ETHForBid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"Unixtimestamp","type":"uint256"},{"indexed":false,"internalType":"address","name":"Bidder","type":"address"}],"name":"BidToppedUp","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"Rebate","type":"uint256"}],"name":"BidTopupRefunded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"BidIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"Bidder","type":"address"},{"indexed":false,"internalType":"uint256","name":"MessageValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"Unixtimestamp","type":"uint256"},{"indexed":false,"internalType":"address","name":"Vault","type":"address"}],"name":"NewBidComplete","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"SaleIndex","type":"uint256"}],"name":"SaleStarted","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"AuctionParams","outputs":[{"internalType":"string","name":"_Name","type":"string"},{"internalType":"bool","name":"_SettlementEnabled","type":"bool"},{"internalType":"bool","name":"_UserSettlementEnabled","type":"bool"},{"internalType":"uint256","name":"_LeaderboardSize","type":"uint256"},{"internalType":"uint256","name":"_UnixStartTime","type":"uint256"},{"internalType":"uint256","name":"_UnixEndTime","type":"uint256"},{"internalType":"uint256","name":"_MinBIPSIncrease","type":"uint256"},{"internalType":"uint256","name":"_SecondsExtension","type":"uint256"},{"internalType":"uint256","name":"_SecondsThreshold","type":"uint256"},{"internalType":"uint256","name":"_InitialMinimumBid","type":"uint256"},{"internalType":"uint256","name":"_ProjectIDMintPass","type":"uint256"},{"internalType":"uint256","name":"_MintPackAmount","type":"uint256"},{"internalType":"address","name":"_NFT","type":"address"},{"internalType":"address","name":"_Operator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"AuthorizedAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"AuthorizedOperator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"Bids","outputs":[{"internalType":"uint256","name":"_OGBidIndex","type":"uint256"},{"internalType":"uint256","name":"_Priority","type":"uint256"},{"internalType":"uint256","name":"_Allocation","type":"uint256"},{"internalType":"uint256","name":"_ETHValue","type":"uint256"},{"internalType":"uint256","name":"_Timestamp","type":"uint256"},{"internalType":"address","name":"_Bidder","type":"address"},{"internalType":"address","name":"_Vault","type":"address"},{"internalType":"bool","name":"_Rebated","type":"bool"},{"internalType":"bool","name":"_Winner","type":"bool"},{"internalType":"bool","name":"_NFTSent","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DelegateCash","outputs":[{"internalType":"contract IDelegation","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"Discounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"uint256[]","name":"BidIndexes","type":"uint256[]"},{"internalType":"uint256[]","name":"Amounts","type":"uint256[]"}],"name":"IncreaseBid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"Leaderboard","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"MerkleRootsAmounts","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"MerkleRootsEligibility","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"NFTTokenIDHasBeenSent","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"uint256","name":"MaxAmount","type":"uint256"},{"internalType":"address","name":"Vault","type":"address"},{"internalType":"bytes32[]","name":"ProofEligibility","type":"bytes32[]"},{"internalType":"bytes32[]","name":"ProofAmount","type":"bytes32[]"}],"name":"NewBid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"PriorityPurchaseAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"SaleState","outputs":[{"internalType":"bool","name":"_Active","type":"bool"},{"internalType":"bool","name":"_NFTsDispersed","type":"bool"},{"internalType":"uint256","name":"_LastMinBid","type":"uint256"},{"internalType":"uint256","name":"_GlobalUniqueBids","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"UserBidIndexes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"}],"name":"UserSettleAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"}],"name":"ViewAuctionParams","outputs":[{"components":[{"internalType":"string","name":"_Name","type":"string"},{"internalType":"bool","name":"_Active","type":"bool"},{"internalType":"bool","name":"_NFTsDispersed","type":"bool"},{"internalType":"bool","name":"_SettlementEnabled","type":"bool"},{"internalType":"uint256","name":"_LeaderboardSize","type":"uint256"},{"internalType":"uint256","name":"_UnixStartTime","type":"uint256"},{"internalType":"uint256","name":"_UnixEndTime","type":"uint256"},{"internalType":"uint256","name":"_MinBIPSIncrease","type":"uint256"},{"internalType":"uint256","name":"_SecondsExtension","type":"uint256"},{"internalType":"uint256","name":"_SecondsThreshold","type":"uint256"},{"internalType":"uint256","name":"_LastMinBid","type":"uint256"},{"internalType":"uint256","name":"_GlobalUniqueBids","type":"uint256"},{"internalType":"uint256","name":"_ProjectIDMintPass","type":"uint256"},{"internalType":"uint256","name":"_MintPackAmount","type":"uint256"},{"internalType":"address","name":"_NFT","type":"address"}],"internalType":"struct EnglishMarketplace.AllAuctionParams","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"uint256[]","name":"Indexes","type":"uint256[]"}],"name":"ViewBidsAtIndexes","outputs":[{"components":[{"internalType":"uint256","name":"_OGBidIndex","type":"uint256"},{"internalType":"uint256","name":"_Priority","type":"uint256"},{"internalType":"uint256","name":"_Allocation","type":"uint256"},{"internalType":"uint256","name":"_ETHValue","type":"uint256"},{"internalType":"uint256","name":"_Timestamp","type":"uint256"},{"internalType":"address","name":"_Bidder","type":"address"},{"internalType":"address","name":"_Vault","type":"address"},{"internalType":"bool","name":"_Rebated","type":"bool"},{"internalType":"bool","name":"_Winner","type":"bool"},{"internalType":"bool","name":"_NFTSent","type":"bool"}],"internalType":"struct EnglishMarketplace.Bid[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"}],"name":"ViewBidsUnique","outputs":[{"components":[{"internalType":"uint256","name":"_OGBidIndex","type":"uint256"},{"internalType":"uint256","name":"_Priority","type":"uint256"},{"internalType":"uint256","name":"_Allocation","type":"uint256"},{"internalType":"uint256","name":"_ETHValue","type":"uint256"},{"internalType":"uint256","name":"_Timestamp","type":"uint256"},{"internalType":"address","name":"_Bidder","type":"address"},{"internalType":"address","name":"_Vault","type":"address"},{"internalType":"bool","name":"_Rebated","type":"bool"},{"internalType":"bool","name":"_Winner","type":"bool"},{"internalType":"bool","name":"_NFTSent","type":"bool"}],"internalType":"struct EnglishMarketplace.Bid[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"address","name":"Wallet","type":"address"}],"name":"ViewFrontend","outputs":[{"internalType":"uint256","name":"_LowestLeaderboardBid","type":"uint256"},{"internalType":"uint256","name":"_MinimumNewBid","type":"uint256"},{"components":[{"internalType":"string","name":"_Name","type":"string"},{"internalType":"bool","name":"_Active","type":"bool"},{"internalType":"bool","name":"_NFTsDispersed","type":"bool"},{"internalType":"bool","name":"_SettlementEnabled","type":"bool"},{"internalType":"uint256","name":"_LeaderboardSize","type":"uint256"},{"internalType":"uint256","name":"_UnixStartTime","type":"uint256"},{"internalType":"uint256","name":"_UnixEndTime","type":"uint256"},{"internalType":"uint256","name":"_MinBIPSIncrease","type":"uint256"},{"internalType":"uint256","name":"_SecondsExtension","type":"uint256"},{"internalType":"uint256","name":"_SecondsThreshold","type":"uint256"},{"internalType":"uint256","name":"_LastMinBid","type":"uint256"},{"internalType":"uint256","name":"_GlobalUniqueBids","type":"uint256"},{"internalType":"uint256","name":"_ProjectIDMintPass","type":"uint256"},{"internalType":"uint256","name":"_MintPackAmount","type":"uint256"},{"internalType":"address","name":"_NFT","type":"address"}],"internalType":"struct EnglishMarketplace.AllAuctionParams","name":"_AuctionParams","type":"tuple"},{"components":[{"internalType":"uint256","name":"_OGBidIndex","type":"uint256"},{"internalType":"uint256","name":"_Priority","type":"uint256"},{"internalType":"uint256","name":"_Allocation","type":"uint256"},{"internalType":"uint256","name":"_ETHValue","type":"uint256"},{"internalType":"uint256","name":"_Timestamp","type":"uint256"},{"internalType":"address","name":"_Bidder","type":"address"},{"internalType":"address","name":"_Vault","type":"address"},{"internalType":"bool","name":"_Rebated","type":"bool"},{"internalType":"bool","name":"_Winner","type":"bool"},{"internalType":"bool","name":"_NFTSent","type":"bool"}],"internalType":"struct EnglishMarketplace.Bid[]","name":"_RankedLeaderboard","type":"tuple[]"},{"internalType":"uint256[]","name":"_UserBidIndexes","type":"uint256[]"},{"internalType":"uint256[]","name":"_DiscountAmounts","type":"uint256[]"},{"internalType":"bytes32[]","name":"_MerkleRootsEligibility","type":"bytes32[]"},{"internalType":"bytes32[]","name":"_MerkleRootsAmounts","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"}],"name":"ViewLeaderboardBids","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"}],"name":"ViewLeaderboardIndexes","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"}],"name":"ViewLeaderboardRanked","outputs":[{"components":[{"internalType":"uint256","name":"_OGBidIndex","type":"uint256"},{"internalType":"uint256","name":"_Priority","type":"uint256"},{"internalType":"uint256","name":"_Allocation","type":"uint256"},{"internalType":"uint256","name":"_ETHValue","type":"uint256"},{"internalType":"uint256","name":"_Timestamp","type":"uint256"},{"internalType":"address","name":"_Bidder","type":"address"},{"internalType":"address","name":"_Vault","type":"address"},{"internalType":"bool","name":"_Rebated","type":"bool"},{"internalType":"bool","name":"_Winner","type":"bool"},{"internalType":"bool","name":"_NFTSent","type":"bool"}],"internalType":"struct EnglishMarketplace.Bid[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"}],"name":"ViewMinimumValidBid","outputs":[{"internalType":"uint256","name":"ValidBid","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"}],"name":"ViewRoots","outputs":[{"internalType":"bytes32[]","name":"","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"address","name":"Wallet","type":"address"}],"name":"ViewWalletBidIndexes","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"address","name":"Wallet","type":"address"}],"name":"ViewWalletBids","outputs":[{"components":[{"internalType":"uint256","name":"_OGBidIndex","type":"uint256"},{"internalType":"uint256","name":"_Priority","type":"uint256"},{"internalType":"uint256","name":"_Allocation","type":"uint256"},{"internalType":"uint256","name":"_ETHValue","type":"uint256"},{"internalType":"uint256","name":"_Timestamp","type":"uint256"},{"internalType":"address","name":"_Bidder","type":"address"},{"internalType":"address","name":"_Vault","type":"address"},{"internalType":"bool","name":"_Rebated","type":"bool"},{"internalType":"bool","name":"_Winner","type":"bool"},{"internalType":"bool","name":"_NFTSent","type":"bool"}],"internalType":"struct EnglishMarketplace.Bid[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"}],"name":"_ChangeActiveState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"uint256[]","name":"NewDiscountAmounts","type":"uint256[]"}],"name":"_ChangeDiscountAmounts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"uint256","name":"NewLeaderboardSize","type":"uint256"}],"name":"_ChangeLeaderboardSize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"uint256","name":"NewMinBIPSIncrease","type":"uint256"}],"name":"_ChangeMinBIPSIncrease","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"uint256","name":"NewMinBid","type":"uint256"}],"name":"_ChangeMinBid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"uint256","name":"NewAmount","type":"uint256"}],"name":"_ChangeMintPackAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"uint256","name":"MintPassProjectID","type":"uint256"}],"name":"_ChangeMintPassProjectID","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"address","name":"NewAddress","type":"address"}],"name":"_ChangeNFTAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"address","name":"Operator","type":"address"}],"name":"_ChangeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"bytes32[]","name":"RootsEligibility","type":"bytes32[]"},{"internalType":"bytes32[]","name":"RootsAmounts","type":"bytes32[]"}],"name":"_ChangeRoots","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"uint256","name":"Seconds","type":"uint256"}],"name":"_ChangeSecondsExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"uint256","name":"Seconds","type":"uint256"}],"name":"_ChangeSecondsThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"bool","name":"NewState","type":"bool"}],"name":"_ChangeSettlementEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"uint256","name":"NewUnixEndTime","type":"uint256"}],"name":"_ChangeUnixEndTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"uint256","name":"NewUnixStartTime","type":"uint256"}],"name":"_ChangeUnixStartTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"_GLOBAL_UNIQUE_SALES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"}],"name":"_InitiateRebateAndProceeds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"_LAUNCHPAD","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_OWNER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"}],"name":"_ProcessETHAndNFTsMintPacksRanked","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"}],"name":"_ProcessETHAndNFTsTokenIDsAmbiguous","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"}],"name":"_ProcessETHAndNFTsTokenIDsDistinct","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"},{"internalType":"uint256[]","name":"TokenIDs","type":"uint256[]"}],"name":"_ProcessETHAndNFTsTokenIDsSpecificRanked","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"_Name","type":"string"},{"internalType":"bool","name":"_SettlementEnabled","type":"bool"},{"internalType":"bool","name":"_UserSettlementEnabled","type":"bool"},{"internalType":"uint256","name":"_LeaderboardSize","type":"uint256"},{"internalType":"uint256","name":"_UnixStartTime","type":"uint256"},{"internalType":"uint256","name":"_UnixEndTime","type":"uint256"},{"internalType":"uint256","name":"_MinBIPSIncrease","type":"uint256"},{"internalType":"uint256","name":"_SecondsExtension","type":"uint256"},{"internalType":"uint256","name":"_SecondsThreshold","type":"uint256"},{"internalType":"uint256","name":"_InitialMinimumBid","type":"uint256"},{"internalType":"uint256","name":"_ProjectIDMintPass","type":"uint256"},{"internalType":"uint256","name":"_MintPackAmount","type":"uint256"},{"internalType":"address","name":"_NFT","type":"address"},{"internalType":"address","name":"_Operator","type":"address"}],"internalType":"struct EnglishMarketplace.Params","name":"AuctionInfo","type":"tuple"},{"internalType":"bytes32[]","name":"RootsEligibility","type":"bytes32[]"},{"internalType":"bytes32[]","name":"RootsAmounts","type":"bytes32[]"},{"internalType":"uint256[]","name":"DiscountAmounts","type":"uint256[]"}],"name":"_StartAuction","outputs":[{"internalType":"uint256","name":"SaleIndex","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_Address","type":"address"}],"name":"__AdminChangeOperatorState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"__WithdrawETHToMultisig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_Address","type":"address"}],"name":"___OwnerChangeAdminState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_NewOwner","type":"address"}],"name":"___OwnerTransferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"___WithdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_Address","type":"address"}],"name":"____LaunchpadOverrideAddress","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60406080815234620004135760018060a01b031990600073e06f5fae754e81bc050215ff89b03d9e9ff207008382541617815533815260206002815282822093600192839160ff199683888254161790557390d98d5a1fd21b7cea4d5c18341607ed1a8345c0825285822083888254161790557318b7511938fbe2ee08adf3d4a24edb00a5c9b783825285822083888254161790557391594b5e5d74fccb3f71674ee74c5f4d44f333d58252858220838882541617905560049683885583600f553382845416178355828052600685528683208482825416178155673782dace9d90000096879101556005855286832080548581811c9116801562000408575b87821014620003f557601f8111620003c7575b5073b642f85d2b23b16ac310cc0d462716d80608b25c91600b91602270506172697320476f6c64656e205061636b60781b01905584805260058752888520908680830191825416179055601460028201556003976365c11410898301556365c265908b830155606e6005830155610258806006840155600783015560088201556013600a8201550191825416179055600c8352848120918254680100000000000000009384821015620003b45790620001d091838201815562000418565b9490805495871b60001996877f9d68dac65c6a727c9df669d2cdd4f0aba1686eaa708148cb03e3a590ad1622e7831b921b1916179055828052600c815286832080549085821015620003a157906200022d91848201815562000418565b815490881b90877f6e03f1a95ca9713b999315f45ebd86a518ac26e25a8ce4faed4f36a05d3a23da831b921b1916179055828052600d815286832080549085821015620003a157906200028591848201815562000418565b815490881b90877f75ffaea20827ac2efdbb92096c519fc34f1ea2c377f9736b46905db7405e3207831b921b1916179055828052600d815286832080549085821015620003a15790620002dd91848201815562000418565b815490881b90877fd4a4248680d3ed1008af3ffe64a6dce5907ae2b6c27df6f700864078a1db99ad831b921b1916179055828052600b815286832080549085821015620003a15781620003389185600b959401815562000418565b815490891b9088605a831b921b191617905583805252858220918254938410156200038e5750820181556200036e919062000418565b81939154911b91605f831b921b191617905551615d7b9081620004488239f35b634e487b7160e01b815260418852602490fd5b634e487b7160e01b855260418a52602485fd5b634e487b7160e01b845260418952602484fd5b81855285601f888720920160051c8201915b828110620003e957505062000112565b868155018690620003d9565b634e487b7160e01b855260228a52602485fd5b90607f1690620000ff565b600080fd5b8054821015620004315760005260206000200190600090565b634e487b7160e01b600052603260045260246000fdfe6080604052600436101561001257600080fd5b60003560e01c8063041c1f14146141b6578063068035a514613e8c57806306c5bb9914613e115780630794736b14613cfe5780630b5d7bf014613ccb5780630b62209014613c985780630d5e64df146139e557806311ca8f3914613954578063185176cb146139195780631a3ec25b146138165780631aea2a9d146137e35780631b512f171461372b578063228dd2b5146136e357806325dd75f21461369a5780632d46c6a11461361f5780634bc54449146135a45780634c9016a0146135655780634e3b98bb14612efc57806356769c4614612d915780635928b66614612d3857806362a22e8914612cf257806368b4b7a014612cd35780636a95cc0814612caa578063765b8b5114612c83578063767b572314612be157806379005b301461249c57806379aa43f6146124145780637c04530d146121225780637df92fd11461203c578063824be6a214611fb45780638ee4855914611ecb578063906b1c9f14611ea4578063991c6f5914611e445780639ae9181714611e265780639d9d862314611d6e5780639eca8f6914611d3d578063a3e40def14611ce4578063a7f323da14611c38578063b009b55a14611c07578063b202367a14611bc8578063b451abcc14611b4d578063b4be58cb146119e9578063b538a8fa14611157578063b69dab3b14611044578063ca858d7a14610aa2578063cff9ebfb14610a6a578063d7470b1514610a2a578063d783f4eb146109af578063d7b50c3614610988578063d8fee6d514610925578063debdbe031461064e578063e07c41af146105b0578063e18aff4e14610535578063e30814af146104ba578063ead82d5314610465578063f480f4a0146104265763fe8778d81461028f57600080fd5b34610421576040600319360112610421576004356102ab614247565b6102b3615241565b506102bd826156cf565b906102c7836158aa565b5082600052602092600584528360646102e860056040600020015486614933565b049282600052600682526002604060002001546005835260026040600020015411610407575b916103e76103f5926103d961040396956103cb61032a866153af565b91610334876158aa565b9087600052600986526001600160a01b03604060002091166000528552604060002096600052600b85526103bd604060002093600c8752600d6040600020975261039d61039761039161038b60406000209c614c1a565b97614c1a565b98614c1a565b99614c1a565b9a6040519e8f9e8f908152015260408d61010091829101528d01906143d6565b908b820360608d0152614287565b9089820360808b01526144b9565b9087820360a08901526144b9565b9085820360c08701526144b9565b9083820360e08501526144b9565b0390f35b60069091526040600020600101549350839250849061030e565b600080fd5b346104215761043436614231565b90600052600d602052604060002080548210156104215760209161045791614539565b90546040519160031b1c8152f35b3461042157602060031936011261042157600435600052600660205260806040600020805490600260018201549101549060ff604051938181161515855260081c161515602084015260408301526060820152f35b34610421576104c836614231565b9033600052600360205260ff604060002054168015610521575b8015610508575b6104f290614983565b6000526005602052600660406000200155600080f35b506104f26001600160a01b0360015416331490506104e9565b50600260205260ff604060002054166104e2565b346104215761054336614231565b9033600052600360205260ff60406000205416801561059c575b8015610583575b61056d90614983565b6000526005602052600460406000200155600080f35b5061056d6001600160a01b036001541633149050610564565b50600260205260ff6040600020541661055d565b346104215760406003193601126104215760243580151581036104215761061f9033600052600360205260ff60406000205416801561063a575b8015610621575b6105fa90614983565b600435600052600560205260016040600020019060ff60ff1983541691151516179055565b005b506105fa6001600160a01b0360015416331490506105f1565b50600260205260ff604060002054166105ea565b346104215761065c36614362565b909133600052600360205260ff604060002054168015610911575b80156108f8575b61068790614983565b806000526006602052604060002060ff1981541690556106a681614caa565b8060005260066020526106c160ff604060002054161561515f565b8060005260066020526106df60ff60406000205460081c16156151f6565b806000526005602052600260406000200154820361088e5761070081615996565b928160005260056020526040600020916001600160a01b03600b81600c86015416940154169460005b85811061073257005b82600052600a80602052604060002061074c838988614923565b3560005260205260ff6040600020541661084a57836000526020526040600020610777828887614923565b356000526020526040600020600160ff1982541617905582600052600760205260406000206107a68284614c96565b516000526020526001600160a01b0360056040600020015416906107cb818887614923565b35883b1561042157604051927f23b872dd00000000000000000000000000000000000000000000000000000000845287600485015260248401526044830152600082606481838c5af191821561083e5761082a9261082f575b50614914565b610729565b61083890614580565b88610824565b6040513d6000823e3d90fd5b606460405162461bcd60e51b815260206004820152601d60248201527f41756374696f6e3a20546f6b656e494420416c72656164792053656e740000006044820152fd5b608460405162461bcd60e51b815260206004820152603a60248201527f41756374696f6e3a20546f6b656e494473204172726179204c656e677468204d60448201527f757374204d61746368204c6561646572626f6172642053697a650000000000006064820152fd5b506106876001600160a01b03600154163314905061067e565b50600260205260ff60406000205416610677565b34610421576020600319360112610421576001600160a01b0361094661425d565b33600052600260205261096060ff60406000205416614ac7565b16600052600360205261061f604060002060ff8154161560ff60ff1983541691151516179055565b346104215760006003193601126104215760206001600160a01b0360005416604051908152f35b34610421576109bd36614231565b9033600052600360205260ff604060002054168015610a16575b80156109fd575b6109e790614983565b6000526006602052600160406000200155600080f35b506109e76001600160a01b0360015416331490506109de565b50600260205260ff604060002054166109d7565b3461042157602060031936011261042157600435600052600c602052610403610a566040600020614c1a565b6040519182916020835260208301906144b9565b3461042157610a7836614231565b90600052600a602052604060002090600052602052602060ff604060002054166040519015158152f35b610aab366144ed565b610ab794939294614873565b610ac2333214614714565b836000526006602052610adc60ff60406000205416614785565b836000526005602052610af96003604060002001544210156147d0565b836000526005602052610b15600460406000200154421061481b565b808503610fda578415610f705783600052600560205260ff6001604060002001541615610f62575b610b456148c8565b5060009460005b818110610c8e5786803410610c4a57610b659034614946565b80610b72575b6001600455005b600080808084335af1610b83614953565b5015610bba5760207ff79ba5faa5f6d4317287ca41019cf5d9038d065b41fecbcc6eef3c12e128c8c991604051908152a180610b6b565b60a460405162461bcd60e51b815260206004820152604460248201527f41756374696f6e3a204661696c656420546f205265626174652045786365737360448201527f2045544820546f204269646465722c2052657375626d6974205472616e73616360648201527f74696f6e000000000000000000000000000000000000000000000000000000006084820152fd5b606460405162461bcd60e51b815260206004820152601b60248201527f41756374696f6e3a20496e76616c6964204554482056616c75657300000000006044820152fd5b8560005260076020526040600020610ca7828488614923565b35600052602052604060002060405190610cc082614594565b805482526001810154602083015260028101546040830152600381015491826060820152600482015460808201526001600160a01b03600681600585015416938460a0850152015490811660c083015260ff8160a01c161591821560e082015261012060ff808460a81c161593841561010085015260b01c16151591015281610f5a575b50610d5a575b5050610d5590614914565b610b4c565b9791973303610ef057610d9a90610d7c610d758a8789614923565b3582614866565b90886000526005602052606492839160056040600020015490614933565b0411610e865750610e25610d5591610db3898688614923565b358860005260076020526040600020610dcd8b878b614923565b35600052602052610de76003604060002001918254614866565b90558760005260076020526040600020610e028a868a614923565b3560005260205242600460406000200155610e1e898688614923565b3590614866565b967f30bf27c46d6566e3f9cd7a966890a105a07e7d2f5519293ecbb940595f8c3e8e60a0610e5483868a614923565b35610e6084888a614923565b35604051918b835260208301526040820152426060820152336080820152a19088610d4a565b6084907f6573203e3d20352520496e6372656173650000000000000000000000000000006040519162461bcd60e51b835260206004840152603160248401527f41756374696f6e3a2042696420416d6f756e7420546f707570205265717569726044840152820152fd5b608460405162461bcd60e51b815260206004820152603c60248201527f41756374696f6e3a20606d73672e73656e64657260204973204e6f742054686560448201527f20426964646572204f6620446573697265642042696420496e646578000000006064820152fd5b90508a610d44565b610f6b846150e3565b610b3d565b608460405162461bcd60e51b815260206004820152602960248201527f41756374696f6e3a20557365722048617320496e707574204e6f20426964732060448201527f546f20546f7020557000000000000000000000000000000000000000000000006064820152fd5b608460405162461bcd60e51b815260206004820152603560248201527f41756374696f6e3a20426964496e646578657320416e6420416d6f756e74732060448201527f4172726179204c656e677468204d69736d6174636800000000000000000000006064820152fd5b3461042157602080600319360112610421576004358060005260069182815260026110758160406000200154615360565b9360005b8460005281845282604060002001548110156111445761113f906007855260406000208160005285526040600020604051906110b482614594565b8054825260018101548783015285810154604083015260038101546060830152600481015460808301526001600160a01b0385816005840154169260a093848601520154918291821660c085015260ff9283911c16151560e0840152818160a81c16151561010084015260b01c1615156101208201526111348289614c96565b526108248188614c96565b611079565b6040518481528061040381870189614287565b3461042157602060031936011261042157611170614873565b61117b333214614714565b600435600052600660205260ff60406000205460081c1661197f57600435600052600560205260ff60016040600020015460081c1615611915576004356000526009602052604060002033600052602052604060002054156118ab5760043560005260056020526004604060002001544211156118415760043560005260096020526040600020336000526020526112166040600020614c1a565b6112216004356156cf565b906000916000805b600435600052600960205260406000203360005260205260406000205481101561155957600435600052600760205260406000206112678286614c96565b5160005260205260ff60066040600020015460a81c161580611522575b806114ef575b61129d575b61129890614914565b611229565b90611470611298916004356000526007602052604060002060096020526040600020336000526020526112d4856040600020614539565b90549060031b1c600052602052600660406000200175010000000000000000000000000000000000000000007fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff825416179055600435600052600760205260406000206113418588614c96565b516000526020526006604060002001740100000000000000000000000000000000000000007fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff825416179055600435600052600760205260406000206113a78588614c96565b5160005260205262010f2c600160406000200154146000146114a1576064611469815b600435600052600560205260ff600160406000200154166000146114785760043560005260076020526040600020611402888b614c96565b5160005260205261146361142a60036040600020015485611423858d614933565b0490614946565b600435600052600760205260406000206114448a8d614c96565b5160005260205261145d81600360406000200154614946565b9b614866565b99614933565b0490614866565b91905061128f565b6007602052604060002061148c888b614c96565b51600052602052600360406000200154614933565b600435600052600b60205260646114696114e36040600020600760205260406000206114cd898c614c96565b5160005260205260016040600020015490614539565b90549060031b1c6113ca565b506004356000526007602052604060002061150a8286614c96565b5160005260205282600360406000200154101561128a565b506004356000526007602052604060002061153d8286614c96565b5160005260205260ff60066040600020015460a01c1615611284565b84600080808086730bc56e3c1397e4570069e89c07936a5c6020e3be5af161157f614953565b50156117d75780611776575b5060043560005260056020526001600160a01b03600b604060002001541660005b6004356000526009602052604060002033600052602052604060002054811015610b6b576004356000526007806020526040600020906009602052604060002033600052602052611601836040600020614539565b929054600393841b1c60005260205260ff60066040600020015460a81c1680611726575b61163a575b505061163590614914565b6115ac565b6004356000526020526040600020906009602052604060002033600052602052611668836040600020614539565b9054911b1c60005260205260066040600020017601000000000000000000000000000000000000000000007fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff825416179055813b1561042157604051907f86a4fd730000000000000000000000000000000000000000000000000000000082523360048301526001602483015260008260448183875af191821561083e5761163592611717575b81925061162a565b61172090614580565b8361170f565b506004356000528060205260406000206009602052604060002033600052602052611755846040600020614539565b905490841b1c60005260205260ff60066040600020015460b01c1615611625565b600080808093335af1611787614953565b5015611793578061158b565b606460405162461bcd60e51b815260206004820152601d60248201527f41756374696f6e3a2055736572205769746864726177204661696c65640000006044820152fd5b608460405162461bcd60e51b815260206004820152602160248201527f41756374696f6e3a204d756c7469736967205769746864726177204661696c6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152fd5b608460405162461bcd60e51b815260206004820152603160248201527f41756374696f6e3a2043616e6e6f742046696e616c697a652c2041756374696f60448201527f6e204973205374696c6c204163746976650000000000000000000000000000006064820152fd5b608460405162461bcd60e51b815260206004820152602360248201527f41756374696f6e3a205573657220486173204e6f204269647320546f2053657460448201527f746c6500000000000000000000000000000000000000000000000000000000006064820152fd5b608460405162461bcd60e51b815260206004820152602760248201527f41756374696f6e3a205573657220536574746c656d656e74204973204e6f742060448201527f456e61626c6564000000000000000000000000000000000000000000000000006064820152fd5b608460405162461bcd60e51b815260206004820152602160248201527f41756374696f6e3a204e4654732048617665204265656e20446973706572736560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152fd5b34610421576119f736614362565b90336000526020926003845260ff604060002054168015611b3a575b8015611b21575b611a2390614983565b60005b838110611adb5750600052600b835260406000209067ffffffffffffffff8311611aac57680100000000000000008311611aac578154838355808410611a8f575b5090600052826000209260005b838110611a7d57005b82358582015591810191600101611a74565b611aa6908360005284866000209182019101614a65565b84611a67565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b806064611aec611b03938787614923565b35111580611b08575b611afe90614a7c565b614914565b611a26565b50611afe611b17828787614923565b3515159050611af5565b50611a236001600160a01b036001541633149050611a1a565b506002845260ff60406000205416611a13565b3461042157611b5b36614231565b9033600052600360205260ff604060002054168015611bb4575b8015611b9b575b611b8590614983565b6000526005602052600a60406000200155600080f35b50611b856001600160a01b036001541633149050611b7c565b50600260205260ff60406000205416611b75565b34610421576020600319360112610421576001600160a01b03611be961425d565b166000526002602052602060ff604060002054166040519015158152f35b3461042157611c1536614231565b90600052600b602052604060002080548210156104215760209161045791614539565b3461042157611c4636614231565b906000526007602052604060002090600052602052610140604060002060ff81549160018101549060028101549060038101546004820154906001600160a01b039360068560058601541694015495604051988952602089015260408801526060870152608086015260a0850152811660c0840152818160a01c16151560e0840152818160a81c16151561010084015260b01c161515610120820152f35b3461042157602060031936011261042157611cfd61425d565b6001600160a01b0390611d1582600054163314614ba9565b16600052600260205261061f604060002060ff8154161560ff60ff1983541691151516179055565b3461042157611d4b36614231565b90600052600c602052604060002080548210156104215760209161045791614539565b3461042157604060031936011261042157611d87614247565b33600052600360205260ff604060002054168015611e12575b8015611df9575b611db090614983565b60043560005260056020526001600160a01b03600b60406000200191167fffffffffffffffffffffffff0000000000000000000000000000000000000000825416179055600080f35b50611db06001600160a01b036001541633149050611da7565b50600260205260ff60406000205416611da0565b34610421576000600319360112610421576020600f54604051908152f35b3461042157602060031936011261042157611e5d61425d565b7fffffffffffffffffffffffff0000000000000000000000000000000000000000600054916001600160a01b0390611e983383861614614ba9565b16911617600055600080f35b34610421576020600319360112610421576020611ec2600435615777565b50604051908152f35b346104215760206003193601126104215760043560005260056020526040600020611ef58161466d565b60018201546002830154926003810154906004810154600582015460068301546007840154600885015491600986015493600a870154956001600160a01b0380600b8a01541698600c015416986040519c8d809d6101c08083528201611f5a91614396565b9c60ff81161515602083015260081c60ff161515906040015260608d015260808c015260a08b015260c08a015260e08901526101008801526101208701526101408601526101608501526101808401526101a08301520390f35b3461042157611fc236614231565b9033600052600360205260ff604060002054168015612028575b801561200f575b611fec90614983565b611ff960648310156149f4565b6000526005602052600560406000200155600080f35b50611fec6001600160a01b036001541633149050611fe3565b50600260205260ff60406000205416611fdc565b346104215760206003193601126104215761205561425d565b600154906001600160a01b033381841614801561210a575b156120a0577fffffffffffffffffffffffff00000000000000000000000000000000000000009116911617600155600080f35b608460405162461bcd60e51b815260206004820152603860248201527f4d697373696f6e436f6e74726f6c207c206f6e6c794c61756e6368706164207c60448201527f2043616c6c6572204973204e6f74204c61756e636870616400000000000000006064820152fd5b5033600052600260205260ff6040600020541661206d565b346104215760208060031936011261042157600435336000526003825260ff9182604060002054168015612402575b80156123e9575b61216190614983565b81600052600691828252604060002060ff19815416905561218181614caa565b80600052828252836040600020541661237f57806000528282526121af8460406000205460081c16156151f6565b8060005282825260406000206101007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff8254161790556005908183526001600160a01b039283600b60406000200154169561220983615996565b9260005b845181101561061f57816000526007808552604060002061222e8388614c96565b51600052855283896040600020015460a81c168061234f575b61225b575b5061225690614914565b61220d565b8260005280855260406000206122718388614c96565b516000528552886040600020017601000000000000000000000000000000000000000000007fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff82541617905582600052845260406000206122d28287614c96565b5160005284528686604060002001541690893b15610421576040517f86a4fd73000000000000000000000000000000000000000000000000000000008152600481019290925260016024830152600082604481838e5af191821561083e5761225692612340575b509061224c565b61234990614580565b8a612339565b508260005280855260406000206123668388614c96565b51600052855283896040600020015460b01c1615612247565b6084826040519062461bcd60e51b82526004820152603b60248201527f41756374696f6e3a2041756374696f6e204973205374696c6c2041637469766560448201527f2c204d7573742044697370657273652046756e647320466972737400000000006064820152fd5b506121616001600160a01b036001541633149050612158565b50600281528260406000205416612151565b346104215760206003193601126104215761061f60043533600052600360205260ff604060002054168015612488575b801561246f575b61245490614983565b806000526006602052604060002060ff198154169055614caa565b506124546001600160a01b03600154163314905061244b565b50600260205260ff60406000205416612444565b34610421576003196080813601126104215760043567ffffffffffffffff8111610421576101c0809282360301126104215760405191820182811067ffffffffffffffff821117611aac57604052806004013567ffffffffffffffff8111610421578101366023820112156104215760048101359161251a836145f1565b61252760405191826145ce565b83815236602485850101116104215760006020856125ed9660246101a497018386013783010152845261255c6024820161460d565b602085015261256d6044820161460d565b6040850152606481013560608501526084810135608085015260a481013560a085015260c481013560c085015260e481013560e08501526101048101356101008501526101248101356101208501526101448101356101408501526101648101356101608501526125e16101848201614273565b61018085015201614273565b6101a082015260243567ffffffffffffffff811161042157612613903690600401614331565b9067ffffffffffffffff604435116104215761263436604435600401614331565b9067ffffffffffffffff606435116104215761265536606435600401614331565b94909333600052600360205260ff604060002054168015612bcd575b8015612bb4575b61268190614983565b83821480612bab575b15612b41576126a0606460c089015110156149f4565b600f54968760005260056020526040600020815180519067ffffffffffffffff8211611aac5781906126d2845461461a565b601f8111612b04575b50602090601f8311600114612a9857600092612a8d575b50506000198260011b9260031b1c19161781555b6001810161272760208401511515829060ff60ff1983541691151516179055565b604083015115157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff61ff0083549260081b169116179055606082015160028201556080820151600382015560a0820151600482015560c0820151600582015560e08201516006820155610100820151600782015561012082015160088201556101408201516009820155610160820151600a820155600b8101906101a0600c6001600160a01b03928361018087015116947fffffffffffffffffffffffff0000000000000000000000000000000000000000958682541617905501930151169082541617905586600052600560205260086040600020015460066020526040600020906001820155600160ff19825416179055600b602052604060002067ffffffffffffffff8711611aac57680100000000000000008711611aac578054878255808810612a6f575b50859060005260206000209060005b888110612a5b5750505086600052600c60205260406000209067ffffffffffffffff8311611aac57680100000000000000008311611aac578154838355808410612a31575b5090600052602060002060005b838110612a1d575050505084600052600d60205260406000209067ffffffffffffffff8311611aac57680100000000000000008311611aac5781548383558084106129f4575b5090600052602060002060005b8381106129e05750505050600183018084116129b157600f5560005b82811061297b576020847fa78c547613f6306e7a70d1bd161c18a496cae1eeb8d4f9e58b60d69ad72ddf5882604051838152a1604051908152f35b80606461298c61299d938686614923565b351115806129a257611afe90614a7c565b612940565b50611afe611b17828686614923565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600190602084359401938184015501612924565b8260005283602060002091820191015b818110612a115750612917565b60008155600101612a04565b6001906020843594019381840155016128d1565b826000526020600020908482015b8183018110612a4f5750506128c4565b60008155600101612a3f565b60019060208335930192818501550161287f565b612a8790826000528860206000209182019101614a65565b88612870565b015190508b806126f2565b9250836000526020600020906000935b601f1984168510612ae9576001945083601f19811610612ad0575b505050811b018155612706565b015160001960f88460031b161c191690558b8080612ac3565b81810151835560209485019460019093019290910190612aa8565b612b3190856000526020600020601f850160051c81019160208610612b37575b601f0160051c0190614a65565b8c6126db565b9091508190612b24565b608460405162461bcd60e51b815260206004820152602160248201527f41756374696f6e3a204172726179204c656e67746873204d757374204d61746360448201527f68000000000000000000000000000000000000000000000000000000000000006064820152fd5b5085841461268a565b506126816001600160a01b036001541633149050612678565b50600260205260ff60406000205416612671565b346104215760208060031936011261042157600435612bff816152fa565b816000526005908184526002612c1b81604060002001546152c9565b9260005b856000528187528260406000200154811015612c7057612c6b90600788526040600020612c4c8287614c96565b516000528852600360406000200154612c658288614c96565b52614914565b612c1f565b60405187815280610403818a01886144b9565b346104215760006003193601126104215760206001600160a01b0360015416604051908152f35b346104215760006003193601126104215760206040516d76a84fef008cdabe6409d2fe638b8152f35b3461042157602060031936011261042157610403610a566004356152fa565b3461042157612d003661448f565b9160005260096020526001600160a01b0360406000209116600052602052604060002080548210156104215760209161045791614539565b3461042157600060031936011261042157336000526002602052612d6360ff60406000205416614ac7565b61061f600080808047730bc56e3c1397e4570069e89c07936a5c6020e3be5af1612d8b614953565b50614b38565b3461042157612d9f366144ed565b92336000526020946003865260ff604060002054168015612ee9575b8015612ed0575b612dcb90614983565b80600052600c865260406000209367ffffffffffffffff94858211611aac576801000000000000000093848311611aac578154838355808410612ea8575b50906000528760002060005b838110612e965750505050600052600d85526040600020928411611aac578311611aac578154838355808410612e6e575b5090600052826000209260005b838110612e5c57005b82358582015591810191600101612e53565b82600052838560002091820191015b818110612e8a5750612e46565b60008155600101612e7d565b82358282015591890191600101612e15565b82600052838a60002091820191015b818110612ec45750612e09565b60008155600101612eb7565b50612dcb6001600160a01b036001541633149050612dc2565b506002865260ff60406000205416612dbb565b60a0600319360112610421576044356001600160a01b038116908181036104215767ffffffffffffffff9060643582811161042157612f3f903690600401614331565b91909260843590811161042157612f5a903690600401614331565b929091612f65614873565b612f70333214614714565b6004356000526006602052612f8c60ff60406000205416614785565b6004356000526005602052612fab6003604060002001544210156147d0565b6004356000526005602052612fc9600460406000200154421061481b565b3395806134be575b5050612fde600435615777565b8195913410613454576004356000526006602052600260406000200154600560205260026040600020015411156132b3575b613052955060066020526002604060002001549060086020526040600020906000526020526040600020556130466004356150e3565b85602435600435615501565b906004356000526006602052600260406000200154916040519061307582614594565b838252602082015260243560408201523460608201524260808201523360a08201526001600160a01b03821660c0820152600060e0820152600061010082015260006101208201526004356000526007602052604060002083600052602052600660406000208251815560208301516001820155604083015160028201556060830151600382015560808301516004820155600581016001600160a01b0360a0850151167fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905501906001600160a01b0360c0820151169082549174ff000000000000000000000000000000000000000060e0830151151560a01b16907fffffffffffffffffff000000000000000000000000000000000000000000000076ff0000000000000000000000000000000000000000000061012075ff000000000000000000000000000000000000000000610100870151151560a81b16950151151560b01b16941617171717905560043560005260096020526040600020336000526020526040600020805468010000000000000000811015611aac5761322491600182018155614539565b81549060031b9060001985831b921b191617905560018201918281116129b1576001600160a01b0360c0927f317b5389fd90ccd694f8873c2d07dc6c1c062b7143f1c91e58d48a5bc13afa6e94600435600052600660205260026040600020015560405192600435845260208401523360408401523460608401524260808401521660a0820152a16001600455005b60076020526040600020600860205260406000208260005260205260406000205460005260205260ff60066040600020015460a01c161561330c575b613052956004356000526006602052600160406000200155613010565b600435600090815260076020908152604080832060088352818420858552835281842080548552925280832060060180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000017905590548252812060058101546003909101548291829182916001600160a01b03165af16133a2614953565b501561341057613052956004356000526007602052604060002060086020526040600020836000526020526040600020546000526020527faa017e93278eca5fcf4a3ebb0506b183f3d0c3aa08e9aefaa419061b83341db26020604060002054604051908152a195506132ef565b606460405162461bcd60e51b815260206004820152601860248201527f41756374696f6e3a204b69636b6261636b204661696c656400000000000000006044820152fd5b608460405162461bcd60e51b815260206004820152603f60248201527f41756374696f6e3a2042696420416d6f756e74204d757374204265203e3d204360448201527f757272656e74204c6561646572626f61726420466c6f6f72202a20312e3035006064820152fd5b604051907f9c395bc200000000000000000000000000000000000000000000000000000000825287600483015260248201526020816044816d76a84fef008cdabe6409d2fe638b5afa90811561083e5760009161352a575b50613522575b80612fd1565b94508561351c565b90506020813d60201161355d575b81613545602093836145ce565b81010312610421575180151581036104215787613516565b3d9150613538565b34610421576020600319360112610421576001600160a01b0361358661425d565b166000526003602052602060ff604060002054166040519015158152f35b34610421576135b236614231565b9033600052600360205260ff60406000205416801561360b575b80156135f2575b6135dc90614983565b6000526005602052600960406000200155600080f35b506135dc6001600160a01b0360015416331490506135d3565b50600260205260ff604060002054166135cc565b346104215761362d36614231565b9033600052600360205260ff604060002054168015613686575b801561366d575b61365790614983565b6000526005602052600260406000200155600080f35b506136576001600160a01b03600154163314905061364e565b50600260205260ff60406000205416613647565b34610421576040600319360112610421576136b3614247565b60043560005260096020526001600160a01b0360406000209116600052602052610403610a566040600020614c1a565b34610421576136f13661448f565b91600052600e6020526001600160a01b03604060002091166000526020526040600020906000526020526020604060002054604051908152f35b3461042157604060031936011261042157613744614247565b33600052600360205260ff6040600020541680156137cf575b80156137b6575b61376d90614983565b60043560005260056020526001600160a01b03600c60406000200191167fffffffffffffffffffffffff0000000000000000000000000000000000000000825416179055600080f35b5061376d6001600160a01b036001541633149050613764565b50600260205260ff6040600020541661375d565b34610421576020600319360112610421576104036138026004356153af565b6040519182916020835260208301906143d6565b346104215761382436614362565b61383081939293615360565b9260005b828110613851576040516020808252819061040390820188614287565b6139149084600052602060078152604060002061386f838787614923565b35600052815260406000206040519161388783614594565b815483526001820154908301526002810154604083015260038101546060830152600481015460808301526001600160a01b036006816005840154169260a093848601520154918291821660c085015260ff9283911c16151560e0840152818160a81c16151561010084015260b01c1615156101208201526139098288614c96565b526108248187614c96565b613834565b34610421576000600319360112610421576139406001600160a01b03600054163314614ba9565b61061f600080808047335af1612d8b614953565b346104215760206003193601126104215733600052600360205260ff6040600020541680156139d1575b80156139b8575b61398e90614983565b600435600052600660205261061f604060002060ff8154161560ff60ff1983541691151516179055565b5061398e6001600160a01b036001541633149050613985565b50600260205260ff6040600020541661397e565b34610421576020806003193601126104215760043590336000526003815260ff80604060002054168015613c86575b8015613c6d575b613a2490614983565b82600052600691828152604060002060ff198154169055613a4484614caa565b83600052828152613a5c82604060002054161561515f565b83600052828152604060002054613a7983600892831c16156151f6565b8460005283825260406000206101007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff8254161790556005918281526001600160a01b039384600b60406000200154169660005b8160005285845260026040600020015481101561061f57600780855260406000208686526040600020836000528652604060002054600052855283896040600020015460a81c1680613c34575b613b2e575b50613b2990614914565b613acd565b82600052808552604060002086865260406000208360005286526040600020546000528552886040600020017601000000000000000000000000000000000000000000007fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff8254161790558260005284526040600020858552604060002082600052855260406000205460005284528686604060002001541690893b15610421576040517f86a4fd73000000000000000000000000000000000000000000000000000000008152600481019290925260016024830152600082604481838e5af191821561083e57613b2992613c25575b5090613b1f565b613c2e90614580565b8a613c1e565b508260005280855260406000208686526040600020836000528652604060002054600052855283896040600020015460b01c1615613b1a565b50613a246001600160a01b036001541633149050613a1b565b50600282528060406000205416613a14565b3461042157602060031936011261042157610403613cb76004356158aa565b604051918291602083526020830190614287565b3461042157613cd936614231565b9060005260086020526040600020906000526020526020604060002054604051908152f35b3461042157604060031936011261042157600435613d1a614247565b908060005260206009815260406000206001600160a01b038094166000528152613d476040600020614c1a565b92613d528451615360565b9360005b815181101561114457613e0c9085600052600785526040600020613d7a8285614c96565b516000528552604060002060405190613d9282614594565b805482526001810154878301526002810154604083015260038101546060830152600481015460808301526006866005830154169160a092838501520154809187821660c085015260ff9283911c16151560e0840152818160a81c16151561010084015260b01c1615156101208201526111348289614c96565b613d56565b3461042157613e1f36614231565b9033600052600360205260ff604060002054168015613e78575b8015613e5f575b613e4990614983565b6000526005602052600360406000200155600080f35b50613e496001600160a01b036001541633149050613e40565b50600260205260ff60406000205416613e39565b346104215760208060031936011261042157600435336000526003825260ff91826040600020541680156141a4575b801561418b575b613ecb90614983565b81600052600690818152604060002060ff198154169055613eeb83614caa565b82600052818152613f0384604060002054161561515f565b82600052818152613f1e8460406000205460081c16156151f6565b82600052600580825260019384600a604060002001541115614121578060005283835260406000206101007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff8254161790558183526001600160a01b039283600b604060002001541696613f9183615996565b9280600052848352600a6040600020015496886000905b613fae57005b855181101561061f578260005260078086526040600020613fcf8389614c96565b51600052865284836040600020015460a81c16806140f1575b613ffd575b50613ff790614914565b89613fa8565b8360005280865260406000206140138389614c96565b516000528652826040600020017601000000000000000000000000000000000000000000007fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff82541617905583600052855260406000206140748288614c96565b51600052855287876040600020015416908b3b156104215760008a60448e948360405196879485937f86a4fd73000000000000000000000000000000000000000000000000000000008552600485015260248401525af191821561083e57613ff7926140e2575b5090613fed565b6140eb90614580565b8c6140db565b508360005280865260406000206141088389614c96565b51600052865284836040600020015460b01c1615613fe8565b6084836040519062461bcd60e51b82526004820152602560248201527f41756374696f6e3a204d696e74205061636b20416d6f756e74204d757374204260448201527f65203e20310000000000000000000000000000000000000000000000000000006064820152fd5b50613ecb6001600160a01b036001541633149050613ec2565b50600281528260406000205416613ebb565b34610421576141c436614231565b9033600052600360205260ff60406000205416801561421d575b8015614204575b6141ee90614983565b6000526005602052600760406000200155600080f35b506141ee6001600160a01b0360015416331490506141e5565b50600260205260ff604060002054166141de565b6003196040910112610421576004359060243590565b602435906001600160a01b038216820361042157565b600435906001600160a01b038216820361042157565b35906001600160a01b038216820361042157565b90815180825260208080930193019160005b8281106142a7575050505090565b835180518652808301518684015260408082015190870152606080820151908701526080808201519087015260a0808201516001600160a01b039081169188019190915260c0808301519091169087015260e08082015115159087015261010080820151151590870152610120908101511515908601526101409094019392810192600101614299565b9181601f840112156104215782359167ffffffffffffffff8311610421576020808501948460051b01011161042157565b90604060031983011261042157600435916024359067ffffffffffffffff82116104215761439291600401614331565b9091565b919082519283825260005b8481106143c2575050601f19601f8460006020809697860101520116010190565b6020818301810151848301820152016143a1565b906143ea82516101e0808452830190614396565b916020810151151560208301526040810151151560408301526060810151151560608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e0830152610100808201519083015261012080820151908301526101408082015190830152610160808201519083015261018080820151908301526101a080820151908301526001600160a01b036101c0809201511691015290565b600319606091011261042157600435906024356001600160a01b0381168103610421579060443590565b90815180825260208080930193019160005b8281106144d9575050505090565b8351855293810193928101926001016144cb565b906060600319830112610421576004359167ffffffffffffffff91602435838111610421578261451f91600401614331565b939093926044359182116104215761439291600401614331565b80548210156145515760005260206000200190600090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b67ffffffffffffffff8111611aac57604052565b610140810190811067ffffffffffffffff821117611aac57604052565b6101e0810190811067ffffffffffffffff821117611aac57604052565b90601f601f19910116810190811067ffffffffffffffff821117611aac57604052565b67ffffffffffffffff8111611aac57601f01601f191660200190565b3590811515820361042157565b90600182811c92168015614663575b602083101461463457565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b91607f1691614629565b90604051918260008254926146818461461a565b9081845260019485811690816000146146f057506001146146ad575b50506146ab925003836145ce565b565b9093915060005260209081600020936000915b8183106146d85750506146ab9350820101388061469d565b855488840185015294850194879450918301916146c0565b90506146ab95506020935060ff1991501682840152151560051b820101388061469d565b1561471b57565b608460405162461bcd60e51b815260206004820152603c60248201527f41756374696f6e3a20454f41204f6e6c792c20557365206064656c656761746560448201527f2e636173686020466f722057616c6c65742044656c65676174696f6e000000006064820152fd5b1561478c57565b606460405162461bcd60e51b815260206004820152601e60248201527f41756374696f6e3a2041756374696f6e204973204e6f742041637469766500006044820152fd5b156147d757565b606460405162461bcd60e51b815260206004820152602060248201527f41756374696f6e3a2041756374696f6e20486173204e6f7420537461727465646044820152fd5b1561482257565b606460405162461bcd60e51b815260206004820152601e60248201527f41756374696f6e3a2041756374696f6e2048617320436f6e636c7564656400006044820152fd5b919082018092116129b157565b600260045414614884576002600455565b606460405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b604051906148d582614594565b816101206000918281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e0820152826101008201520152565b60001981146129b15760010190565b91908110156145515760051b0190565b818102929181159184041417156129b157565b919082039182116129b157565b3d1561497e573d90614964826145f1565b9161497260405193846145ce565b82523d6000602084013e565b606090565b1561498a57565b608460405162461bcd60e51b815260206004820152603f60248201527f4d697373696f6e436f6e74726f6c207c206f6e6c794f70657261746f72207c2060448201527f43616c6c6572204973204e6f74204f70657261746f72204f722041646d696e006064820152fd5b156149fb57565b608460405162461bcd60e51b815260206004820152602d60248201527f41756374696f6e3a204d696e696d756d204249505320496e637265617365204d60448201527f757374204265203e3d20313030000000000000000000000000000000000000006064820152fd5b818110614a70575050565b60008155600101614a65565b15614a8357565b606460405162461bcd60e51b815260206004820152601860248201527f496e76616c696420446973636f756e7420416d6f756e747300000000000000006044820152fd5b15614ace57565b608460405162461bcd60e51b815260206004820152603060248201527f4d697373696f6e436f6e74726f6c207c206f6e6c7941646d696e207c2043616c60448201527f6c6572204973204e6f742041646d696e000000000000000000000000000000006064820152fd5b15614b3f57565b608460405162461bcd60e51b815260206004820152602f60248201527f556e61626c6520746f2057697468647261772c20526563697069656e74204d6160448201527f79204861766520526576657274656400000000000000000000000000000000006064820152fd5b15614bb057565b608460405162461bcd60e51b815260206004820152603060248201527f4d697373696f6e436f6e74726f6c207c206f6e6c794f776e6572207c2043616c60448201527f6c6572204973204e6f74204f776e6572000000000000000000000000000000006064820152fd5b9060405191828154918282526020928383019160005283600020936000905b828210614c4f575050506146ab925003836145ce565b855484526001958601958895509381019390910190614c39565b8051156145515760200190565b8051600110156145515760400190565b8051600210156145515760600190565b80518210156145515760209160051b010190565b60009080825260056020818152600293604090858282200154936006948585528784842001548091116150d4575b508197614ce4876156cf565b90835b88855283875289868620015481101561500c576007808852868620600890818a528888208489528a52888820548852895260ff91828b8a8a20015460a01c161580614fde575b80614fb2575b614d49575b505050614d4490614914565b614ce7565b8689859f95938c8f96958f958d96898852818452858820858552868920848a5285528689205489528452808689200175010000000000000000000000000000000000000000007fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff825416179055898852818452858820858552868920848a528552868920548952845285882001740100000000000000000000000000000000000000007fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff8254161790558887528083528487208484528588208389528452858820548852835260018c81878a200154998b8a52838652878a20878752888b20868c528752888b20548b52865260038c818a8d2001549c62010f2c8114600014614f95575050506064925b8c8b52898752888b2001541615614f7f57614e93614e9a92606492614933565b0489614946565b985b89614eca575b505050505050505091614ebb614ec192614d4494614946565b90614866565b9a903880614d38565b875282528386209282528386209086528152828520548552528220015481908190819086906001600160a01b03165af1614f02614953565b5015614f16578686898f8c8f388391614ea2565b60848989519062461bcd60e51b82526004820152603e60248201527f41756374696f6e3a204661696c656420546f205265626174652045544820546f60448201527f204269646465722c20557365204661696c7361666520576974686472617700006064820152fd5b506064614e93614f8f928b614933565b98614e9c565b614fa7918d52600b89528a8d20614539565b9054911b1c92614e73565b508b8852808a52888820828b52898920858a528b528989205489528a528560038a8a2001541015614d33565b508b8852808a52888820828b52898920858a528b528989205489528a52828b8a8a20015460a81c1615614d2d565b50989150508194508193965081929550730bc56e3c1397e4570069e89c07936a5c6020e3be5af161503b614953565b5015615045575050565b60a49250519062461bcd60e51b82526004820152604860248201527f41756374696f6e3a2041646d696e204661696c656420546f205769746864726160448201527f772045544820546f204d756c74697369672c20557365204661696c736166652060648201527f57697468647261770000000000000000000000000000000000000000000000006084820152fd5b81855287848420015538614cd8565b600081815260056020526150ff60046040832001544290614946565b918082526005602052604082209260078401541161511c57505050565b61514b60067fab9c9a8aeadcc64e09e3ec376616fdcd4dd4a5e728535b290e272c2f1792056f94015442614866565b9082526005602052600460408320015580a1565b1561516657565b60a460405162461bcd60e51b815260206004820152604e60248201527f41756374696f6e3a2041756374696f6e204973205374696c6c2041637469766560448201527f2c204d7573742044697370657273652046756e647320262046696e616c697a6560648201527f2041756374696f6e2046697273740000000000000000000000000000000000006084820152fd5b156151fd57565b606460405162461bcd60e51b815260206004820152601f60248201527f41756374696f6e3a204e46547320416c726561647920446973706572736564006044820152fd5b6040519061524e826145b1565b81606081526101c06000918260208201528260408201528260608201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201528261016082015282610180820152826101a08201520152565b67ffffffffffffffff8111611aac5760051b60200190565b906152d3826152b1565b6152e060405191826145ce565b828152601f196152f082946152b1565b0190602036910137565b6000818152600590602082815260029460409561531b8188862001546152c9565b94845b8786528185528289872001548110156153545761534f9060088652898720818852865289872054612c65828a614c96565b61531e565b50505094505050905090565b9061536a826152b1565b61537760405191826145ce565b828152601f1961538782946152b1565b019060005b82811061539857505050565b6020906153a36148c8565b8282850101520161538c565b6153b7615241565b506000908152600560205260408082209160066020528181205492600560205282822091600183015460ff1692600281015490600381015490600481015460058201549060068301549260070154936006602052898720958a60018801549760020154986005602052209960098b015499600a8c01549b600b01546001600160a01b03169c80519e8f9261544a846145b1565b6154539061466d565b835260ff81161515602084015260081c60ff161515910152151560608d015260808c015260a08b015260c08a015260e08901526101008801526101208701526101408601526101608501526101808401526101a08301526101c082015290565b92916154be826152b1565b916154cc60405193846145ce565b829481845260208094019160051b810192831161042157905b8282106154f25750505050565b813581529083019083016154e5565b95919092949395604094855191602097888401917fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606096871b1692838152601486528986019567ffffffffffffffff9681811088821117611aac578b525190209a60005b82600052600b8c528a6000205481101561565e578c6155aa615591838f8f90600c9052600020614539565b929054600393841b1c6155a536878a6154b3565b615672565b6155bd57506155b890614914565b615566565b93509b5050600052600d89526155d68a89600020614539565b9054911b1c9387519689880192835260349081890152875286019286841090841117611aac57615611956155a59388525190209336916154b3565b1561561b57505090565b60649250519062461bcd60e51b82526004820152601e60248201527f41756374696f6e3a20496e76616c6964204d65726b6c6520416d6f756e7400006044820152fd5b5050505050505050505050505062010f2c90565b929091906000915b84518310156156c75761568d8386614c96565b51906000828210156156b557506000526020526156af60406000205b92614914565b9161567a565b6040916156af938252602052206156a9565b915092501490565b60001960005b826000526020600581526040600281600020015483101561576f5760079182815281600020906008918282528360002086600052825283600020546000528152600393868585600020015410615739575b505050505061573490614914565b6156d5565b61573495965087600052815282600020918152826000208660005281528260002054600052526000200154919038808080615726565b505050905090565b90615781826157fc565b9160009080825260209160068352604091600283832001546005855260028484200154116000146157bc576001936006918352522001549190565b906157f7926005918286600760649852838320600882528484208b855282528484205484528152600384842001549583525220015490614933565b049190565b600019600092828452602090600682526002946040958087832001546005908186528289852001541161589957825b876000528186528289600020015481101561588d576007865288600020600887528960002082600052875289600020546000528652600389600020015487811115615880575b5061587b90614914565b61582b565b965092508261587b615871565b50505093509350505090565b509450916006919593505220015490565b6158b381615996565b6158bd8151615360565b9160005b82518110156159905761598b90826000526020600781526040806000206158e88488614c96565b51600052825280600020908051926158ff84614594565b8254845260018301549084015260028201549083015260038101546060830152600481015460808301526001600160a01b036006816005840154169260a093848601520154918291821660c085015260ff9283911c16151560e0840152818160a81c16151561010084015260b01c1615156101208201526159808287614c96565b526108248186614c96565b6158c1565b50505090565b90600091808352602090600682526040936002858181842001549260058652200154809110600014615d3f5750600682526002846000200154915b6159da836152b1565b926159e7865194856145ce565b808452601f196159f6826152b1565b018260005b828110615d2f5750505060005b8451811015615b0257865190608082019180831067ffffffffffffffff841117611aac57615afd92895260039081815260603687830137615a498389614c96565b52615a548288614c96565b5085600052600780865289600020916008928388528b6000208560005288528b6000205460005287528a6000200154615a96615a90858b614c96565b51614c69565b5286600052818652896000208360005286528960002054615ac0615aba858b614c96565b51614c76565b528660005285528860002090855288600020826000528552886000205460005284526004886000200154612c65615af78389614c96565b51614c86565b615a08565b509450505060005b8151811015615cdb57615b20615a908284614c96565b51615b2e615aba8385614c96565b5194615b3d615af78486614c96565b5194835b8015801580615cb8575b15615ca157600019820191808311806129b15786615b6c615a90868c614c96565b511480615c88575b818115615c4d575b50615c0d576129b157615b92615a90848a614c96565b51615ba0615a90838b614c96565b52615bae615aba848a614c96565b51615bbc615aba838b614c96565b52615bd8615af7615bd0615af7868c614c96565b51928a614c96565b5215615b41577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b509050615af79150612c659296979398615c4596955b615c30615a90848c614c96565b52615c3e615aba838b614c96565b5287614c96565b919091615b0a565b90506129b15786615c61615a90868c614c96565b511480615c6f575b81615b7c565b5050600089615c81615af7868c614c96565b5111615c69565b505060008a615c9a615aba868c614c96565b5111615b74565b50615af790612c659296979398615c459695615c23565b5060001982018281116129b157615cd3615a9087928a614c96565b511015615b4b565b5091615ce6816152c9565b9260005b8151811015615d2a57615d00615aba8284614c96565b51906000198401918483116129b157612c65615d1f83615d2595614946565b88614c96565b615cea565b505050565b60608282890101520183906159fb565b916159d156fea2646970667358221220e8f091550448b62da430ae76e677b92e5425287ecc97fd269e78cb09d3a937d464736f6c63430008130033

Deployed Bytecode

0x6080604052600436101561001257600080fd5b60003560e01c8063041c1f14146141b6578063068035a514613e8c57806306c5bb9914613e115780630794736b14613cfe5780630b5d7bf014613ccb5780630b62209014613c985780630d5e64df146139e557806311ca8f3914613954578063185176cb146139195780631a3ec25b146138165780631aea2a9d146137e35780631b512f171461372b578063228dd2b5146136e357806325dd75f21461369a5780632d46c6a11461361f5780634bc54449146135a45780634c9016a0146135655780634e3b98bb14612efc57806356769c4614612d915780635928b66614612d3857806362a22e8914612cf257806368b4b7a014612cd35780636a95cc0814612caa578063765b8b5114612c83578063767b572314612be157806379005b301461249c57806379aa43f6146124145780637c04530d146121225780637df92fd11461203c578063824be6a214611fb45780638ee4855914611ecb578063906b1c9f14611ea4578063991c6f5914611e445780639ae9181714611e265780639d9d862314611d6e5780639eca8f6914611d3d578063a3e40def14611ce4578063a7f323da14611c38578063b009b55a14611c07578063b202367a14611bc8578063b451abcc14611b4d578063b4be58cb146119e9578063b538a8fa14611157578063b69dab3b14611044578063ca858d7a14610aa2578063cff9ebfb14610a6a578063d7470b1514610a2a578063d783f4eb146109af578063d7b50c3614610988578063d8fee6d514610925578063debdbe031461064e578063e07c41af146105b0578063e18aff4e14610535578063e30814af146104ba578063ead82d5314610465578063f480f4a0146104265763fe8778d81461028f57600080fd5b34610421576040600319360112610421576004356102ab614247565b6102b3615241565b506102bd826156cf565b906102c7836158aa565b5082600052602092600584528360646102e860056040600020015486614933565b049282600052600682526002604060002001546005835260026040600020015411610407575b916103e76103f5926103d961040396956103cb61032a866153af565b91610334876158aa565b9087600052600986526001600160a01b03604060002091166000528552604060002096600052600b85526103bd604060002093600c8752600d6040600020975261039d61039761039161038b60406000209c614c1a565b97614c1a565b98614c1a565b99614c1a565b9a6040519e8f9e8f908152015260408d61010091829101528d01906143d6565b908b820360608d0152614287565b9089820360808b01526144b9565b9087820360a08901526144b9565b9085820360c08701526144b9565b9083820360e08501526144b9565b0390f35b60069091526040600020600101549350839250849061030e565b600080fd5b346104215761043436614231565b90600052600d602052604060002080548210156104215760209161045791614539565b90546040519160031b1c8152f35b3461042157602060031936011261042157600435600052600660205260806040600020805490600260018201549101549060ff604051938181161515855260081c161515602084015260408301526060820152f35b34610421576104c836614231565b9033600052600360205260ff604060002054168015610521575b8015610508575b6104f290614983565b6000526005602052600660406000200155600080f35b506104f26001600160a01b0360015416331490506104e9565b50600260205260ff604060002054166104e2565b346104215761054336614231565b9033600052600360205260ff60406000205416801561059c575b8015610583575b61056d90614983565b6000526005602052600460406000200155600080f35b5061056d6001600160a01b036001541633149050610564565b50600260205260ff6040600020541661055d565b346104215760406003193601126104215760243580151581036104215761061f9033600052600360205260ff60406000205416801561063a575b8015610621575b6105fa90614983565b600435600052600560205260016040600020019060ff60ff1983541691151516179055565b005b506105fa6001600160a01b0360015416331490506105f1565b50600260205260ff604060002054166105ea565b346104215761065c36614362565b909133600052600360205260ff604060002054168015610911575b80156108f8575b61068790614983565b806000526006602052604060002060ff1981541690556106a681614caa565b8060005260066020526106c160ff604060002054161561515f565b8060005260066020526106df60ff60406000205460081c16156151f6565b806000526005602052600260406000200154820361088e5761070081615996565b928160005260056020526040600020916001600160a01b03600b81600c86015416940154169460005b85811061073257005b82600052600a80602052604060002061074c838988614923565b3560005260205260ff6040600020541661084a57836000526020526040600020610777828887614923565b356000526020526040600020600160ff1982541617905582600052600760205260406000206107a68284614c96565b516000526020526001600160a01b0360056040600020015416906107cb818887614923565b35883b1561042157604051927f23b872dd00000000000000000000000000000000000000000000000000000000845287600485015260248401526044830152600082606481838c5af191821561083e5761082a9261082f575b50614914565b610729565b61083890614580565b88610824565b6040513d6000823e3d90fd5b606460405162461bcd60e51b815260206004820152601d60248201527f41756374696f6e3a20546f6b656e494420416c72656164792053656e740000006044820152fd5b608460405162461bcd60e51b815260206004820152603a60248201527f41756374696f6e3a20546f6b656e494473204172726179204c656e677468204d60448201527f757374204d61746368204c6561646572626f6172642053697a650000000000006064820152fd5b506106876001600160a01b03600154163314905061067e565b50600260205260ff60406000205416610677565b34610421576020600319360112610421576001600160a01b0361094661425d565b33600052600260205261096060ff60406000205416614ac7565b16600052600360205261061f604060002060ff8154161560ff60ff1983541691151516179055565b346104215760006003193601126104215760206001600160a01b0360005416604051908152f35b34610421576109bd36614231565b9033600052600360205260ff604060002054168015610a16575b80156109fd575b6109e790614983565b6000526006602052600160406000200155600080f35b506109e76001600160a01b0360015416331490506109de565b50600260205260ff604060002054166109d7565b3461042157602060031936011261042157600435600052600c602052610403610a566040600020614c1a565b6040519182916020835260208301906144b9565b3461042157610a7836614231565b90600052600a602052604060002090600052602052602060ff604060002054166040519015158152f35b610aab366144ed565b610ab794939294614873565b610ac2333214614714565b836000526006602052610adc60ff60406000205416614785565b836000526005602052610af96003604060002001544210156147d0565b836000526005602052610b15600460406000200154421061481b565b808503610fda578415610f705783600052600560205260ff6001604060002001541615610f62575b610b456148c8565b5060009460005b818110610c8e5786803410610c4a57610b659034614946565b80610b72575b6001600455005b600080808084335af1610b83614953565b5015610bba5760207ff79ba5faa5f6d4317287ca41019cf5d9038d065b41fecbcc6eef3c12e128c8c991604051908152a180610b6b565b60a460405162461bcd60e51b815260206004820152604460248201527f41756374696f6e3a204661696c656420546f205265626174652045786365737360448201527f2045544820546f204269646465722c2052657375626d6974205472616e73616360648201527f74696f6e000000000000000000000000000000000000000000000000000000006084820152fd5b606460405162461bcd60e51b815260206004820152601b60248201527f41756374696f6e3a20496e76616c6964204554482056616c75657300000000006044820152fd5b8560005260076020526040600020610ca7828488614923565b35600052602052604060002060405190610cc082614594565b805482526001810154602083015260028101546040830152600381015491826060820152600482015460808201526001600160a01b03600681600585015416938460a0850152015490811660c083015260ff8160a01c161591821560e082015261012060ff808460a81c161593841561010085015260b01c16151591015281610f5a575b50610d5a575b5050610d5590614914565b610b4c565b9791973303610ef057610d9a90610d7c610d758a8789614923565b3582614866565b90886000526005602052606492839160056040600020015490614933565b0411610e865750610e25610d5591610db3898688614923565b358860005260076020526040600020610dcd8b878b614923565b35600052602052610de76003604060002001918254614866565b90558760005260076020526040600020610e028a868a614923565b3560005260205242600460406000200155610e1e898688614923565b3590614866565b967f30bf27c46d6566e3f9cd7a966890a105a07e7d2f5519293ecbb940595f8c3e8e60a0610e5483868a614923565b35610e6084888a614923565b35604051918b835260208301526040820152426060820152336080820152a19088610d4a565b6084907f6573203e3d20352520496e6372656173650000000000000000000000000000006040519162461bcd60e51b835260206004840152603160248401527f41756374696f6e3a2042696420416d6f756e7420546f707570205265717569726044840152820152fd5b608460405162461bcd60e51b815260206004820152603c60248201527f41756374696f6e3a20606d73672e73656e64657260204973204e6f742054686560448201527f20426964646572204f6620446573697265642042696420496e646578000000006064820152fd5b90508a610d44565b610f6b846150e3565b610b3d565b608460405162461bcd60e51b815260206004820152602960248201527f41756374696f6e3a20557365722048617320496e707574204e6f20426964732060448201527f546f20546f7020557000000000000000000000000000000000000000000000006064820152fd5b608460405162461bcd60e51b815260206004820152603560248201527f41756374696f6e3a20426964496e646578657320416e6420416d6f756e74732060448201527f4172726179204c656e677468204d69736d6174636800000000000000000000006064820152fd5b3461042157602080600319360112610421576004358060005260069182815260026110758160406000200154615360565b9360005b8460005281845282604060002001548110156111445761113f906007855260406000208160005285526040600020604051906110b482614594565b8054825260018101548783015285810154604083015260038101546060830152600481015460808301526001600160a01b0385816005840154169260a093848601520154918291821660c085015260ff9283911c16151560e0840152818160a81c16151561010084015260b01c1615156101208201526111348289614c96565b526108248188614c96565b611079565b6040518481528061040381870189614287565b3461042157602060031936011261042157611170614873565b61117b333214614714565b600435600052600660205260ff60406000205460081c1661197f57600435600052600560205260ff60016040600020015460081c1615611915576004356000526009602052604060002033600052602052604060002054156118ab5760043560005260056020526004604060002001544211156118415760043560005260096020526040600020336000526020526112166040600020614c1a565b6112216004356156cf565b906000916000805b600435600052600960205260406000203360005260205260406000205481101561155957600435600052600760205260406000206112678286614c96565b5160005260205260ff60066040600020015460a81c161580611522575b806114ef575b61129d575b61129890614914565b611229565b90611470611298916004356000526007602052604060002060096020526040600020336000526020526112d4856040600020614539565b90549060031b1c600052602052600660406000200175010000000000000000000000000000000000000000007fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff825416179055600435600052600760205260406000206113418588614c96565b516000526020526006604060002001740100000000000000000000000000000000000000007fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff825416179055600435600052600760205260406000206113a78588614c96565b5160005260205262010f2c600160406000200154146000146114a1576064611469815b600435600052600560205260ff600160406000200154166000146114785760043560005260076020526040600020611402888b614c96565b5160005260205261146361142a60036040600020015485611423858d614933565b0490614946565b600435600052600760205260406000206114448a8d614c96565b5160005260205261145d81600360406000200154614946565b9b614866565b99614933565b0490614866565b91905061128f565b6007602052604060002061148c888b614c96565b51600052602052600360406000200154614933565b600435600052600b60205260646114696114e36040600020600760205260406000206114cd898c614c96565b5160005260205260016040600020015490614539565b90549060031b1c6113ca565b506004356000526007602052604060002061150a8286614c96565b5160005260205282600360406000200154101561128a565b506004356000526007602052604060002061153d8286614c96565b5160005260205260ff60066040600020015460a01c1615611284565b84600080808086730bc56e3c1397e4570069e89c07936a5c6020e3be5af161157f614953565b50156117d75780611776575b5060043560005260056020526001600160a01b03600b604060002001541660005b6004356000526009602052604060002033600052602052604060002054811015610b6b576004356000526007806020526040600020906009602052604060002033600052602052611601836040600020614539565b929054600393841b1c60005260205260ff60066040600020015460a81c1680611726575b61163a575b505061163590614914565b6115ac565b6004356000526020526040600020906009602052604060002033600052602052611668836040600020614539565b9054911b1c60005260205260066040600020017601000000000000000000000000000000000000000000007fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff825416179055813b1561042157604051907f86a4fd730000000000000000000000000000000000000000000000000000000082523360048301526001602483015260008260448183875af191821561083e5761163592611717575b81925061162a565b61172090614580565b8361170f565b506004356000528060205260406000206009602052604060002033600052602052611755846040600020614539565b905490841b1c60005260205260ff60066040600020015460b01c1615611625565b600080808093335af1611787614953565b5015611793578061158b565b606460405162461bcd60e51b815260206004820152601d60248201527f41756374696f6e3a2055736572205769746864726177204661696c65640000006044820152fd5b608460405162461bcd60e51b815260206004820152602160248201527f41756374696f6e3a204d756c7469736967205769746864726177204661696c6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152fd5b608460405162461bcd60e51b815260206004820152603160248201527f41756374696f6e3a2043616e6e6f742046696e616c697a652c2041756374696f60448201527f6e204973205374696c6c204163746976650000000000000000000000000000006064820152fd5b608460405162461bcd60e51b815260206004820152602360248201527f41756374696f6e3a205573657220486173204e6f204269647320546f2053657460448201527f746c6500000000000000000000000000000000000000000000000000000000006064820152fd5b608460405162461bcd60e51b815260206004820152602760248201527f41756374696f6e3a205573657220536574746c656d656e74204973204e6f742060448201527f456e61626c6564000000000000000000000000000000000000000000000000006064820152fd5b608460405162461bcd60e51b815260206004820152602160248201527f41756374696f6e3a204e4654732048617665204265656e20446973706572736560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152fd5b34610421576119f736614362565b90336000526020926003845260ff604060002054168015611b3a575b8015611b21575b611a2390614983565b60005b838110611adb5750600052600b835260406000209067ffffffffffffffff8311611aac57680100000000000000008311611aac578154838355808410611a8f575b5090600052826000209260005b838110611a7d57005b82358582015591810191600101611a74565b611aa6908360005284866000209182019101614a65565b84611a67565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b806064611aec611b03938787614923565b35111580611b08575b611afe90614a7c565b614914565b611a26565b50611afe611b17828787614923565b3515159050611af5565b50611a236001600160a01b036001541633149050611a1a565b506002845260ff60406000205416611a13565b3461042157611b5b36614231565b9033600052600360205260ff604060002054168015611bb4575b8015611b9b575b611b8590614983565b6000526005602052600a60406000200155600080f35b50611b856001600160a01b036001541633149050611b7c565b50600260205260ff60406000205416611b75565b34610421576020600319360112610421576001600160a01b03611be961425d565b166000526002602052602060ff604060002054166040519015158152f35b3461042157611c1536614231565b90600052600b602052604060002080548210156104215760209161045791614539565b3461042157611c4636614231565b906000526007602052604060002090600052602052610140604060002060ff81549160018101549060028101549060038101546004820154906001600160a01b039360068560058601541694015495604051988952602089015260408801526060870152608086015260a0850152811660c0840152818160a01c16151560e0840152818160a81c16151561010084015260b01c161515610120820152f35b3461042157602060031936011261042157611cfd61425d565b6001600160a01b0390611d1582600054163314614ba9565b16600052600260205261061f604060002060ff8154161560ff60ff1983541691151516179055565b3461042157611d4b36614231565b90600052600c602052604060002080548210156104215760209161045791614539565b3461042157604060031936011261042157611d87614247565b33600052600360205260ff604060002054168015611e12575b8015611df9575b611db090614983565b60043560005260056020526001600160a01b03600b60406000200191167fffffffffffffffffffffffff0000000000000000000000000000000000000000825416179055600080f35b50611db06001600160a01b036001541633149050611da7565b50600260205260ff60406000205416611da0565b34610421576000600319360112610421576020600f54604051908152f35b3461042157602060031936011261042157611e5d61425d565b7fffffffffffffffffffffffff0000000000000000000000000000000000000000600054916001600160a01b0390611e983383861614614ba9565b16911617600055600080f35b34610421576020600319360112610421576020611ec2600435615777565b50604051908152f35b346104215760206003193601126104215760043560005260056020526040600020611ef58161466d565b60018201546002830154926003810154906004810154600582015460068301546007840154600885015491600986015493600a870154956001600160a01b0380600b8a01541698600c015416986040519c8d809d6101c08083528201611f5a91614396565b9c60ff81161515602083015260081c60ff161515906040015260608d015260808c015260a08b015260c08a015260e08901526101008801526101208701526101408601526101608501526101808401526101a08301520390f35b3461042157611fc236614231565b9033600052600360205260ff604060002054168015612028575b801561200f575b611fec90614983565b611ff960648310156149f4565b6000526005602052600560406000200155600080f35b50611fec6001600160a01b036001541633149050611fe3565b50600260205260ff60406000205416611fdc565b346104215760206003193601126104215761205561425d565b600154906001600160a01b033381841614801561210a575b156120a0577fffffffffffffffffffffffff00000000000000000000000000000000000000009116911617600155600080f35b608460405162461bcd60e51b815260206004820152603860248201527f4d697373696f6e436f6e74726f6c207c206f6e6c794c61756e6368706164207c60448201527f2043616c6c6572204973204e6f74204c61756e636870616400000000000000006064820152fd5b5033600052600260205260ff6040600020541661206d565b346104215760208060031936011261042157600435336000526003825260ff9182604060002054168015612402575b80156123e9575b61216190614983565b81600052600691828252604060002060ff19815416905561218181614caa565b80600052828252836040600020541661237f57806000528282526121af8460406000205460081c16156151f6565b8060005282825260406000206101007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff8254161790556005908183526001600160a01b039283600b60406000200154169561220983615996565b9260005b845181101561061f57816000526007808552604060002061222e8388614c96565b51600052855283896040600020015460a81c168061234f575b61225b575b5061225690614914565b61220d565b8260005280855260406000206122718388614c96565b516000528552886040600020017601000000000000000000000000000000000000000000007fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff82541617905582600052845260406000206122d28287614c96565b5160005284528686604060002001541690893b15610421576040517f86a4fd73000000000000000000000000000000000000000000000000000000008152600481019290925260016024830152600082604481838e5af191821561083e5761225692612340575b509061224c565b61234990614580565b8a612339565b508260005280855260406000206123668388614c96565b51600052855283896040600020015460b01c1615612247565b6084826040519062461bcd60e51b82526004820152603b60248201527f41756374696f6e3a2041756374696f6e204973205374696c6c2041637469766560448201527f2c204d7573742044697370657273652046756e647320466972737400000000006064820152fd5b506121616001600160a01b036001541633149050612158565b50600281528260406000205416612151565b346104215760206003193601126104215761061f60043533600052600360205260ff604060002054168015612488575b801561246f575b61245490614983565b806000526006602052604060002060ff198154169055614caa565b506124546001600160a01b03600154163314905061244b565b50600260205260ff60406000205416612444565b34610421576003196080813601126104215760043567ffffffffffffffff8111610421576101c0809282360301126104215760405191820182811067ffffffffffffffff821117611aac57604052806004013567ffffffffffffffff8111610421578101366023820112156104215760048101359161251a836145f1565b61252760405191826145ce565b83815236602485850101116104215760006020856125ed9660246101a497018386013783010152845261255c6024820161460d565b602085015261256d6044820161460d565b6040850152606481013560608501526084810135608085015260a481013560a085015260c481013560c085015260e481013560e08501526101048101356101008501526101248101356101208501526101448101356101408501526101648101356101608501526125e16101848201614273565b61018085015201614273565b6101a082015260243567ffffffffffffffff811161042157612613903690600401614331565b9067ffffffffffffffff604435116104215761263436604435600401614331565b9067ffffffffffffffff606435116104215761265536606435600401614331565b94909333600052600360205260ff604060002054168015612bcd575b8015612bb4575b61268190614983565b83821480612bab575b15612b41576126a0606460c089015110156149f4565b600f54968760005260056020526040600020815180519067ffffffffffffffff8211611aac5781906126d2845461461a565b601f8111612b04575b50602090601f8311600114612a9857600092612a8d575b50506000198260011b9260031b1c19161781555b6001810161272760208401511515829060ff60ff1983541691151516179055565b604083015115157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff61ff0083549260081b169116179055606082015160028201556080820151600382015560a0820151600482015560c0820151600582015560e08201516006820155610100820151600782015561012082015160088201556101408201516009820155610160820151600a820155600b8101906101a0600c6001600160a01b03928361018087015116947fffffffffffffffffffffffff0000000000000000000000000000000000000000958682541617905501930151169082541617905586600052600560205260086040600020015460066020526040600020906001820155600160ff19825416179055600b602052604060002067ffffffffffffffff8711611aac57680100000000000000008711611aac578054878255808810612a6f575b50859060005260206000209060005b888110612a5b5750505086600052600c60205260406000209067ffffffffffffffff8311611aac57680100000000000000008311611aac578154838355808410612a31575b5090600052602060002060005b838110612a1d575050505084600052600d60205260406000209067ffffffffffffffff8311611aac57680100000000000000008311611aac5781548383558084106129f4575b5090600052602060002060005b8381106129e05750505050600183018084116129b157600f5560005b82811061297b576020847fa78c547613f6306e7a70d1bd161c18a496cae1eeb8d4f9e58b60d69ad72ddf5882604051838152a1604051908152f35b80606461298c61299d938686614923565b351115806129a257611afe90614a7c565b612940565b50611afe611b17828686614923565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600190602084359401938184015501612924565b8260005283602060002091820191015b818110612a115750612917565b60008155600101612a04565b6001906020843594019381840155016128d1565b826000526020600020908482015b8183018110612a4f5750506128c4565b60008155600101612a3f565b60019060208335930192818501550161287f565b612a8790826000528860206000209182019101614a65565b88612870565b015190508b806126f2565b9250836000526020600020906000935b601f1984168510612ae9576001945083601f19811610612ad0575b505050811b018155612706565b015160001960f88460031b161c191690558b8080612ac3565b81810151835560209485019460019093019290910190612aa8565b612b3190856000526020600020601f850160051c81019160208610612b37575b601f0160051c0190614a65565b8c6126db565b9091508190612b24565b608460405162461bcd60e51b815260206004820152602160248201527f41756374696f6e3a204172726179204c656e67746873204d757374204d61746360448201527f68000000000000000000000000000000000000000000000000000000000000006064820152fd5b5085841461268a565b506126816001600160a01b036001541633149050612678565b50600260205260ff60406000205416612671565b346104215760208060031936011261042157600435612bff816152fa565b816000526005908184526002612c1b81604060002001546152c9565b9260005b856000528187528260406000200154811015612c7057612c6b90600788526040600020612c4c8287614c96565b516000528852600360406000200154612c658288614c96565b52614914565b612c1f565b60405187815280610403818a01886144b9565b346104215760006003193601126104215760206001600160a01b0360015416604051908152f35b346104215760006003193601126104215760206040516d76a84fef008cdabe6409d2fe638b8152f35b3461042157602060031936011261042157610403610a566004356152fa565b3461042157612d003661448f565b9160005260096020526001600160a01b0360406000209116600052602052604060002080548210156104215760209161045791614539565b3461042157600060031936011261042157336000526002602052612d6360ff60406000205416614ac7565b61061f600080808047730bc56e3c1397e4570069e89c07936a5c6020e3be5af1612d8b614953565b50614b38565b3461042157612d9f366144ed565b92336000526020946003865260ff604060002054168015612ee9575b8015612ed0575b612dcb90614983565b80600052600c865260406000209367ffffffffffffffff94858211611aac576801000000000000000093848311611aac578154838355808410612ea8575b50906000528760002060005b838110612e965750505050600052600d85526040600020928411611aac578311611aac578154838355808410612e6e575b5090600052826000209260005b838110612e5c57005b82358582015591810191600101612e53565b82600052838560002091820191015b818110612e8a5750612e46565b60008155600101612e7d565b82358282015591890191600101612e15565b82600052838a60002091820191015b818110612ec45750612e09565b60008155600101612eb7565b50612dcb6001600160a01b036001541633149050612dc2565b506002865260ff60406000205416612dbb565b60a0600319360112610421576044356001600160a01b038116908181036104215767ffffffffffffffff9060643582811161042157612f3f903690600401614331565b91909260843590811161042157612f5a903690600401614331565b929091612f65614873565b612f70333214614714565b6004356000526006602052612f8c60ff60406000205416614785565b6004356000526005602052612fab6003604060002001544210156147d0565b6004356000526005602052612fc9600460406000200154421061481b565b3395806134be575b5050612fde600435615777565b8195913410613454576004356000526006602052600260406000200154600560205260026040600020015411156132b3575b613052955060066020526002604060002001549060086020526040600020906000526020526040600020556130466004356150e3565b85602435600435615501565b906004356000526006602052600260406000200154916040519061307582614594565b838252602082015260243560408201523460608201524260808201523360a08201526001600160a01b03821660c0820152600060e0820152600061010082015260006101208201526004356000526007602052604060002083600052602052600660406000208251815560208301516001820155604083015160028201556060830151600382015560808301516004820155600581016001600160a01b0360a0850151167fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905501906001600160a01b0360c0820151169082549174ff000000000000000000000000000000000000000060e0830151151560a01b16907fffffffffffffffffff000000000000000000000000000000000000000000000076ff0000000000000000000000000000000000000000000061012075ff000000000000000000000000000000000000000000610100870151151560a81b16950151151560b01b16941617171717905560043560005260096020526040600020336000526020526040600020805468010000000000000000811015611aac5761322491600182018155614539565b81549060031b9060001985831b921b191617905560018201918281116129b1576001600160a01b0360c0927f317b5389fd90ccd694f8873c2d07dc6c1c062b7143f1c91e58d48a5bc13afa6e94600435600052600660205260026040600020015560405192600435845260208401523360408401523460608401524260808401521660a0820152a16001600455005b60076020526040600020600860205260406000208260005260205260406000205460005260205260ff60066040600020015460a01c161561330c575b613052956004356000526006602052600160406000200155613010565b600435600090815260076020908152604080832060088352818420858552835281842080548552925280832060060180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000017905590548252812060058101546003909101548291829182916001600160a01b03165af16133a2614953565b501561341057613052956004356000526007602052604060002060086020526040600020836000526020526040600020546000526020527faa017e93278eca5fcf4a3ebb0506b183f3d0c3aa08e9aefaa419061b83341db26020604060002054604051908152a195506132ef565b606460405162461bcd60e51b815260206004820152601860248201527f41756374696f6e3a204b69636b6261636b204661696c656400000000000000006044820152fd5b608460405162461bcd60e51b815260206004820152603f60248201527f41756374696f6e3a2042696420416d6f756e74204d757374204265203e3d204360448201527f757272656e74204c6561646572626f61726420466c6f6f72202a20312e3035006064820152fd5b604051907f9c395bc200000000000000000000000000000000000000000000000000000000825287600483015260248201526020816044816d76a84fef008cdabe6409d2fe638b5afa90811561083e5760009161352a575b50613522575b80612fd1565b94508561351c565b90506020813d60201161355d575b81613545602093836145ce565b81010312610421575180151581036104215787613516565b3d9150613538565b34610421576020600319360112610421576001600160a01b0361358661425d565b166000526003602052602060ff604060002054166040519015158152f35b34610421576135b236614231565b9033600052600360205260ff60406000205416801561360b575b80156135f2575b6135dc90614983565b6000526005602052600960406000200155600080f35b506135dc6001600160a01b0360015416331490506135d3565b50600260205260ff604060002054166135cc565b346104215761362d36614231565b9033600052600360205260ff604060002054168015613686575b801561366d575b61365790614983565b6000526005602052600260406000200155600080f35b506136576001600160a01b03600154163314905061364e565b50600260205260ff60406000205416613647565b34610421576040600319360112610421576136b3614247565b60043560005260096020526001600160a01b0360406000209116600052602052610403610a566040600020614c1a565b34610421576136f13661448f565b91600052600e6020526001600160a01b03604060002091166000526020526040600020906000526020526020604060002054604051908152f35b3461042157604060031936011261042157613744614247565b33600052600360205260ff6040600020541680156137cf575b80156137b6575b61376d90614983565b60043560005260056020526001600160a01b03600c60406000200191167fffffffffffffffffffffffff0000000000000000000000000000000000000000825416179055600080f35b5061376d6001600160a01b036001541633149050613764565b50600260205260ff6040600020541661375d565b34610421576020600319360112610421576104036138026004356153af565b6040519182916020835260208301906143d6565b346104215761382436614362565b61383081939293615360565b9260005b828110613851576040516020808252819061040390820188614287565b6139149084600052602060078152604060002061386f838787614923565b35600052815260406000206040519161388783614594565b815483526001820154908301526002810154604083015260038101546060830152600481015460808301526001600160a01b036006816005840154169260a093848601520154918291821660c085015260ff9283911c16151560e0840152818160a81c16151561010084015260b01c1615156101208201526139098288614c96565b526108248187614c96565b613834565b34610421576000600319360112610421576139406001600160a01b03600054163314614ba9565b61061f600080808047335af1612d8b614953565b346104215760206003193601126104215733600052600360205260ff6040600020541680156139d1575b80156139b8575b61398e90614983565b600435600052600660205261061f604060002060ff8154161560ff60ff1983541691151516179055565b5061398e6001600160a01b036001541633149050613985565b50600260205260ff6040600020541661397e565b34610421576020806003193601126104215760043590336000526003815260ff80604060002054168015613c86575b8015613c6d575b613a2490614983565b82600052600691828152604060002060ff198154169055613a4484614caa565b83600052828152613a5c82604060002054161561515f565b83600052828152604060002054613a7983600892831c16156151f6565b8460005283825260406000206101007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff8254161790556005918281526001600160a01b039384600b60406000200154169660005b8160005285845260026040600020015481101561061f57600780855260406000208686526040600020836000528652604060002054600052855283896040600020015460a81c1680613c34575b613b2e575b50613b2990614914565b613acd565b82600052808552604060002086865260406000208360005286526040600020546000528552886040600020017601000000000000000000000000000000000000000000007fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff8254161790558260005284526040600020858552604060002082600052855260406000205460005284528686604060002001541690893b15610421576040517f86a4fd73000000000000000000000000000000000000000000000000000000008152600481019290925260016024830152600082604481838e5af191821561083e57613b2992613c25575b5090613b1f565b613c2e90614580565b8a613c1e565b508260005280855260406000208686526040600020836000528652604060002054600052855283896040600020015460b01c1615613b1a565b50613a246001600160a01b036001541633149050613a1b565b50600282528060406000205416613a14565b3461042157602060031936011261042157610403613cb76004356158aa565b604051918291602083526020830190614287565b3461042157613cd936614231565b9060005260086020526040600020906000526020526020604060002054604051908152f35b3461042157604060031936011261042157600435613d1a614247565b908060005260206009815260406000206001600160a01b038094166000528152613d476040600020614c1a565b92613d528451615360565b9360005b815181101561114457613e0c9085600052600785526040600020613d7a8285614c96565b516000528552604060002060405190613d9282614594565b805482526001810154878301526002810154604083015260038101546060830152600481015460808301526006866005830154169160a092838501520154809187821660c085015260ff9283911c16151560e0840152818160a81c16151561010084015260b01c1615156101208201526111348289614c96565b613d56565b3461042157613e1f36614231565b9033600052600360205260ff604060002054168015613e78575b8015613e5f575b613e4990614983565b6000526005602052600360406000200155600080f35b50613e496001600160a01b036001541633149050613e40565b50600260205260ff60406000205416613e39565b346104215760208060031936011261042157600435336000526003825260ff91826040600020541680156141a4575b801561418b575b613ecb90614983565b81600052600690818152604060002060ff198154169055613eeb83614caa565b82600052818152613f0384604060002054161561515f565b82600052818152613f1e8460406000205460081c16156151f6565b82600052600580825260019384600a604060002001541115614121578060005283835260406000206101007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff8254161790558183526001600160a01b039283600b604060002001541696613f9183615996565b9280600052848352600a6040600020015496886000905b613fae57005b855181101561061f578260005260078086526040600020613fcf8389614c96565b51600052865284836040600020015460a81c16806140f1575b613ffd575b50613ff790614914565b89613fa8565b8360005280865260406000206140138389614c96565b516000528652826040600020017601000000000000000000000000000000000000000000007fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff82541617905583600052855260406000206140748288614c96565b51600052855287876040600020015416908b3b156104215760008a60448e948360405196879485937f86a4fd73000000000000000000000000000000000000000000000000000000008552600485015260248401525af191821561083e57613ff7926140e2575b5090613fed565b6140eb90614580565b8c6140db565b508360005280865260406000206141088389614c96565b51600052865284836040600020015460b01c1615613fe8565b6084836040519062461bcd60e51b82526004820152602560248201527f41756374696f6e3a204d696e74205061636b20416d6f756e74204d757374204260448201527f65203e20310000000000000000000000000000000000000000000000000000006064820152fd5b50613ecb6001600160a01b036001541633149050613ec2565b50600281528260406000205416613ebb565b34610421576141c436614231565b9033600052600360205260ff60406000205416801561421d575b8015614204575b6141ee90614983565b6000526005602052600760406000200155600080f35b506141ee6001600160a01b0360015416331490506141e5565b50600260205260ff604060002054166141de565b6003196040910112610421576004359060243590565b602435906001600160a01b038216820361042157565b600435906001600160a01b038216820361042157565b35906001600160a01b038216820361042157565b90815180825260208080930193019160005b8281106142a7575050505090565b835180518652808301518684015260408082015190870152606080820151908701526080808201519087015260a0808201516001600160a01b039081169188019190915260c0808301519091169087015260e08082015115159087015261010080820151151590870152610120908101511515908601526101409094019392810192600101614299565b9181601f840112156104215782359167ffffffffffffffff8311610421576020808501948460051b01011161042157565b90604060031983011261042157600435916024359067ffffffffffffffff82116104215761439291600401614331565b9091565b919082519283825260005b8481106143c2575050601f19601f8460006020809697860101520116010190565b6020818301810151848301820152016143a1565b906143ea82516101e0808452830190614396565b916020810151151560208301526040810151151560408301526060810151151560608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e0830152610100808201519083015261012080820151908301526101408082015190830152610160808201519083015261018080820151908301526101a080820151908301526001600160a01b036101c0809201511691015290565b600319606091011261042157600435906024356001600160a01b0381168103610421579060443590565b90815180825260208080930193019160005b8281106144d9575050505090565b8351855293810193928101926001016144cb565b906060600319830112610421576004359167ffffffffffffffff91602435838111610421578261451f91600401614331565b939093926044359182116104215761439291600401614331565b80548210156145515760005260206000200190600090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b67ffffffffffffffff8111611aac57604052565b610140810190811067ffffffffffffffff821117611aac57604052565b6101e0810190811067ffffffffffffffff821117611aac57604052565b90601f601f19910116810190811067ffffffffffffffff821117611aac57604052565b67ffffffffffffffff8111611aac57601f01601f191660200190565b3590811515820361042157565b90600182811c92168015614663575b602083101461463457565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b91607f1691614629565b90604051918260008254926146818461461a565b9081845260019485811690816000146146f057506001146146ad575b50506146ab925003836145ce565b565b9093915060005260209081600020936000915b8183106146d85750506146ab9350820101388061469d565b855488840185015294850194879450918301916146c0565b90506146ab95506020935060ff1991501682840152151560051b820101388061469d565b1561471b57565b608460405162461bcd60e51b815260206004820152603c60248201527f41756374696f6e3a20454f41204f6e6c792c20557365206064656c656761746560448201527f2e636173686020466f722057616c6c65742044656c65676174696f6e000000006064820152fd5b1561478c57565b606460405162461bcd60e51b815260206004820152601e60248201527f41756374696f6e3a2041756374696f6e204973204e6f742041637469766500006044820152fd5b156147d757565b606460405162461bcd60e51b815260206004820152602060248201527f41756374696f6e3a2041756374696f6e20486173204e6f7420537461727465646044820152fd5b1561482257565b606460405162461bcd60e51b815260206004820152601e60248201527f41756374696f6e3a2041756374696f6e2048617320436f6e636c7564656400006044820152fd5b919082018092116129b157565b600260045414614884576002600455565b606460405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b604051906148d582614594565b816101206000918281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e0820152826101008201520152565b60001981146129b15760010190565b91908110156145515760051b0190565b818102929181159184041417156129b157565b919082039182116129b157565b3d1561497e573d90614964826145f1565b9161497260405193846145ce565b82523d6000602084013e565b606090565b1561498a57565b608460405162461bcd60e51b815260206004820152603f60248201527f4d697373696f6e436f6e74726f6c207c206f6e6c794f70657261746f72207c2060448201527f43616c6c6572204973204e6f74204f70657261746f72204f722041646d696e006064820152fd5b156149fb57565b608460405162461bcd60e51b815260206004820152602d60248201527f41756374696f6e3a204d696e696d756d204249505320496e637265617365204d60448201527f757374204265203e3d20313030000000000000000000000000000000000000006064820152fd5b818110614a70575050565b60008155600101614a65565b15614a8357565b606460405162461bcd60e51b815260206004820152601860248201527f496e76616c696420446973636f756e7420416d6f756e747300000000000000006044820152fd5b15614ace57565b608460405162461bcd60e51b815260206004820152603060248201527f4d697373696f6e436f6e74726f6c207c206f6e6c7941646d696e207c2043616c60448201527f6c6572204973204e6f742041646d696e000000000000000000000000000000006064820152fd5b15614b3f57565b608460405162461bcd60e51b815260206004820152602f60248201527f556e61626c6520746f2057697468647261772c20526563697069656e74204d6160448201527f79204861766520526576657274656400000000000000000000000000000000006064820152fd5b15614bb057565b608460405162461bcd60e51b815260206004820152603060248201527f4d697373696f6e436f6e74726f6c207c206f6e6c794f776e6572207c2043616c60448201527f6c6572204973204e6f74204f776e6572000000000000000000000000000000006064820152fd5b9060405191828154918282526020928383019160005283600020936000905b828210614c4f575050506146ab925003836145ce565b855484526001958601958895509381019390910190614c39565b8051156145515760200190565b8051600110156145515760400190565b8051600210156145515760600190565b80518210156145515760209160051b010190565b60009080825260056020818152600293604090858282200154936006948585528784842001548091116150d4575b508197614ce4876156cf565b90835b88855283875289868620015481101561500c576007808852868620600890818a528888208489528a52888820548852895260ff91828b8a8a20015460a01c161580614fde575b80614fb2575b614d49575b505050614d4490614914565b614ce7565b8689859f95938c8f96958f958d96898852818452858820858552868920848a5285528689205489528452808689200175010000000000000000000000000000000000000000007fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff825416179055898852818452858820858552868920848a528552868920548952845285882001740100000000000000000000000000000000000000007fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff8254161790558887528083528487208484528588208389528452858820548852835260018c81878a200154998b8a52838652878a20878752888b20868c528752888b20548b52865260038c818a8d2001549c62010f2c8114600014614f95575050506064925b8c8b52898752888b2001541615614f7f57614e93614e9a92606492614933565b0489614946565b985b89614eca575b505050505050505091614ebb614ec192614d4494614946565b90614866565b9a903880614d38565b875282528386209282528386209086528152828520548552528220015481908190819086906001600160a01b03165af1614f02614953565b5015614f16578686898f8c8f388391614ea2565b60848989519062461bcd60e51b82526004820152603e60248201527f41756374696f6e3a204661696c656420546f205265626174652045544820546f60448201527f204269646465722c20557365204661696c7361666520576974686472617700006064820152fd5b506064614e93614f8f928b614933565b98614e9c565b614fa7918d52600b89528a8d20614539565b9054911b1c92614e73565b508b8852808a52888820828b52898920858a528b528989205489528a528560038a8a2001541015614d33565b508b8852808a52888820828b52898920858a528b528989205489528a52828b8a8a20015460a81c1615614d2d565b50989150508194508193965081929550730bc56e3c1397e4570069e89c07936a5c6020e3be5af161503b614953565b5015615045575050565b60a49250519062461bcd60e51b82526004820152604860248201527f41756374696f6e3a2041646d696e204661696c656420546f205769746864726160448201527f772045544820546f204d756c74697369672c20557365204661696c736166652060648201527f57697468647261770000000000000000000000000000000000000000000000006084820152fd5b81855287848420015538614cd8565b600081815260056020526150ff60046040832001544290614946565b918082526005602052604082209260078401541161511c57505050565b61514b60067fab9c9a8aeadcc64e09e3ec376616fdcd4dd4a5e728535b290e272c2f1792056f94015442614866565b9082526005602052600460408320015580a1565b1561516657565b60a460405162461bcd60e51b815260206004820152604e60248201527f41756374696f6e3a2041756374696f6e204973205374696c6c2041637469766560448201527f2c204d7573742044697370657273652046756e647320262046696e616c697a6560648201527f2041756374696f6e2046697273740000000000000000000000000000000000006084820152fd5b156151fd57565b606460405162461bcd60e51b815260206004820152601f60248201527f41756374696f6e3a204e46547320416c726561647920446973706572736564006044820152fd5b6040519061524e826145b1565b81606081526101c06000918260208201528260408201528260608201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201528261016082015282610180820152826101a08201520152565b67ffffffffffffffff8111611aac5760051b60200190565b906152d3826152b1565b6152e060405191826145ce565b828152601f196152f082946152b1565b0190602036910137565b6000818152600590602082815260029460409561531b8188862001546152c9565b94845b8786528185528289872001548110156153545761534f9060088652898720818852865289872054612c65828a614c96565b61531e565b50505094505050905090565b9061536a826152b1565b61537760405191826145ce565b828152601f1961538782946152b1565b019060005b82811061539857505050565b6020906153a36148c8565b8282850101520161538c565b6153b7615241565b506000908152600560205260408082209160066020528181205492600560205282822091600183015460ff1692600281015490600381015490600481015460058201549060068301549260070154936006602052898720958a60018801549760020154986005602052209960098b015499600a8c01549b600b01546001600160a01b03169c80519e8f9261544a846145b1565b6154539061466d565b835260ff81161515602084015260081c60ff161515910152151560608d015260808c015260a08b015260c08a015260e08901526101008801526101208701526101408601526101608501526101808401526101a08301526101c082015290565b92916154be826152b1565b916154cc60405193846145ce565b829481845260208094019160051b810192831161042157905b8282106154f25750505050565b813581529083019083016154e5565b95919092949395604094855191602097888401917fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606096871b1692838152601486528986019567ffffffffffffffff9681811088821117611aac578b525190209a60005b82600052600b8c528a6000205481101561565e578c6155aa615591838f8f90600c9052600020614539565b929054600393841b1c6155a536878a6154b3565b615672565b6155bd57506155b890614914565b615566565b93509b5050600052600d89526155d68a89600020614539565b9054911b1c9387519689880192835260349081890152875286019286841090841117611aac57615611956155a59388525190209336916154b3565b1561561b57505090565b60649250519062461bcd60e51b82526004820152601e60248201527f41756374696f6e3a20496e76616c6964204d65726b6c6520416d6f756e7400006044820152fd5b5050505050505050505050505062010f2c90565b929091906000915b84518310156156c75761568d8386614c96565b51906000828210156156b557506000526020526156af60406000205b92614914565b9161567a565b6040916156af938252602052206156a9565b915092501490565b60001960005b826000526020600581526040600281600020015483101561576f5760079182815281600020906008918282528360002086600052825283600020546000528152600393868585600020015410615739575b505050505061573490614914565b6156d5565b61573495965087600052815282600020918152826000208660005281528260002054600052526000200154919038808080615726565b505050905090565b90615781826157fc565b9160009080825260209160068352604091600283832001546005855260028484200154116000146157bc576001936006918352522001549190565b906157f7926005918286600760649852838320600882528484208b855282528484205484528152600384842001549583525220015490614933565b049190565b600019600092828452602090600682526002946040958087832001546005908186528289852001541161589957825b876000528186528289600020015481101561588d576007865288600020600887528960002082600052875289600020546000528652600389600020015487811115615880575b5061587b90614914565b61582b565b965092508261587b615871565b50505093509350505090565b509450916006919593505220015490565b6158b381615996565b6158bd8151615360565b9160005b82518110156159905761598b90826000526020600781526040806000206158e88488614c96565b51600052825280600020908051926158ff84614594565b8254845260018301549084015260028201549083015260038101546060830152600481015460808301526001600160a01b036006816005840154169260a093848601520154918291821660c085015260ff9283911c16151560e0840152818160a81c16151561010084015260b01c1615156101208201526159808287614c96565b526108248186614c96565b6158c1565b50505090565b90600091808352602090600682526040936002858181842001549260058652200154809110600014615d3f5750600682526002846000200154915b6159da836152b1565b926159e7865194856145ce565b808452601f196159f6826152b1565b018260005b828110615d2f5750505060005b8451811015615b0257865190608082019180831067ffffffffffffffff841117611aac57615afd92895260039081815260603687830137615a498389614c96565b52615a548288614c96565b5085600052600780865289600020916008928388528b6000208560005288528b6000205460005287528a6000200154615a96615a90858b614c96565b51614c69565b5286600052818652896000208360005286528960002054615ac0615aba858b614c96565b51614c76565b528660005285528860002090855288600020826000528552886000205460005284526004886000200154612c65615af78389614c96565b51614c86565b615a08565b509450505060005b8151811015615cdb57615b20615a908284614c96565b51615b2e615aba8385614c96565b5194615b3d615af78486614c96565b5194835b8015801580615cb8575b15615ca157600019820191808311806129b15786615b6c615a90868c614c96565b511480615c88575b818115615c4d575b50615c0d576129b157615b92615a90848a614c96565b51615ba0615a90838b614c96565b52615bae615aba848a614c96565b51615bbc615aba838b614c96565b52615bd8615af7615bd0615af7868c614c96565b51928a614c96565b5215615b41577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b509050615af79150612c659296979398615c4596955b615c30615a90848c614c96565b52615c3e615aba838b614c96565b5287614c96565b919091615b0a565b90506129b15786615c61615a90868c614c96565b511480615c6f575b81615b7c565b5050600089615c81615af7868c614c96565b5111615c69565b505060008a615c9a615aba868c614c96565b5111615b74565b50615af790612c659296979398615c459695615c23565b5060001982018281116129b157615cd3615a9087928a614c96565b511015615b4b565b5091615ce6816152c9565b9260005b8151811015615d2a57615d00615aba8284614c96565b51906000198401918483116129b157612c65615d1f83615d2595614946565b88614c96565b615cea565b505050565b60608282890101520183906159fb565b916159d156fea2646970667358221220e8f091550448b62da430ae76e677b92e5425287ecc97fd269e78cb09d3a937d464736f6c63430008130033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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