ETH Price: $2,604.25 (-0.26%)

Contract

0x06d3E950fE4CeD87c7b24e8336B8688CE2c0Ca9c
 

Overview

ETH Balance

0.007 ETH

Eth Value

$18.23 (@ $2,604.25/ETH)

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Cancel Auction207004682024-09-07 18:18:2340 days ago1725733103IN
Tux: Auctions
0 ETH0.000376982.05112456
Cancel Auction207004602024-09-07 18:16:4740 days ago1725733007IN
Tux: Auctions
0 ETH0.00032911.67843476
Cancel Auction193334572024-02-29 13:25:47231 days ago1709213147IN
Tux: Auctions
0 ETH0.0157510880.32947
Cancel Auction191035922024-01-28 7:37:11263 days ago1706427431IN
Tux: Auctions
0 ETH0.0024903212.70048538
Cancel Auction191035852024-01-28 7:35:47263 days ago1706427347IN
Tux: Auctions
0 ETH0.0023282611.87397776
Cancel Auction191035262024-01-28 7:23:35263 days ago1706426615IN
Tux: Auctions
0 ETH0.0031623216.12763632
Cancel Auction184460972023-10-28 3:43:59355 days ago1698464639IN
Tux: Auctions
0 ETH0.0022282512.1237213
Set Auction Rese...180624122023-09-04 10:06:47409 days ago1693822007IN
Tux: Auctions
0 ETH0.0004370313.32580242
Set Auction Rese...170065152023-04-08 22:07:23558 days ago1680991643IN
Tux: Auctions
0 ETH0.0006046818.43775758
Cancel Auction166737732023-02-21 1:59:47604 days ago1676944787IN
Tux: Auctions
0 ETH0.0048283926.27081015
Cancel Auction166737732023-02-21 1:59:47604 days ago1676944787IN
Tux: Auctions
0 ETH0.0049709626.27081015
Cancel Auction166737712023-02-21 1:59:23604 days ago1676944763IN
Tux: Auctions
0 ETH0.0052379628.49924148
Cancel Auction166737692023-02-21 1:58:59604 days ago1676944739IN
Tux: Auctions
0 ETH0.005137227.95105662
Cancel Auction166737642023-02-21 1:57:59604 days ago1676944679IN
Tux: Auctions
0 ETH0.0047033425.59044854
Cancel Auction165525022023-02-04 2:40:35621 days ago1675478435IN
Tux: Auctions
0 ETH0.0046783423.8592291
Set Auction Rese...165524552023-02-04 2:31:11621 days ago1675477871IN
Tux: Auctions
0 ETH0.0009677829.52015231
Cancel Auction163955972023-01-13 4:50:23643 days ago1673585423IN
Tux: Auctions
0 ETH0.0034001917.34076852
Cancel Auction163942212023-01-13 0:13:23643 days ago1673568803IN
Tux: Auctions
0 ETH0.003119416.97236045
Cancel Auction163345882023-01-04 16:22:11652 days ago1672849331IN
Tux: Auctions
0 ETH0.0060578630.89282542
Cancel Auction163233592023-01-03 2:46:11653 days ago1672713971IN
Tux: Auctions
0 ETH0.0041402221.11358073
Cancel Auction163190742023-01-02 12:25:35654 days ago1672662335IN
Tux: Auctions
0 ETH0.0027067914.30502027
Cancel Auction162904792022-12-29 12:41:23658 days ago1672317683IN
Tux: Auctions
0 ETH0.0029240614.91162519
Cancel Auction162537542022-12-24 9:39:23663 days ago1671874763IN
Tux: Auctions
0 ETH0.0196081100
Cancel Auction162170582022-12-19 6:49:47668 days ago1671432587IN
Tux: Auctions
0 ETH0.0024459212.47329088
Cancel Auction162139642022-12-18 20:27:47669 days ago1671395267IN
Tux: Auctions
0 ETH0.0023702812.08827203
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
151071012022-07-09 7:44:10831 days ago1657352650
Tux: Auctions
0.075 ETH
150733002022-07-04 2:17:41836 days ago1656901061
Tux: Auctions
0.05 ETH
146631002022-04-26 23:41:11904 days ago1651016471
Tux: Auctions
0.15 ETH
145034522022-04-01 23:57:07929 days ago1648857427
Tux: Auctions
2.5 ETH
145034412022-04-01 23:54:08929 days ago1648857248
Tux: Auctions
5 ETH
144775642022-03-28 23:11:29934 days ago1648509089
Tux: Auctions
5 ETH
142830752022-02-26 17:25:50964 days ago1645896350
Tux: Auctions
3 ETH
142522732022-02-21 23:05:54969 days ago1645484754
Tux: Auctions
0.25 ETH
142319112022-02-18 19:17:23972 days ago1645211843
Tux: Auctions
4 ETH
138015622021-12-14 5:59:101038 days ago1639461550
Tux: Auctions
2 ETH
137881562021-12-12 4:25:571040 days ago1639283157
Tux: Auctions
0.5 ETH
137687312021-12-09 3:32:231043 days ago1639020743
Tux: Auctions
2 ETH
136725252021-11-23 18:54:201059 days ago1637693660
Tux: Auctions
6.175 ETH
136725252021-11-23 18:54:201059 days ago1637693660
Tux: Auctions
0.325 ETH
136725102021-11-23 18:52:111059 days ago1637693531
Tux: Auctions
3 ETH
136661162021-11-22 18:39:131060 days ago1637606353
Tux: Auctions
1.2 ETH
136660662021-11-22 18:28:521060 days ago1637605732
Tux: Auctions
5 ETH
136580822021-11-21 12:04:381061 days ago1637496278
Tux: Auctions
4 ETH
136090242021-11-13 17:37:541069 days ago1636825074
Tux: Auctions
7 ETH
136090232021-11-13 17:37:491069 days ago1636825069
Tux: Auctions
6 ETH
135932042021-11-11 6:00:041071 days ago1636610404
Tux: Auctions
1 ETH
135779012021-11-08 20:36:551074 days ago1636403815
Tux: Auctions
10 ETH
135573832021-11-05 15:28:301077 days ago1636126110
Tux: Auctions
5.2 ETH
135517852021-11-04 18:18:361078 days ago1636049916
Tux: Auctions
6.9 ETH
135508732021-11-04 14:57:421078 days ago1636037862
Tux: Auctions
2.5 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Auctions

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 100 runs

Other Settings:
default evmVersion
File 1 of 13 : Auctions.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.9;

import { ITux } from "./ITux.sol";
import { ITuxERC20 } from "./ITuxERC20.sol";
import { IAuctions } from "./IAuctions.sol";

import "./library/UintSet.sol";
import "./library/AddressSet.sol";
import "./library/OrderedSet.sol";
import "./library/RankedSet.sol";
import "./library/RankedAddressSet.sol";
import { IERC721, IERC165 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import { IERC721Metadata } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";


contract Auctions is
    IAuctions
{
    using UintSet for UintSet.Set;
    using AddressSet for AddressSet.Set;
    using OrderedSet for OrderedSet.Set;
    using RankedSet for RankedSet.Set;
    using RankedAddressSet for RankedAddressSet.Set;

    uint256 private _lastBidId;
    uint256 private _lastOfferId;
    uint256 private _lastHouseId;
    uint256 private _lastAuctionId;

    // TuxERC20 contract address
    address public tuxERC20;

    // Minimum amount of time left in seconds to an auction after a new bid is placed
    uint256 constant public timeBuffer = 900;  // 15 minutes -> 900 seconds

    // Minimum percentage difference between the last bid and the current bid
    uint16 constant public minimumIncrementPercentage = 500;  // 5%

    // Mapping from house name to house ID
    mapping(string => uint256) public houseIDs;

    // Mapping from keccak256(contract, token) to currently running auction ID
    mapping(bytes32 => uint256) public tokenAuction;

    // Mapping of token contracts
    mapping(address => IAuctions.TokenContract) public contracts;

    // Mapping of auctions
    mapping(uint256 => IAuctions.Auction) public auctions;

    // Mapping of houses
    mapping(uint256 => IAuctions.House) public houses;

    // Mapping of bids
    mapping(uint256 => IAuctions.Bid) public bids;

    // Mapping of offers
    mapping(uint256 => IAuctions.Offer) public offers;

    // Mapping of accounts
    mapping(address => IAuctions.Account) public accounts;

    // Mapping from creator to stats
    mapping(address => IAuctions.CreatorStats) public creatorStats;

    // Mapping from collector to stats
    mapping(address => IAuctions.CollectorStats) public collectorStats;

    // Mapping from creator to token contracts
    mapping(address => AddressSet.Set) private _collections;

    // Mapping from house ID to token IDs requiring approval
    mapping(uint256 => UintSet.Set) private _houseQueue;

    // Mapping from auction ID to bids
    mapping(uint256 => UintSet.Set) private _auctionBids;

    // Mapping from house ID to active auction IDs
    mapping(uint256 => OrderedSet.Set) private _houseAuctions;

    // Mapping from curator to enumerable house IDs
    mapping(address => UintSet.Set) private _curatorHouses;

    // Mapping from creator to enumerable house IDs
    mapping(address => UintSet.Set) private _creatorHouses;

    // Mapping from house id to enumerable creators
    mapping(uint256 => AddressSet.Set) private _houseCreators;

    // Mapping from seller to active auction IDs
    mapping(address => UintSet.Set) private _sellerAuctions;

    // Mapping from bidder to active auction IDs
    mapping(address => UintSet.Set) private _bidderAuctions;

    // Mapping from keccak256(contract, token) to previous auction IDs
    mapping(bytes32 => UintSet.Set) private _previousTokenAuctions;

    // Mapping from keccak256(contract, token) to offer IDs
    mapping(bytes32 => UintSet.Set) private _tokenOffers;

    // RankedSet of house IDs
    RankedSet.Set private _rankedHouses;

    // RankedAddressSet of creators
    RankedAddressSet.Set private _rankedCreators;

    // RankedAddressSet of collectors
    RankedAddressSet.Set private _rankedCollectors;

    // OrderedSet of active token contracts
    RankedAddressSet.Set private _rankedContracts;

    // OrderedSet of active houses
    OrderedSet.Set private _activeHouses;

    // OrderedSet of active auction IDs without a house ID
    OrderedSet.Set private _activeAuctions;


    bytes4 constant interfaceId = 0x80ac58cd; // ERC721 interfaceId
    bytes4 constant interfaceIdMetadata = 0x5b5e139f; // Metadata extension
    bytes4 constant interfaceIdEnumerable = 0x780e9d63; // Enumerable extension


    modifier auctionExists(uint256 auctionId) {
        require(
            auctions[auctionId].tokenOwner != address(0),
            "Does not exist");
        _;
    }

    modifier onlyHouseCurator(uint256 houseId) {
        require(
            msg.sender == houses[houseId].curator,
            "Not house curator");
        _;
    }


    /*
     * Constructor
     */
    constructor(
        address tuxERC20_
    ) {
        tuxERC20 = tuxERC20_;
    }

    function totalHouses() public view override returns (uint256) {
        return _lastHouseId;
    }

    function totalAuctions() public view override returns (uint256) {
        return _lastAuctionId;
    }

    function totalContracts() public view override returns (uint256) {
        return _rankedContracts.length();
    }

    function totalCreators() public view override returns (uint256) {
        return _rankedCreators.length();
    }

    function totalCollectors() public view override returns (uint256) {
        return _rankedCollectors.length();
    }

    function totalActiveHouses() public view override returns (uint256) {
        return _activeHouses.length();
    }

    function totalActiveAuctions() public view override returns (uint256) {
        return _activeAuctions.length();
    }

    function totalActiveHouseAuctions(uint256 houseId) public view override returns (uint256) {
        return _houseAuctions[houseId].length();
    }

    function getActiveHouses(uint256 from, uint256 n) public view override returns (uint256[] memory) {
        return _activeHouses.valuesFromN(from, n);
    }

    function getRankedHouses(uint256 from, uint256 n) public view override returns (uint256[] memory) {
        return _rankedHouses.valuesFromN(from, n);
    }

    function getRankedCreators(address from, uint256 n) public view override returns (address[] memory) {
        return _rankedCreators.valuesFromN(from, n);
    }

    function getRankedCollectors(address from, uint256 n) public view override returns (address[] memory) {
        return _rankedCollectors.valuesFromN(from, n);
    }

    function getRankedContracts(address from, uint256 n) public view override returns (address[] memory) {
        return _rankedContracts.valuesFromN(from, n);
    }

    function getCollections(address creator) external view override returns (address[] memory) {
        return _collections[creator].values();
    }

    function getAuctions(uint256 from, uint256 n) public view override returns (uint256[] memory) {
        return _activeAuctions.valuesFromN(from, n);
    }

    function getHouseAuctions(uint256 houseId, uint256 from, uint256 n) public view override returns (uint256[] memory) {
        return _houseAuctions[houseId].valuesFromN(from, n);
    }

    function getHouseQueue(uint256 houseId) public view override returns (uint256[] memory) {
        return _houseQueue[houseId].values();
    }

    function getAuctionBids(uint256 auctionId) public view override returns (uint256[] memory) {
        return _auctionBids[auctionId].values();
    }

    function getCuratorHouses(address curator) public view override returns (uint256[] memory) {
        return _curatorHouses[curator].values();
    }

    function getCreatorHouses(address creator) public view override returns (uint256[] memory) {
        return _creatorHouses[creator].values();
    }

    function getHouseCreators(uint256 houseId) public view override returns (address[] memory) {
        return _houseCreators[houseId].values();
    }

    function getSellerAuctions(address seller) public view override returns (uint256[] memory) {
        return _sellerAuctions[seller].values();
    }

    function getBidderAuctions(address bidder) public view override returns (uint256[] memory) {
        return _bidderAuctions[bidder].values();
    }

    function getPreviousAuctions(bytes32 tokenHash) public view override returns (uint256[] memory) {
        return _previousTokenAuctions[tokenHash].values();
    }

    function getTokenOffers(bytes32 tokenHash) public view override returns (uint256[] memory) {
        return _tokenOffers[tokenHash].values();
    }


    function createHouse(
        string  memory name,
        address curator,
        uint16  fee,
        bool    preApproved,
        string  memory metadata
    )
        public
        override
    {
        require(
            houseIDs[name] == 0,
            "Already exists");
        require(
            bytes(name).length > 0,
            "Name required");
        require(
            bytes(name).length <= 32,
            "Name too long");
        require(
            curator != address(0),
            "Address required");
        require(
            fee < 10000,
            "Fee too high");

        _lastHouseId += 1;
        uint256 houseId = _lastHouseId;

        houses[houseId].name = name;
        houses[houseId].curator = payable(curator);
        houses[houseId].fee = fee;
        houses[houseId].preApproved = preApproved;
        houses[houseId].metadata = metadata;

        _curatorHouses[curator].add(houseId);
        _rankedHouses.add(houseId);
        houseIDs[name] = houseId;

        ITuxERC20(tuxERC20).updateFeatured();
        ITuxERC20(tuxERC20).mint(msg.sender, 5 * 10**18);

        emit HouseCreated(
            houseId
        );
    }

    function addCreator(
        uint256 houseId,
        address creator
    )
        public
        override
        onlyHouseCurator(houseId)
    {
        require(
            _houseCreators[houseId].contains(creator) == false,
            "Already added");

        _houseCreators[houseId].add(creator);
        _creatorHouses[creator].add(houseId);

        ITuxERC20(tuxERC20).mint(msg.sender, 1 * 10**18);

        emit CreatorAdded(
            houseId,
            creator
        );
    }

    function removeCreator(
        uint256 houseId,
        address creator
    )
        public
        override
        onlyHouseCurator(houseId)
    {
        require(
            _houseCreators[houseId].contains(creator) == true,
            "Already removed");

        _houseCreators[houseId].remove(creator);
        _creatorHouses[creator].remove(houseId);

        emit CreatorRemoved(
            houseId,
            creator
        );
    }

    function updateFee(
        uint256 houseId,
        uint16  fee
    )
        public
        override
        onlyHouseCurator(houseId)
    {
        require(
            fee < 10000,
            "Fee too high");

        houses[houseId].fee = fee;

        emit FeeUpdated(
            houseId,
            fee
        );
    }

    function updateMetadata(
        uint256 houseId,
        string memory metadata
    )
        public
        override
        onlyHouseCurator(houseId)
    {
        houses[houseId].metadata = metadata;

        emit MetadataUpdated(
            houseId,
            metadata
        );
    }

    function updateName(
        string  memory name
    )
        public
        override
    {
        accounts[msg.sender].name = name;

        emit AccountUpdated(
            msg.sender
        );
    }

    function updateBio(
        string  memory bioHash
    )
        public
        override
    {
        accounts[msg.sender].bioHash = bioHash;

        emit AccountUpdated(
            msg.sender
        );
    }

    function updatePicture(
        string  memory pictureHash
    )
        public
        override
    {
        accounts[msg.sender].pictureHash = pictureHash;

        emit AccountUpdated(
            msg.sender
        );
    }

    function createAuction(
        address tokenContract,
        uint256 tokenId,
        uint256 duration,
        uint256 reservePrice,
        uint256 houseId
    )
        public
        override
    {
        if (contracts[tokenContract].tokenContract == address(0)) {
            registerTokenContract(tokenContract);
        }

        address tokenOwner = IERC721(tokenContract).ownerOf(tokenId);
        require(
            msg.sender == tokenOwner ||
            msg.sender == IERC721(tokenContract).getApproved(tokenId),
            "Not owner or approved");

        uint16  fee = 0;
        bool    preApproved = true;
        address curator = address(0);

        if (houseId > 0) {
            curator = houses[houseId].curator;

            require(
                curator != address(0),
                "House does not exist");
            require(
                _houseCreators[houseId].contains(tokenOwner) || msg.sender == curator,
                "Not approved by curator");

            fee = houses[houseId].fee;
            preApproved = houses[houseId].preApproved;
            houses[houseId].activeAuctions += 1;
        }

        try ITux(tokenContract).tokenCreator(tokenId) returns (address creator) {
            if (!_rankedCreators.contains(creator)) {
                _rankedCreators.add(creator);
            }
        } catch {}

        _lastAuctionId += 1;
        uint256 auctionId = _lastAuctionId;

        tokenAuction[keccak256(abi.encode(tokenContract, tokenId))] = auctionId;

        _sellerAuctions[tokenOwner].add(auctionId);

        bool approved = (curator == address(0) || preApproved || curator == tokenOwner);

        if (houseId > 0) {
            if (approved == true) {
                _houseAuctions[houseId].add(auctionId);
                if (_activeHouses.head() != houseId) {
                    if (_activeHouses.contains(houseId)) {
                        _activeHouses.remove(houseId);
                    }
                    _activeHouses.add(houseId);
                }
            }
            else {
                _houseQueue[houseId].add(auctionId);
            }
        }
        else {
            _activeAuctions.add(auctionId);
        }

        auctions[auctionId] = Auction({
            tokenContract: tokenContract,
            tokenId: tokenId,
            tokenOwner: tokenOwner,
            duration: duration,
            reservePrice: reservePrice,
            houseId: houseId,
            fee: fee,
            approved: approved,
            firstBidTime: 0,
            amount: 0,
            bidder: payable(0),
            created: block.timestamp
        });

        IERC721(tokenContract).transferFrom(tokenOwner, address(this), tokenId);

        ITuxERC20(tuxERC20).updateFeatured();
        ITuxERC20(tuxERC20).mint(msg.sender, 10 * 10**18);

        emit AuctionCreated(
            auctionId
        );
    }

    function setAuctionApproval(uint256 auctionId, bool approved)
        public
        override
        auctionExists(auctionId)
    {
        IAuctions.Auction storage auction = auctions[auctionId];
        address curator = houses[auction.houseId].curator;

        require(
            curator == msg.sender,
            "Not auction curator");
        require(
            auction.firstBidTime == 0,
            "Already started");
        require(
            (approved == true && auction.approved == false) ||
            (approved == false && auction.approved == true),
            "Already in this state");

        auction.approved = approved;

        if (approved == true) {
            _houseAuctions[auction.houseId].add(auctionId);
            _houseQueue[auction.houseId].remove(auctionId);

            if (_activeHouses.head() != auction.houseId) {
                if (_activeHouses.contains(auction.houseId)) {
                    _activeHouses.remove(auction.houseId);
                }
                _activeHouses.add(auction.houseId);
            }
        }

        emit AuctionApprovalUpdated(
            auctionId,
            approved
        );
    }

    function setAuctionReservePrice(uint256 auctionId, uint256 reservePrice)
        public
        override
        auctionExists(auctionId)
    {
        IAuctions.Auction storage auction = auctions[auctionId];

        require(
            msg.sender == auction.tokenOwner,
            "Not token owner");
        require(
            auction.firstBidTime == 0,
            "Already started");

        auction.reservePrice = reservePrice;

        emit AuctionReservePriceUpdated(
            auctionId,
            reservePrice
        );
    }

    function createBid(uint256 auctionId)
        public
        payable
        override
        auctionExists(auctionId)
    {
        IAuctions.Auction storage auction = auctions[auctionId];

        require(
            auction.approved,
            "Not approved by curator");
        require(
            auction.firstBidTime == 0 ||
            block.timestamp < auction.firstBidTime + auction.duration,
            "Auction expired");
        require(
            msg.value >= auction.amount + (
                auction.amount * minimumIncrementPercentage / 10000),
            "Amount too low");
        require(
            msg.value >= auction.reservePrice,
            "Bid below reserve price");

        address payable lastBidder = auction.bidder;
        bool isFirstBid = true;
        if (lastBidder != payable(0)) {
            isFirstBid = false;
        }

        if (auction.firstBidTime == 0) {
            auction.firstBidTime = block.timestamp;
        } else if (isFirstBid == false) {
            _handleOutgoingBid(lastBidder, auction.amount);
        }

        auction.amount = msg.value;
        auction.bidder = payable(msg.sender);

        if (auction.duration > 0) {
            _lastBidId += 1;
            uint256 bidId = _lastBidId;

            bids[bidId] = Bid({
                timestamp: block.timestamp,
                bidder: msg.sender,
                value: msg.value
            });

            _auctionBids[auctionId].add(bidId);
            _bidderAuctions[msg.sender].add(auctionId);
        }

        contracts[auction.tokenContract].bids += 1;

        try ITux(auction.tokenContract).tokenCreator(auction.tokenId) returns (address creator) {
            if (creator == auction.tokenOwner) {
                creatorStats[auction.tokenOwner].bids += 1;
            }
        } catch {}

        if (collectorStats[msg.sender].bids == 0) {
            _rankedCollectors.add(msg.sender);
        }
        collectorStats[msg.sender].bids += 1;

        if (auction.houseId > 0) {
            houses[auction.houseId].bids += 1;
            /* _rankedHouses.rankScore(auction.houseId, houses[auction.houseId].bids); // This gets too expensive... */

            _houseAuctions[auction.houseId].remove(auctionId);
            _houseAuctions[auction.houseId].add(auctionId);
        }

        bool extended = false;
        if (auction.duration > 0) {
          uint256 timeRemaining = auction.firstBidTime + auction.duration - block.timestamp;
          if (timeRemaining < timeBuffer) {
              auction.duration += timeBuffer - timeRemaining;
              extended = true;
          }
        }

        ITuxERC20(tuxERC20).updateFeatured();
        ITuxERC20(tuxERC20).mint(msg.sender, 10 * 10**18);

        emit AuctionBid(
            auctionId,
            msg.sender,
            msg.value,
            isFirstBid,
            extended
        );

        if (extended) {
            emit AuctionDurationExtended(
                auctionId,
                auction.duration
            );
        }
    }

    function endAuction(uint256 auctionId)
        public
        override
        auctionExists(auctionId)
    {
        IAuctions.Auction storage auction = auctions[auctionId];

        require(
            uint256(auction.firstBidTime) != 0,
            "Not started");
        require(
            block.timestamp >=
            auction.firstBidTime + auction.duration,
            "Not ended");

        try IERC721(auction.tokenContract).safeTransferFrom(
            address(this), auction.bidder, auction.tokenId
        ) {} catch {
            _handleOutgoingBid(auction.bidder, auction.amount);
            _cancelAuction(auctionId);
            return;
        }

        uint256 houseId = auction.houseId;
        address curator = address(0);
        uint256 curatorFee = 0;
        uint256 tokenOwnerProfit = auction.amount;

        collectorStats[auction.bidder].bought += 1;
        collectorStats[auction.bidder].totalSpent += tokenOwnerProfit;
        contracts[auction.tokenContract].sales += 1;
        contracts[auction.tokenContract].total += tokenOwnerProfit;

        try ITux(auction.tokenContract).tokenCreator(auction.tokenId) returns (address creator) {
            if (creator == auction.tokenOwner) {
                creatorStats[creator].sales += 1;
                creatorStats[creator].total += tokenOwnerProfit;
            } else {
                collectorStats[auction.tokenOwner].sales += 1;
                collectorStats[auction.tokenOwner].totalSold += tokenOwnerProfit;
            }
        } catch {
            collectorStats[auction.tokenOwner].sales += 1;
            collectorStats[auction.tokenOwner].totalSold += tokenOwnerProfit;
        }

        if (houseId > 0) {
            curator = houses[houseId].curator;
            houses[houseId].sales += 1;
            houses[houseId].total += tokenOwnerProfit;
            if (houses[houseId].activeAuctions > 0) {
                houses[houseId].activeAuctions -= 1;
            }
            _houseAuctions[houseId].remove(auctionId);
        }
        else {
            _activeAuctions.remove(auctionId);
        }

        if (curator != address(0) && auction.fee > 0) {
            curatorFee = tokenOwnerProfit * auction.fee / 10000;
            tokenOwnerProfit = tokenOwnerProfit - curatorFee;
            _handleOutgoingBid(curator, curatorFee);
        }
        _handleOutgoingBid(auction.tokenOwner, tokenOwnerProfit);

        if (houseId > 0) {
            houses[houseId].feesTotal += curatorFee;
        }

        bytes32 auctionHash = keccak256(abi.encode(auction.tokenContract, auction.tokenId));
        _previousTokenAuctions[auctionHash].add(auctionId);
        delete tokenAuction[auctionHash];

        if (auction.duration > 0) {
            uint256 i = _auctionBids[auctionId].length();
            while (i > 0) {
                uint256 bidId = _auctionBids[auctionId].at(i - 1);
                _bidderAuctions[bids[bidId].bidder].remove(auctionId);
                i--;
            }
        }

        _sellerAuctions[auction.tokenOwner].remove(auctionId);

        ITuxERC20(tuxERC20).updateFeatured();
        ITuxERC20(tuxERC20).mint(msg.sender, 10 * 10**18);

        emit AuctionEnded(
            auctionId
        );
    }

    function buyAuction(uint256 auctionId)
        public
        payable
        override
    {
        createBid(auctionId);
        endAuction(auctionId);
    }

    function cancelAuction(uint256 auctionId)
        public
        override
        auctionExists(auctionId)
    {
        require(
            auctions[auctionId].tokenOwner == msg.sender,
            "Not auction owner");
        require(
            uint256(auctions[auctionId].firstBidTime) == 0,
            "Already started");

        _cancelAuction(auctionId);
    }

    function registerTokenContract(address tokenContract)
        public
        override
    {
        require(
            contracts[tokenContract].tokenContract == address(0),
            "Already registered");
        require(
            IERC165(tokenContract).supportsInterface(interfaceId),
            "Does not support ERC721");
        require(
            IERC165(tokenContract).supportsInterface(interfaceIdMetadata),
            "Does not support ERC721Metadata");
        require(
            IERC165(tokenContract).supportsInterface(interfaceIdEnumerable),
            "Does not support ERC721Enumerable");

        contracts[tokenContract].name = IERC721Metadata(tokenContract).name();
        contracts[tokenContract].tokenContract = tokenContract;

        try ITux(tokenContract).owner() returns(address owner) {
            if (owner != address(0)) {
                _collections[owner].add(tokenContract);
            }
        } catch {}

        _rankedContracts.add(tokenContract);

        ITuxERC20(tuxERC20).mint(msg.sender, 1 * 10**18);
    }

    function makeOffer(address tokenContract, uint256 tokenId)
        public
        payable
        override
    {
        require(
            IERC165(tokenContract).supportsInterface(interfaceId),
            "Does not support ERC721");

        bytes32 auctionHash = keccak256(abi.encode(tokenContract, tokenId));
        require(
            tokenAuction[auctionHash] == 0,
            "Auction exists");

        _lastOfferId += 1;
        uint256 offerId = _lastOfferId;

        offers[offerId] = Offer({
            tokenContract: tokenContract,
            tokenId: tokenId,
            from: msg.sender,
            amount: msg.value,
            timestamp: block.timestamp
        });

        _tokenOffers[auctionHash].add(offerId);

        ITuxERC20(tuxERC20).mint(msg.sender, 1 * 10**18);
    }

    function acceptOffer(uint256 offerId)
        public
        override
    {
        IAuctions.Offer storage offer = offers[offerId];
        require(
            offer.tokenContract != address(0),
            "Does not exist");
        require(
            msg.sender == IERC721(offer.tokenContract).ownerOf(offer.tokenId) ||
            msg.sender == IERC721(offer.tokenContract).getApproved(offer.tokenId),
            "Not owner or approved");

        IERC721(offer.tokenContract).safeTransferFrom(msg.sender, offer.from, offer.tokenId);

        _handleOutgoingBid(msg.sender, offer.amount);

        bytes32 auctionHash = keccak256(abi.encode(offer.tokenContract, offer.tokenId));
        _tokenOffers[auctionHash].remove(offerId);

        delete offers[offerId];

        ITuxERC20(tuxERC20).mint(msg.sender, 1 * 10**18);
    }

    function cancelOffer(uint256 offerId)
        public
        override
    {
        IAuctions.Offer storage offer = offers[offerId];
        require(
            offer.from == msg.sender,
            "Not owner or missing");

        _handleOutgoingBid(msg.sender, offer.amount);

        bytes32 auctionHash = keccak256(abi.encode(offer.tokenContract, offer.tokenId));
        _tokenOffers[auctionHash].remove(offerId);

        delete offers[offerId];
    }

    function updateHouseRank(uint256 houseId)
        public
        override
    {
        require(
            _rankedHouses.scoreOf(houseId) < houses[houseId].bids,
            "Rank up to date");

        _rankedHouses.rankScore(houseId, houses[houseId].bids);

        ITuxERC20(tuxERC20).mint(msg.sender, 1 * 10**18);
    }

    function updateCreatorRank(address creator)
        public
        override
    {
        require(
            _rankedCreators.scoreOf(creator) < creatorStats[creator].bids,
            "Rank up to date");

        _rankedCreators.rankScore(creator, creatorStats[creator].bids);

        ITuxERC20(tuxERC20).mint(msg.sender, 1 * 10**18);
    }

    function updateCollectorRank(address collector)
        public
        override
    {
        require(
            _rankedCollectors.scoreOf(collector) < collectorStats[collector].bids,
            "Rank up to date");

        _rankedCollectors.rankScore(collector, collectorStats[collector].bids);

        ITuxERC20(tuxERC20).mint(msg.sender, 1 * 10**18);
    }

    function updateContractRank(address tokenContract)
        public
        override
    {
        require(
            _rankedContracts.scoreOf(tokenContract) < contracts[tokenContract].bids,
            "Rank up to date");

        _rankedContracts.rankScore(tokenContract, contracts[tokenContract].bids);

        ITuxERC20(tuxERC20).mint(msg.sender, 1 * 10**18);
    }

    function feature(uint256 auctionId, uint256 amount)
        public
        override
    {
        require(
            auctions[auctionId].tokenOwner == msg.sender,
            "Not token owner");
        ITuxERC20(tuxERC20).feature(auctionId, amount, msg.sender);
    }

    function cancelFeature(uint256 auctionId)
        public
        override
    {
        require(
            auctions[auctionId].tokenOwner == msg.sender,
            "Not token owner");
        ITuxERC20(tuxERC20).cancel(auctionId, msg.sender);
    }

    function _handleOutgoingBid(address to, uint256 amount) internal {
        require(
            _safeTransferETH(to, amount),
            "ETH transfer failed");
    }

    function _safeTransferETH(address to, uint256 value) internal returns (bool) {
        (bool success, ) = to.call{value: value}(new bytes(0));
        return success;
    }

    function _cancelAuction(uint256 auctionId) internal {
        IAuctions.Auction storage auction = auctions[auctionId];

        IERC721(auction.tokenContract).safeTransferFrom(address(this), auction.tokenOwner, auction.tokenId);

        uint256 houseId = auction.houseId;
        if (houseId > 0) {
            _houseAuctions[houseId].remove(auctionId);
            if (houses[houseId].activeAuctions > 0) {
                houses[houseId].activeAuctions -= 1;
            }
        }
        else {
            _activeAuctions.remove(auctionId);
        }

        auction.approved = false;
        bytes32 auctionHash = keccak256(abi.encode(auction.tokenContract, auction.tokenId));
        _previousTokenAuctions[auctionHash].add(auctionId);
        delete tokenAuction[auctionHash];

        emit AuctionCanceled(
            auctionId
        );
    }
}

File 2 of 13 : ITux.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.9;

import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol";

interface ITux is IERC721 {
    function owner() external view returns (address);
    function tokenCreator(uint256 tokenId) external view returns (address);
    function creatorTokens(address creator) external view returns (uint256[] memory);
}

File 3 of 13 : ITuxERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

interface ITuxERC20 {
    function mint(address to, uint256 amount) external;

    function feature(
        uint256 auctionId,
        uint256 amount,
        address from
    ) external;

    function cancel(
        uint256 auctionId,
        address from
    ) external;

    function updateFeatured() external;
    function payouts() external;
}

File 4 of 13 : IAuctions.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.9;


interface IAuctions {

    struct House {
        // House name
        string  name;

        // House curator
        address payable curator;

        // House percentage fee
        uint16  fee;

        // Pre-approve added creators
        bool    preApproved;

        // IPFS hash for metadata (logo, featured creators, pieces, links)
        string  metadata;

        // Total bids
        uint256 bids;

        // Total sales number
        uint256 sales;

        // Total sales amount
        uint256 total;

        // Total fees amount
        uint256 feesTotal;

        // Counter of active autions
        uint256 activeAuctions;
    }

    struct Auction {
        // Address of the ERC721 contract
        address tokenContract;

        // ERC721 tokenId
        uint256 tokenId;

        // Address of the token owner
        address tokenOwner;

        // Length of time in seconds to run the auction for, after the first bid was made
        uint256 duration;

        // Minimum price of the first bid
        uint256 reservePrice;

        // House ID for curator address
        uint256 houseId;

        // Curator fee for this auction
        uint16  fee;

        // Whether or not the auction curator has approved the auction to start
        bool    approved;

        // The time of the first bid
        uint256 firstBidTime;

        // The current highest bid amount
        uint256 amount;

        // The address of the current highest bidder
        address payable bidder;

        // The timestamp when this auction was created
        uint256 created;
    }

    struct TokenContract {
        string  name;
        address tokenContract;
        uint256 bids;
        uint256 sales;
        uint256 total;
    }

    struct Account {
        string  name;
        string  bioHash;
        string  pictureHash;
    }

    struct CreatorStats {
        uint256 bids;
        uint256 sales;
        uint256 total;
    }

    struct CollectorStats {
        uint256 bids;
        uint256 sales;
        uint256 bought;
        uint256 totalSold;
        uint256 totalSpent;
    }

    struct Bid {
        uint256 timestamp;
        address bidder;
        uint256 value;
    }

    struct Offer {
        address tokenContract;
        uint256 tokenId;
        address from;
        uint256 amount;
        uint256 timestamp;
    }

    event HouseCreated(
        uint256 indexed houseId
    );

    event CreatorAdded(
        uint256 indexed houseId,
        address indexed creator
    );

    event CreatorRemoved(
        uint256 indexed houseId,
        address indexed creator
    );

    event FeeUpdated(
        uint256 indexed houseId,
        uint16  fee
    );

    event MetadataUpdated(
        uint256 indexed houseId,
        string  metadata
    );

    event AccountUpdated(
        address indexed owner
    );

    event AuctionCreated(
        uint256 indexed auctionId
    );

    event AuctionApprovalUpdated(
        uint256 indexed auctionId,
        bool    approved
    );

    event AuctionReservePriceUpdated(
        uint256 indexed auctionId,
        uint256 reservePrice
    );

    event AuctionBid(
        uint256 indexed auctionId,
        address indexed bidder,
        uint256 value,
        bool    firstBid,
        bool    extended
    );

    event AuctionDurationExtended(
        uint256 indexed auctionId,
        uint256 duration
    );

    event AuctionEnded(
        uint256 indexed auctionId
    );

    event AuctionCanceled(
        uint256 indexed auctionId
    );

    function totalHouses() external view returns (uint256);

    function totalAuctions() external view returns (uint256);

    function totalContracts() external view returns (uint256);

    function totalCreators() external view returns (uint256);

    function totalCollectors() external view returns (uint256);

    function totalActiveHouses() external view returns (uint256);

    function totalActiveAuctions() external view returns (uint256);

    function totalActiveHouseAuctions(uint256 houseId) external view returns (uint256);

    function getActiveHouses(uint256 from, uint256 n) external view returns (uint256[] memory);

    function getRankedHouses(uint256 from, uint256 n) external view returns (uint256[] memory);

    function getRankedCreators(address from, uint256 n) external view returns (address[] memory);

    function getRankedCollectors(address from, uint256 n) external view returns (address[] memory);

    function getRankedContracts(address from, uint256 n) external view returns (address[] memory);

    function getCollections(address creator) external view returns (address[] memory);

    function getAuctions(uint256 from, uint256 n) external view returns (uint256[] memory);

    function getHouseAuctions(uint256 houseId, uint256 from, uint256 n) external view returns (uint256[] memory);

    function getHouseQueue(uint256 houseId) external view returns (uint256[] memory);

    function getCuratorHouses(address curator) external view returns (uint256[] memory);

    function getCreatorHouses(address creator) external view returns (uint256[] memory);

    function getHouseCreators(uint256 houseId) external view returns (address[] memory);

    function getSellerAuctions(address seller) external view returns (uint256[] memory);

    function getBidderAuctions(address bidder) external view returns (uint256[] memory);

    function getAuctionBids(uint256 auctionId) external view returns (uint256[] memory);

    function getPreviousAuctions(bytes32 tokenHash) external view returns (uint256[] memory);

    function getTokenOffers(bytes32 tokenHash) external view returns (uint256[] memory);

    function registerTokenContract(
        address tokenContract
    ) external;

    function makeOffer(
        address tokenContract,
        uint256 tokenId
    ) external payable;

    function acceptOffer(
        uint256 offerId
    ) external;

    function cancelOffer(
        uint256 offerId
    ) external;

    function createHouse(
        string  memory name,
        address curator,
        uint16  fee,
        bool    preApproved,
        string  memory metadata
    ) external;

    function addCreator(
        uint256 houseId,
        address creator
    ) external;

    function removeCreator(
        uint256 houseId,
        address creator
    ) external;

    function updateMetadata(
        uint256 houseId,
        string  memory metadata
    ) external;

    function updateFee(
        uint256 houseId,
        uint16  fee
    ) external;

    function updateName(
        string  memory name
    ) external;

    function updateBio(
        string  memory bioHash
    ) external;

    function updatePicture(
        string  memory pictureHash
    ) external;

    function createAuction(
        address tokenContract,
        uint256 tokenId,
        uint256 duration,
        uint256 reservePrice,
        uint256 houseId
    ) external;

    function setAuctionApproval(
        uint256 auctionId,
        bool approved
    ) external;

    function setAuctionReservePrice(
        uint256 auctionId,
        uint256 reservePrice
    ) external;

    function createBid(
        uint256 auctionId
    ) external payable;

    function endAuction(
        uint256 auctionId
    ) external;

    function buyAuction(
      uint256 auctionId
    ) external payable;

    function cancelAuction(
        uint256 auctionId
    ) external;

    function feature(
        uint256 auctionId,
        uint256 amount
    ) external;

    function cancelFeature(
        uint256 auctionId
    ) external;

    function updateHouseRank(
        uint256 houseId
    ) external;

    function updateCreatorRank(
        address creator
    ) external;

    function updateCollectorRank(
        address collector
    ) external;

    function updateContractRank(
        address tokenContract
    ) external;
}

File 5 of 13 : UintSet.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library UintSet {

    struct Set {
        // Storage of set values
        uint256[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(uint256 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Set storage set, uint256 value) internal returns (bool) {
        if (!contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Set storage set, uint256 value) internal returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                uint256 lastvalue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastvalue;
                // Update the index for the moved value
                set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Set storage set, uint256 value) internal view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(Set storage set) internal view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Set storage set, uint256 index) internal view returns (uint256) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Set storage set) internal view returns (uint256[] memory) {
        return set._values;
    }
}

File 6 of 13 : AddressSet.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `address` (`addressSet`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library AddressSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // address values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in address.

    struct Set {
        // Storage of set values
        address[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(address => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Set storage set, address value) internal returns (bool) {
        if (!contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Set storage set, address value) internal returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                address lastvalue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastvalue;
                // Update the index for the moved value
                set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Set storage set, address value) internal view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(Set storage set) internal view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Set storage set, uint256 index) internal view returns (address) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Set storage set) internal view returns (address[] memory) {
        return set._values;
    }
}

File 7 of 13 : OrderedSet.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title OrderedSet
 * @dev Ordered data structure. It has the properties of a mapping of uint256, but members are ordered
 * and can be enumerated. Values can be inserted and removed from anywhere. Add, append, remove and
 * contains are O(1). Enumerate is O(N).
 */
library OrderedSet {

    struct Set {
        uint256 count;
        mapping (uint256 => uint256) _next;
        mapping (uint256 => uint256) _prev;
    }

    /**
     * @dev Insert a value between two values
     */
    function insert(Set storage set, uint256 prev_, uint256 value, uint256 next_) internal {
        set._next[prev_] = value;
        set._next[value] = next_;
        set._prev[next_] = value;
        set._prev[value] = prev_;
        set.count += 1;
    }

    /**
     * @dev Insert a value as the new head
     */
    function add(Set storage set, uint256 value) internal {
        insert(set, 0, value, set._next[0]);
    }

    /**
     * @dev Insert a value as the new tail
     */
    function append(Set storage set, uint256 value) internal {
        insert(set, set._prev[0], value, 0);
    }

    /**
     * @dev Remove a value
     */
    function remove(Set storage set, uint256 value) internal {
        set._next[set._prev[value]] = set._next[value];
        set._prev[set._next[value]] = set._prev[value];
        delete set._next[value];
        delete set._prev[value];
        if (set.count > 0) {
            set.count -= 1;
        }
    }

    /**
     * @dev Returns the head
     */
    function head(Set storage set) internal view returns (uint256) {
        return set._next[0];
    }

    /**
     * @dev Returns the tail
     */
    function tail(Set storage set) internal view returns (uint256) {
        return set._prev[0];
    }

    /**
     * @dev Returns the length
     */
    function length(Set storage set) internal view returns (uint256) {
        return set.count;
    }

    /**
     * @dev Returns the next value
     */
    function next(Set storage set, uint256 _value) internal view returns (uint256) {
        return set._next[_value];
    }

    /**
     * @dev Returns the previous value
     */
    function prev(Set storage set, uint256 _value) internal view returns (uint256) {
        return set._prev[_value];
    }

    /**
     * @dev Returns true if the value is in the set
     */
    function contains(Set storage set, uint256 value) internal view returns (bool) {
        return set._next[0] == value ||
               set._next[value] != 0 ||
               set._prev[value] != 0;
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Set storage set) internal view returns (uint256[] memory) {
        uint256[] memory _values = new uint256[](set.count);
        uint256 value = set._next[0];
        uint256 i = 0;
        while (value != 0) {
            _values[i] = value;
            value = set._next[value];
            i += 1;
        }
        return _values;
    }

    /**
     * @dev Return an array with n values in the set, starting after "from"
     */
    function valuesFromN(Set storage set, uint256 from, uint256 n) internal view returns (uint256[] memory) {
        uint256[] memory _values = new uint256[](n);
        uint256 value = set._next[from];
        uint256 i = 0;
        while (i < n) {
            _values[i] = value;
            value = set._next[value];
            i += 1;
        }
        return _values;
    }
}

File 8 of 13 : RankedSet.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./OrderedSet.sol";

/**
 * @title RankedSet
 * @dev Ranked data structure using two ordered sets, a mapping of scores to
 * boundary values and counter, a mapping of last ranked scores, and a highest
 * score.
 */
library RankedSet {
    using OrderedSet for OrderedSet.Set;

    struct RankGroup {
        uint256 count;
        uint256 start;
        uint256 end;
    }

    struct Set {
        uint256 highScore;
        mapping(uint256 => RankGroup) rankgroups;
        mapping(uint256 => uint256) scores;
        OrderedSet.Set rankedScores;
        OrderedSet.Set rankedItems;
    }

    /**
     * @dev Add an item at the end of the set
     */
    function add(Set storage set, uint256 item) internal {
        set.rankedItems.append(item);
        set.rankgroups[0].end = item;
        set.rankgroups[0].count += 1;
        if (set.rankgroups[0].start == 0) {
            set.rankgroups[0].start = item;
        }
    }

    /**
     * @dev Remove an item
     */
    function remove(Set storage set, uint256 item) internal {
        uint256 score = set.scores[item];
        delete set.scores[item];

        RankGroup storage rankgroup = set.rankgroups[score];
        if (rankgroup.count > 0) {
            rankgroup.count -= 1;
        }

        if (rankgroup.count == 0) {
            rankgroup.start = 0;
            rankgroup.end = 0;
            if (score == set.highScore) {
                set.highScore = set.rankedScores.next(score);
            }
            if (score > 0) {
                set.rankedScores.remove(score);
            }
        } else {
            if (rankgroup.start == item) {
                rankgroup.start = set.rankedItems.next(item);
            }
            if (rankgroup.end == item) {
                rankgroup.end = set.rankedItems.prev(item);
            }
        }

        set.rankedItems.remove(item);
    }

    /**
     * @dev Returns the head
     */
    function head(Set storage set) internal view returns (uint256) {
        return set.rankedItems._next[0];
    }

    /**
     * @dev Returns the tail
     */
    function tail(Set storage set) internal view returns (uint256) {
        return set.rankedItems._prev[0];
    }

    /**
     * @dev Returns the length
     */
    function length(Set storage set) internal view returns (uint256) {
        return set.rankedItems.count;
    }

    /**
     * @dev Returns the next value
     */
    function next(Set storage set, uint256 _value) internal view returns (uint256) {
        return set.rankedItems._next[_value];
    }

    /**
     * @dev Returns the previous value
     */
    function prev(Set storage set, uint256 _value) internal view returns (uint256) {
        return set.rankedItems._prev[_value];
    }

    /**
     * @dev Returns true if the value is in the set
     */
    function contains(Set storage set, uint256 value) internal view returns (bool) {
        return set.rankedItems._next[0] == value ||
               set.rankedItems._next[value] != 0 ||
               set.rankedItems._prev[value] != 0;
    }

    /**
     * @dev Returns a value's score
     */
    function scoreOf(Set storage set, uint256 value) internal view returns (uint256) {
        return set.scores[value];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Set storage set) internal view returns (uint256[] memory) {
        uint256[] memory _values = new uint256[](set.rankedItems.count);
        uint256 value = set.rankedItems._next[0];
        uint256 i = 0;
        while (value != 0) {
            _values[i] = value;
            value = set.rankedItems._next[value];
            i += 1;
        }
        return _values;
    }

    /**
     * @dev Return an array with n values in the set, starting after "from"
     */
    function valuesFromN(Set storage set, uint256 from, uint256 n) internal view returns (uint256[] memory) {
        uint256[] memory _values = new uint256[](n);
        uint256 value = set.rankedItems._next[from];
        uint256 i = 0;
        while (i < n) {
            _values[i] = value;
            value = set.rankedItems._next[value];
            i += 1;
        }
        return _values;
    }

    /**
     * @dev Rank new score
     */
    function rankScore(Set storage set, uint256 item, uint256 newScore) internal {
        RankGroup storage rankgroup = set.rankgroups[newScore];

        if (newScore > set.highScore) {
            remove(set, item);
            rankgroup.start = item;
            set.highScore = newScore;
            set.rankedItems.add(item);
            set.rankedScores.add(newScore);
        } else {
            uint256 score = set.scores[item];
            uint256 prevScore = set.rankedScores.prev(score);

            if (set.rankgroups[score].count == 1) {
                score = set.rankedScores.next(score);
            }

            remove(set, item);

            while (prevScore > 0 && newScore > prevScore) {
                prevScore = set.rankedScores.prev(prevScore);
            }

            set.rankedItems.insert(
                set.rankgroups[prevScore].end,
                item,
                set.rankgroups[set.rankedScores.next(prevScore)].start
            );

            if (rankgroup.count == 0) {
                set.rankedScores.insert(prevScore, newScore, score);
                rankgroup.start = item;
            }
        }

        rankgroup.end = item;
        rankgroup.count += 1;

        set.scores[item] = newScore;
    }
}

File 9 of 13 : RankedAddressSet.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./OrderedSet.sol";
import "./OrderedAddressSet.sol";

/**
 * @title RankedSet
 * @dev Ranked data structure using two ordered sets, a mapping of scores to
 * boundary values, a mapping of last ranked scores, and a highest score.
 */
library RankedAddressSet {
    using OrderedSet for OrderedSet.Set;
    using OrderedAddressSet for OrderedAddressSet.Set;

    struct RankGroup {
        uint256 count;
        address start;
        address end;
    }

    struct Set {
        uint256 highScore;
        mapping(uint256 => RankGroup) rankgroups;
        mapping(address => uint256) scores;
        OrderedSet.Set rankedScores;
        OrderedAddressSet.Set rankedItems;
    }

    /**
     * @dev Add an item at the end of the set
     */
    function add(Set storage set, address item) internal {
        set.rankedItems.append(item);
        set.rankgroups[0].end = item;
        set.rankgroups[0].count += 1;
        if (set.rankgroups[0].start == address(0)) {
            set.rankgroups[0].start = item;
        }
    }

    /**
     * @dev Remove an item
     */
    function remove(Set storage set, address item) internal {
        uint256 score = set.scores[item];
        delete set.scores[item];

        RankGroup storage rankgroup = set.rankgroups[score];
        if (rankgroup.count > 0) {
            rankgroup.count -= 1;
        }

        if (rankgroup.count == 0) {
            rankgroup.start = address(0);
            rankgroup.end = address(0);
            if (score == set.highScore) {
                set.highScore = set.rankedScores.next(score);
            }
            if (score > 0) {
                set.rankedScores.remove(score);
            }
        } else {
            if (rankgroup.start == item) {
                rankgroup.start = set.rankedItems.next(item);
            }
            if (rankgroup.end == item) {
                rankgroup.end = set.rankedItems.prev(item);
            }
        }

        set.rankedItems.remove(item);
    }

    /**
     * @dev Returns the head
     */
    function head(Set storage set) internal view returns (address) {
        return set.rankedItems._next[address(0)];
    }

    /**
     * @dev Returns the tail
     */
    function tail(Set storage set) internal view returns (address) {
        return set.rankedItems._prev[address(0)];
    }

    /**
     * @dev Returns the length
     */
    function length(Set storage set) internal view returns (uint256) {
        return set.rankedItems.count;
    }

    /**
     * @dev Returns the next value
     */
    function next(Set storage set, address _value) internal view returns (address) {
        return set.rankedItems._next[_value];
    }

    /**
     * @dev Returns the previous value
     */
    function prev(Set storage set, address _value) internal view returns (address) {
        return set.rankedItems._prev[_value];
    }

    /**
     * @dev Returns true if the value is in the set
     */
    function contains(Set storage set, address value) internal view returns (bool) {
        return set.rankedItems._next[address(0)] == value ||
               set.rankedItems._next[value] != address(0) ||
               set.rankedItems._prev[value] != address(0);
    }

    /**
     * @dev Returns a value's score
     */
    function scoreOf(Set storage set, address value) internal view returns (uint256) {
        return set.scores[value];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Set storage set) internal view returns (address[] memory) {
        address[] memory _values = new address[](set.rankedItems.count);
        address value = set.rankedItems._next[address(0)];
        uint256 i = 0;
        while (value != address(0)) {
            _values[i] = value;
            value = set.rankedItems._next[value];
            i += 1;
        }
        return _values;
    }

    /**
     * @dev Return an array with n values in the set, starting after "from"
     */
    function valuesFromN(Set storage set, address from, uint256 n) internal view returns (address[] memory) {
        address[] memory _values = new address[](n);
        address value = set.rankedItems._next[from];
        uint256 i = 0;
        while (i < n) {
            _values[i] = value;
            value = set.rankedItems._next[value];
            i += 1;
        }
        return _values;
    }

    /**
     * @dev Rank new score
     */
    function rankScore(Set storage set, address item, uint256 newScore) internal {
        RankGroup storage rankgroup = set.rankgroups[newScore];

        if (newScore > set.highScore) {
            remove(set, item);
            rankgroup.start = item;
            set.highScore = newScore;
            set.rankedItems.add(item);
            set.rankedScores.add(newScore);
        } else {
            uint256 score = set.scores[item];
            uint256 prevScore = set.rankedScores.prev(score);

            if (set.rankgroups[score].count == 1) {
                score = set.rankedScores.next(score);
            }

            remove(set, item);

            while (prevScore > 0 && newScore > prevScore) {
                prevScore = set.rankedScores.prev(prevScore);
            }

            set.rankedItems.insert(
                set.rankgroups[prevScore].end,
                item,
                set.rankgroups[set.rankedScores.next(prevScore)].start
            );

            if (rankgroup.count == 0) {
                set.rankedScores.insert(prevScore, newScore, score);
                rankgroup.start = item;
            }
        }

        rankgroup.end = item;
        rankgroup.count += 1;

        set.scores[item] = newScore;
    }
}

File 10 of 13 : IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

File 11 of 13 : IERC721Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

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

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

pragma solidity ^0.8.0;

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

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

pragma solidity ^0.8.0;

/**
 * @title OrderedSet
 * @dev Ordered data structure. It has the properties of a mapping of uint256, but members are ordered
 * and can be enumerated. Values can be inserted and removed from anywhere. Add, append, remove and
 * contains are O(1). Enumerate is O(N).
 */
library OrderedAddressSet {

    struct Set {
        uint256 count;
        mapping (address => address) _next;
        mapping (address => address) _prev;
    }

    /**
     * @dev Insert a value between two values
     */
    function insert(Set storage set, address prev_, address value, address next_) internal {
        set._next[prev_] = value;
        set._next[value] = next_;
        set._prev[next_] = value;
        set._prev[value] = prev_;
        set.count += 1;
    }

    /**
     * @dev Insert a value as the new head
     */
    function add(Set storage set, address value) internal {
        insert(set, address(0), value, set._next[address(0)]);
    }

    /**
     * @dev Insert a value as the new tail
     */
    function append(Set storage set, address value) internal {
        insert(set, set._prev[address(0)], value, address(0));
    }

    /**
     * @dev Remove a value
     */
    function remove(Set storage set, address value) internal {
        set._next[set._prev[value]] = set._next[value];
        set._prev[set._next[value]] = set._prev[value];
        delete set._next[value];
        delete set._prev[value];
        if (set.count > 0) {
            set.count -= 1;
        }
    }

    /**
     * @dev Returns the head
     */
    function head(Set storage set) internal view returns (address) {
        return set._next[address(0)];
    }

    /**
     * @dev Returns the tail
     */
    function tail(Set storage set) internal view returns (address) {
        return set._prev[address(0)];
    }

    /**
     * @dev Returns the length
     */
    function length(Set storage set) internal view returns (uint256) {
        return set.count;
    }

    /**
     * @dev Returns the next value
     */
    function next(Set storage set, address _value) internal view returns (address) {
        return set._next[_value];
    }

    /**
     * @dev Returns the previous value
     */
    function prev(Set storage set, address _value) internal view returns (address) {
        return set._prev[_value];
    }

    /**
     * @dev Returns true if the value is in the set
     */
    function contains(Set storage set, address value) internal view returns (bool) {
        return set._next[address(0)] == value ||
               set._next[value] != address(0) ||
               set._prev[value] != address(0);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Set storage set) internal view returns (address[] memory) {
        address[] memory _values = new address[](set.count);
        address value = set._next[address(0)];
        uint256 i = 0;
        while (value != address(0)) {
            _values[i] = value;
            value = set._next[value];
            i += 1;
        }
        return _values;
    }

    /**
     * @dev Return an array with n values in the set, starting after "from"
     */
    function valuesFromN(Set storage set, address from, uint256 n) internal view returns (address[] memory) {
        address[] memory _values = new address[](n);
        address value = set._next[from];
        uint256 i = 0;
        while (i < n) {
            _values[i] = value;
            value = set._next[value];
            i += 1;
        }
        return _values;
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"tuxERC20_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"AccountUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"auctionId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"AuctionApprovalUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"auctionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"bidder","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bool","name":"firstBid","type":"bool"},{"indexed":false,"internalType":"bool","name":"extended","type":"bool"}],"name":"AuctionBid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"auctionId","type":"uint256"}],"name":"AuctionCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"auctionId","type":"uint256"}],"name":"AuctionCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"auctionId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"AuctionDurationExtended","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"auctionId","type":"uint256"}],"name":"AuctionEnded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"auctionId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reservePrice","type":"uint256"}],"name":"AuctionReservePriceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"houseId","type":"uint256"},{"indexed":true,"internalType":"address","name":"creator","type":"address"}],"name":"CreatorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"houseId","type":"uint256"},{"indexed":true,"internalType":"address","name":"creator","type":"address"}],"name":"CreatorRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"houseId","type":"uint256"},{"indexed":false,"internalType":"uint16","name":"fee","type":"uint16"}],"name":"FeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"houseId","type":"uint256"}],"name":"HouseCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"houseId","type":"uint256"},{"indexed":false,"internalType":"string","name":"metadata","type":"string"}],"name":"MetadataUpdated","type":"event"},{"inputs":[{"internalType":"uint256","name":"offerId","type":"uint256"}],"name":"acceptOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"accounts","outputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"bioHash","type":"string"},{"internalType":"string","name":"pictureHash","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"houseId","type":"uint256"},{"internalType":"address","name":"creator","type":"address"}],"name":"addCreator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"auctions","outputs":[{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"tokenOwner","type":"address"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"reservePrice","type":"uint256"},{"internalType":"uint256","name":"houseId","type":"uint256"},{"internalType":"uint16","name":"fee","type":"uint16"},{"internalType":"bool","name":"approved","type":"bool"},{"internalType":"uint256","name":"firstBidTime","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"bidder","type":"address"},{"internalType":"uint256","name":"created","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"bids","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"address","name":"bidder","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"auctionId","type":"uint256"}],"name":"buyAuction","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"auctionId","type":"uint256"}],"name":"cancelAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"auctionId","type":"uint256"}],"name":"cancelFeature","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerId","type":"uint256"}],"name":"cancelOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"collectorStats","outputs":[{"internalType":"uint256","name":"bids","type":"uint256"},{"internalType":"uint256","name":"sales","type":"uint256"},{"internalType":"uint256","name":"bought","type":"uint256"},{"internalType":"uint256","name":"totalSold","type":"uint256"},{"internalType":"uint256","name":"totalSpent","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"contracts","outputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"bids","type":"uint256"},{"internalType":"uint256","name":"sales","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"reservePrice","type":"uint256"},{"internalType":"uint256","name":"houseId","type":"uint256"}],"name":"createAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"auctionId","type":"uint256"}],"name":"createBid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"curator","type":"address"},{"internalType":"uint16","name":"fee","type":"uint16"},{"internalType":"bool","name":"preApproved","type":"bool"},{"internalType":"string","name":"metadata","type":"string"}],"name":"createHouse","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"creatorStats","outputs":[{"internalType":"uint256","name":"bids","type":"uint256"},{"internalType":"uint256","name":"sales","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"auctionId","type":"uint256"}],"name":"endAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"auctionId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"feature","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"from","type":"uint256"},{"internalType":"uint256","name":"n","type":"uint256"}],"name":"getActiveHouses","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"auctionId","type":"uint256"}],"name":"getAuctionBids","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"from","type":"uint256"},{"internalType":"uint256","name":"n","type":"uint256"}],"name":"getAuctions","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"bidder","type":"address"}],"name":"getBidderAuctions","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"creator","type":"address"}],"name":"getCollections","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"creator","type":"address"}],"name":"getCreatorHouses","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"curator","type":"address"}],"name":"getCuratorHouses","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"houseId","type":"uint256"},{"internalType":"uint256","name":"from","type":"uint256"},{"internalType":"uint256","name":"n","type":"uint256"}],"name":"getHouseAuctions","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"houseId","type":"uint256"}],"name":"getHouseCreators","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"houseId","type":"uint256"}],"name":"getHouseQueue","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"tokenHash","type":"bytes32"}],"name":"getPreviousAuctions","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"n","type":"uint256"}],"name":"getRankedCollectors","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"n","type":"uint256"}],"name":"getRankedContracts","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"n","type":"uint256"}],"name":"getRankedCreators","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"from","type":"uint256"},{"internalType":"uint256","name":"n","type":"uint256"}],"name":"getRankedHouses","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"seller","type":"address"}],"name":"getSellerAuctions","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"tokenHash","type":"bytes32"}],"name":"getTokenOffers","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"houseIDs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"houses","outputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address payable","name":"curator","type":"address"},{"internalType":"uint16","name":"fee","type":"uint16"},{"internalType":"bool","name":"preApproved","type":"bool"},{"internalType":"string","name":"metadata","type":"string"},{"internalType":"uint256","name":"bids","type":"uint256"},{"internalType":"uint256","name":"sales","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"feesTotal","type":"uint256"},{"internalType":"uint256","name":"activeAuctions","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"makeOffer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"minimumIncrementPercentage","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"offers","outputs":[{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"}],"name":"registerTokenContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"houseId","type":"uint256"},{"internalType":"address","name":"creator","type":"address"}],"name":"removeCreator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"auctionId","type":"uint256"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setAuctionApproval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"auctionId","type":"uint256"},{"internalType":"uint256","name":"reservePrice","type":"uint256"}],"name":"setAuctionReservePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"timeBuffer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"tokenAuction","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalActiveAuctions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"houseId","type":"uint256"}],"name":"totalActiveHouseAuctions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalActiveHouses","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAuctions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalCollectors","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalContracts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalCreators","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalHouses","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tuxERC20","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"bioHash","type":"string"}],"name":"updateBio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collector","type":"address"}],"name":"updateCollectorRank","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"}],"name":"updateContractRank","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"creator","type":"address"}],"name":"updateCreatorRank","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"houseId","type":"uint256"},{"internalType":"uint16","name":"fee","type":"uint16"}],"name":"updateFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"houseId","type":"uint256"}],"name":"updateHouseRank","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"houseId","type":"uint256"},{"internalType":"string","name":"metadata","type":"string"}],"name":"updateMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"updateName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"pictureHash","type":"string"}],"name":"updatePicture","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b5060405162005e2e38038062005e2e83398101604081905262000034916200005a565b600480546001600160a01b0319166001600160a01b03929092169190911790556200008c565b6000602082840312156200006d57600080fd5b81516001600160a01b03811681146200008557600080fd5b9392505050565b615d92806200009c6000396000f3fe6080604052600436106103385760003560e01c8063745ab66e116101b2578063b2a4706e116100ed578063e244d47811610090578063e244d47814610c84578063e638ebfb14610ca4578063e786646714610cc4578063ec91f2a414610ce4578063ef706adf14610cfa578063f7b0770b14610d1a578063fd8acc4214610d3a578063fe892e6014610d4d57600080fd5b8063b2a4706e14610b9c578063b9a2de3a14610baf578063c128fc4914610bcf578063c7bccac014610be4578063c815729d14610c04578063ceb6a22f14610c24578063d219cfba14610c44578063dafdb1e014610c6457600080fd5b806396eed5601161015557806396eed56014610a8f578063973ddb4a14610abc578063976d577014610adc57806399d2813514610afc578063a09037a914610b1c578063a7fe508b14610b31578063aeda852f14610b46578063b03a4dfe14610b7c57600080fd5b8063745ab66e146109085780637502d7ae1461092857806376487b3814610948578063806139741461096857806384da92a7146109a05780638a72ea6a146109c0578063961c9ae414610a4f57806396b5a75514610a6f57600080fd5b80634163faab1161028257806362910b591161022557806362910b5914610804578063659dd2b41461082457806369ce5d871461083757806369dc9ff3146108575780636f8a41e1146108885780637091d2d3146108a857806370b4768e146108c857806372e93ee8146108e857600080fd5b80634163faab1461056f5780634423c5f11461058f5780634693fcae146105f757806353c8388e1461061757806356d0b82d14610637578063571a26a0146106605780635e5c06e214610763578063603737751461079257600080fd5b8063162d8afb116102ea578063162d8afb1461043657806316a50e941461044b5780632adeee26146104605780632e24c5871461048057806331bcaa99146104d7578063374fea91146104f7578063393a7161146105175780633b7def961461053757600080fd5b806306a992981461033d57806309e6a4b91461035f57806311c0036c14610395578063127f1498146103b45780631328c5b3146103e1578063154df9f51461040157806316002f4a14610421575b600080fd5b34801561034957600080fd5b5061035d610358366004615502565b610d6d565b005b34801561036b57600080fd5b5061037f61037a366004615536565b610dc2565b60405161038c9190615562565b60405180910390f35b3480156103a157600080fd5b506029545b60405190815260200161038c565b3480156103c057600080fd5b506103d46103cf3660046155bb565b610deb565b60405161038c91906155d8565b3480156103ed57600080fd5b506103a66103fc366004615619565b610e15565b34801561040d57600080fd5b5061035d61041c366004615619565b610e29565b34801561042d57600080fd5b506003546103a6565b34801561044257600080fd5b506002546103a6565b34801561045757600080fd5b506103a6610ed1565b34801561046c57600080fd5b5061035d61047b366004615657565b610edc565b34801561048c57600080fd5b506104bc61049b3660046155bb565b600d6020526000908152604090208054600182015460029092015490919083565b6040805193845260208401929092529082015260600161038c565b3480156104e357600080fd5b5061035d6104f23660046155bb565b611211565b34801561050357600080fd5b5061035d6105123660046156f5565b6112b8565b34801561052357600080fd5b506103d4610532366004615725565b6113c5565b34801561054357600080fd5b50600454610557906001600160a01b031681565b6040516001600160a01b03909116815260200161038c565b34801561057b57600080fd5b5061035d61058a366004615751565b6113da565b34801561059b57600080fd5b506105d46105aa366004615619565b600a6020526000908152604090208054600182015460029092015490916001600160a01b03169083565b604080519384526001600160a01b0390921660208401529082015260600161038c565b34801561060357600080fd5b5061037f610612366004615751565b611480565b34801561062357600080fd5b5061035d610632366004615773565b61148e565b34801561064357600080fd5b5061064d6101f481565b60405161ffff909116815260200161038c565b34801561066c57600080fd5b506106ee61067b366004615619565b600860208190526000918252604090912080546001820154600283015460038401546004850154600586015460068701546007880154988801546009890154600a909901546001600160a01b039889169a97999689169895979496939561ffff8416956201000090940460ff169416908c565b604080516001600160a01b039d8e168152602081019c909c52998c16998b019990995260608a0197909752608089019590955260a088019390935261ffff90911660c0870152151560e0860152610100850152610120840152929092166101408201526101608101919091526101800161038c565b34801561076f57600080fd5b5061078361077e3660046155bb565b61152c565b60405161038c93929190615811565b34801561079e57600080fd5b506107dc6107ad3660046155bb565b600e60205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b604080519586526020860194909452928401919091526060830152608082015260a00161038c565b34801561081057600080fd5b5061037f61081f3660046155bb565b6116e6565b61035d610832366004615619565b61170a565b34801561084357600080fd5b5061037f6108523660046155bb565b611d1a565b34801561086357600080fd5b506108776108723660046155bb565b611d3e565b60405161038c959493929190615854565b34801561089457600080fd5b5061035d6108a3366004615751565b611dff565b3480156108b457600080fd5b506103d46108c3366004615725565b611ed6565b3480156108d457600080fd5b5061037f6108e3366004615619565b611ee4565b3480156108f457600080fd5b5061037f6109033660046155bb565b611efe565b34801561091457600080fd5b5061037f610923366004615619565b611f22565b34801561093457600080fd5b5061035d610943366004615894565b611f3c565b34801561095457600080fd5b5061035d610963366004615502565b611ffe565b34801561097457600080fd5b506103a6610983366004615502565b805160208183018101805160058252928201919093012091525481565b3480156109ac57600080fd5b5061035d6109bb366004615502565b612024565b3480156109cc57600080fd5b50610a166109db366004615619565b600b60205260009081526040902080546001820154600283015460038401546004909401546001600160a01b03938416949293909116919085565b604080516001600160a01b039687168152602081019590955292909416918301919091526060820152608081019190915260a00161038c565b348015610a5b57600080fd5b5061035d610a6a3660046158c0565b612044565b348015610a7b57600080fd5b5061035d610a8a366004615619565b612799565b348015610a9b57600080fd5b506103a6610aaa366004615619565b60066020526000908152604090205481565b348015610ac857600080fd5b5061035d610ad7366004615904565b61286b565b348015610ae857600080fd5b5061035d610af73660046156f5565b612acc565b348015610b0857600080fd5b5061035d610b173660046155bb565b612c3e565b348015610b2857600080fd5b50603b546103a6565b348015610b3d57600080fd5b506032546103a6565b348015610b5257600080fd5b50610b66610b61366004615619565b612ca6565b60405161038c9a99989796959493929190615929565b348015610b8857600080fd5b5061035d610b97366004615619565b612e1c565b61035d610baa366004615725565b612e77565b348015610bbb57600080fd5b5061035d610bca366004615619565b6130b9565b348015610bdb57600080fd5b506103a661386c565b348015610bf057600080fd5b506103d4610bff366004615725565b613877565b348015610c1057600080fd5b5061035d610c1f366004615619565b613885565b348015610c3057600080fd5b5061037f610c3f366004615751565b613b94565b348015610c5057600080fd5b5061035d610c5f3660046155bb565b613ba2565b348015610c7057600080fd5b5061037f610c7f366004615751565b613c0a565b348015610c9057600080fd5b5061037f610c9f366004615619565b613c18565b348015610cb057600080fd5b506103d4610cbf366004615619565b613c32565b348015610cd057600080fd5b5061037f610cdf366004615619565b613c4c565b348015610cf057600080fd5b506103a661038481565b348015610d0657600080fd5b5061035d610d15366004615619565b613c66565b348015610d2657600080fd5b5061035d610d353660046155bb565b613d6b565b61035d610d48366004615619565b61418d565b348015610d5957600080fd5b5061037f610d683660046155bb565b6141a2565b336000908152600c602090815260409091208251610d93926002909201918401906153a6565b5060405133907fe7b1fae3a790ceab07642c09617df79428b02832cd512bbfdd4db50272dcdf3090600090a250565b6000838152601260205260409020606090610dde9084846141c6565b949350505050565b905090565b6001600160a01b0381166000908152600f60205260409020606090610e0f9061427f565b92915050565b600081815260126020526040812054610e0f565b6000818152600860205260409020600201546001600160a01b03163314610e6b5760405162461bcd60e51b8152600401610e62906159a2565b60405180910390fd5b600480546040516315f5a0b160e21b81529182018390523360248301526001600160a01b0316906357d682c4906044015b600060405180830381600087803b158015610eb657600080fd5b505af1158015610eca573d6000803e3d6000fd5b5050505050565b6000610de6603e5490565b600585604051610eec91906159cb565b908152602001604051809103902054600014610f3b5760405162461bcd60e51b815260206004820152600e60248201526d416c72656164792065786973747360901b6044820152606401610e62565b6000855111610f7c5760405162461bcd60e51b815260206004820152600d60248201526c13985b59481c995c5d5a5c9959609a1b6044820152606401610e62565b602085511115610fbe5760405162461bcd60e51b815260206004820152600d60248201526c4e616d6520746f6f206c6f6e6760981b6044820152606401610e62565b6001600160a01b0384166110075760405162461bcd60e51b815260206004820152601060248201526f1059191c995cdcc81c995c5d5a5c995960821b6044820152606401610e62565b6127108361ffff161061102c5760405162461bcd60e51b8152600401610e62906159e7565b60016002600082825461103f9190615a23565b909155505060025460008181526009602090815260409091208751611066928901906153a6565b5060008181526009602090815260409091206001810180546001600160a01b0389166001600160b01b031990911617600160a01b61ffff8916021760ff60b01b1916600160b01b8715150217905583516110c8926002909201918501906153a6565b506001600160a01b03851660009081526013602052604090206110eb90826142e5565b506110f7601a82614334565b8060058760405161110891906159cb565b90815260408051918290036020018220929092556004805463939ddf5960e01b835292516001600160a01b039093169263939ddf5992828101926000929182900301818387803b15801561115b57600080fd5b505af115801561116f573d6000803e3d6000fd5b5050600480546040516340c10f1960e01b81526001600160a01b0390911693506340c10f1992506111ac913391674563918244f400009101615a3b565b600060405180830381600087803b1580156111c657600080fd5b505af11580156111da573d6000803e3d6000fd5b50506040518392507f3ef0dde97fa0cc56206f591c9007c69a72f6c75af7e50510fc815b58bbb5434c9150600090a2505050505050565b6001600160a01b03811660009081526007602052604090206002015461123860358361439e565b106112555760405162461bcd60e51b8152600401610e6290615a54565b6001600160a01b03811660009081526007602052604090206002015461127f9060359083906143bd565b600480546040516340c10f1960e01b81526001600160a01b03909116916340c10f1991610e9c913391670de0b6b3a76400009101615a3b565b60008281526009602052604090206001015482906001600160a01b031633146112f35760405162461bcd60e51b8152600401610e6290615a7d565b600083815260156020526040902061130b908361457f565b151560011461134e5760405162461bcd60e51b815260206004820152600f60248201526e105b1c9958591e481c995b5bdd9959608a1b6044820152606401610e62565b600083815260156020526040902061136690836145a0565b506001600160a01b038216600090815260146020526040902061138990846146d6565b506040516001600160a01b0383169084907f7efbfc4ea79118ce5c257ac41ccdcea63de279540e4ba7d10a38072523a05d4f90600090a3505050565b60606113d3602c84846147bf565b9392505050565b6000828152600860205260409020600201546001600160a01b031633146114135760405162461bcd60e51b8152600401610e62906159a2565b600480546040516334c77f8760e01b8152918201849052602482018390523360448301526001600160a01b0316906334c77f8790606401600060405180830381600087803b15801561146457600080fd5b505af1158015611478573d6000803e3d6000fd5b505050505050565b60606113d3601a8484614888565b60008281526009602052604090206001015482906001600160a01b031633146114c95760405162461bcd60e51b8152600401610e6290615a7d565b600083815260096020908152604090912083516114ee926002909201918501906153a6565b50827f459157ba24c7ab9878b165ef465fa6ae2ab42bcd8445f576be378768b0c473098360405161151f9190615aa8565b60405180910390a2505050565b600c6020526000908152604090208054819061154790615abb565b80601f016020809104026020016040519081016040528092919081815260200182805461157390615abb565b80156115c05780601f10611595576101008083540402835291602001916115c0565b820191906000526020600020905b8154815290600101906020018083116115a357829003601f168201915b5050505050908060010180546115d590615abb565b80601f016020809104026020016040519081016040528092919081815260200182805461160190615abb565b801561164e5780601f106116235761010080835404028352916020019161164e565b820191906000526020600020905b81548152906001019060200180831161163157829003601f168201915b50505050509080600201805461166390615abb565b80601f016020809104026020016040519081016040528092919081815260200182805461168f90615abb565b80156116dc5780601f106116b1576101008083540402835291602001916116dc565b820191906000526020600020905b8154815290600101906020018083116116bf57829003601f168201915b5050505050905083565b6001600160a01b0381166000908152601760205260409020606090610e0f90614931565b60008181526008602052604090206002015481906001600160a01b03166117435760405162461bcd60e51b8152600401610e6290615af6565b6000828152600860205260409020600681015462010000900460ff1661177b5760405162461bcd60e51b8152600401610e6290615b1e565b6007810154158061179e57508060030154816007015461179b9190615a23565b42105b6117dc5760405162461bcd60e51b815260206004820152600f60248201526e105d58dd1a5bdb88195e1c1a5c9959608a1b6044820152606401610e62565b6008810154612710906117f2906101f490615b4f565b6117fc9190615b6e565b816008015461180b9190615a23565b34101561184b5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b6044820152606401610e62565b80600401543410156118995760405162461bcd60e51b81526020600482015260176024820152764269642062656c6f77207265736572766520707269636560481b6044820152606401610e62565b60098101546001600160a01b0316600181156118b3575060005b60078301546118c7574260078401556118da565b806118da576118da82846008015461498c565b3460088401556009830180546001600160a01b031916331790556003830154156119a35760016000808282546119109190615a23565b9091555050600080546040805160608101825242815233602080830191825234838501908152858752600a82528487209351845591516001840180546001600160a01b0319166001600160a01b0390921691909117905590516002909201919091558884526011905290912061198690826142e5565b503360009081526017602052604090206119a090876142e5565b50505b82546001600160a01b031660009081526007602052604081206002018054600192906119d0908490615a23565b909155505082546001840154604051631030681960e21b81526001600160a01b03909216916340c1a06491611a0b9160040190815260200190565b60206040518083038186803b158015611a2357600080fd5b505afa925050508015611a53575060408051601f3d908101601f19168201909252611a5091810190615b90565b60015b611a5c57611aa9565b60028401546001600160a01b0382811691161415611aa75760028401546001600160a01b03166000908152600d60205260408120805460019290611aa1908490615a23565b90915550505b505b336000908152600e6020526040902054611ac857611ac8602c336149d8565b336000908152600e60205260408120805460019290611ae8908490615a23565b9091555050600583015415611b5d5760058301546000908152600960205260408120600301805460019290611b1e908490615a23565b909155505060058301546000908152601260205260409020611b409086614a7c565b60058301546000908152601260205260409020611b5d9086614ae2565b600383015460009015611bc25760004285600301548660070154611b819190615a23565b611b8b9190615bad565b9050610384811015611bc057611ba381610384615bad565b856003016000828254611bb69190615a23565b9091555060019250505b505b600480546040805163939ddf5960e01b815290516001600160a01b039092169263939ddf5992828201926000929082900301818387803b158015611c0557600080fd5b505af1158015611c19573d6000803e3d6000fd5b5050600480546040516340c10f1960e01b81526001600160a01b0390911693506340c10f199250611c56913391678ac7230489e800009101615a3b565b600060405180830381600087803b158015611c7057600080fd5b505af1158015611c84573d6000803e3d6000fd5b50506040805134815285151560208201528415158183015290513393508992507fac7b4956ef620044e10f430450c0069d356507570c460567101eebac99165c0a9181900360600190a3801561147857857f8fdd260941d3b80e0b9ee888471b99a809d93315f1c2ccd41ac35dbfd64f22698560030154604051611d0a91815260200190565b60405180910390a2505050505050565b6001600160a01b0381166000908152601660205260409020606090610e0f90614931565b600760205260009081526040902080548190611d5990615abb565b80601f0160208091040260200160405190810160405280929190818152602001828054611d8590615abb565b8015611dd25780601f10611da757610100808354040283529160200191611dd2565b820191906000526020600020905b815481529060010190602001808311611db557829003601f168201915b5050505060018301546002840154600385015460049095015493946001600160a01b039092169390925085565b60008281526008602052604090206002015482906001600160a01b0316611e385760405162461bcd60e51b8152600401610e6290615af6565b600083815260086020526040902060028101546001600160a01b03163314611e725760405162461bcd60e51b8152600401610e62906159a2565b600781015415611e945760405162461bcd60e51b8152600401610e6290615bc4565b6004810183905560405183815284907fd44c1f367e4b7835166bd3805433cc6133391fa6e0099d7303ec10205c9efcb89060200160405180910390a250505050565b60606113d3603584846147bf565b6000818152601160205260409020606090610e0f90614931565b6001600160a01b0381166000908152601360205260409020606090610e0f90614931565b6000818152601860205260409020606090610e0f90614931565b60008281526009602052604090206001015482906001600160a01b03163314611f775760405162461bcd60e51b8152600401610e6290615a7d565b6127108261ffff1610611f9c5760405162461bcd60e51b8152600401610e62906159e7565b600083815260096020908152604091829020600101805461ffff60a01b1916600160a01b61ffff871690810291909117909155915191825284917fa20d223dfabc409c327adda1eca96fc2d4f1d446eac9110e8225d4a529489ffd910161151f565b336000908152600c602090815260409091208251610d93926001909201918401906153a6565b336000908152600c602090815260409091208251610d93928401906153a6565b6001600160a01b038581166000908152600760205260409020600101541661206f5761206f85613d6b565b6040516331a9108f60e11b8152600481018590526000906001600160a01b03871690636352211e9060240160206040518083038186803b1580156120b257600080fd5b505afa1580156120c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ea9190615b90565b9050336001600160a01b038216148061218b575060405163020604bf60e21b8152600481018690526001600160a01b0387169063081812fc9060240160206040518083038186803b15801561213e57600080fd5b505afa158015612152573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121769190615b90565b6001600160a01b0316336001600160a01b0316145b6121a75760405162461bcd60e51b8152600401610e6290615bed565b600060018184156122a357506000848152600960205260409020600101546001600160a01b0316806122125760405162461bcd60e51b8152602060048201526014602482015273121bdd5cd948191bd95cc81b9bdd08195e1a5cdd60621b6044820152606401610e62565b600085815260156020526040902061222a908561457f565b8061223d5750336001600160a01b038216145b6122595760405162461bcd60e51b8152600401610e6290615b1e565b600085815260096020526040812060018082015460079092018054600160a01b840461ffff169750600160b01b90930460ff1695509092909161229d908490615a23565b90915550505b604051631030681960e21b8152600481018990526001600160a01b038a16906340c1a0649060240160206040518083038186803b1580156122e357600080fd5b505afa925050508015612313575060408051601f3d908101601f1916820190925261231091810190615b90565b60015b61231c57612338565b612327602382614b00565b612336576123366023826149d8565b505b60016003600082825461234b9190615a23565b9091555050600354604051819060069060009061236e908e908e90602001615a3b565b60408051601f1981840301815291815281516020928301208352828201939093529082016000908120939093556001600160a01b03881683526016905290206123b790826142e5565b5060006001600160a01b03831615806123cd5750835b806123e95750856001600160a01b0316836001600160a01b0316145b9050861561248e57600181151514156124705760008781526012602052604090206124149083614ae2565b60008052603f6020527fe9090a6e551363283803e59daf1c144cd0ac55c420ac8519a53d83ef396a73b354871461246b57612450603e88614b71565b1561246057612460603e88614a7c565b61246b603e88614ae2565b612499565b600087815260106020526040902061248890836142e5565b50612499565b612499604183614ae2565b6040518061018001604052808c6001600160a01b031681526020018b8152602001876001600160a01b031681526020018a81526020018981526020018881526020018661ffff1681526020018215158152602001600081526020016000815260200160006001600160a01b03168152602001428152506008600084815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015560408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550606082015181600301556080820151816004015560a0820151816005015560c08201518160060160006101000a81548161ffff021916908361ffff16021790555060e08201518160060160026101000a81548160ff021916908315150217905550610100820151816007015561012082015181600801556101408201518160090160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555061016082015181600a01559050508a6001600160a01b03166323b872dd87308d6040518463ffffffff1660e01b815260040161266993929190615c1c565b600060405180830381600087803b15801561268357600080fd5b505af1158015612697573d6000803e3d6000fd5b5050600480546040805163939ddf5960e01b815290516001600160a01b03909216945063939ddf599350808301926000929182900301818387803b1580156126de57600080fd5b505af11580156126f2573d6000803e3d6000fd5b5050600480546040516340c10f1960e01b81526001600160a01b0390911693506340c10f19925061272f913391678ac7230489e800009101615a3b565b600060405180830381600087803b15801561274957600080fd5b505af115801561275d573d6000803e3d6000fd5b50506040518492507f7e0e356457a92dacd3760ddf327a24dd226c6ca01b2cc41a7fd6f28469c7ab9b9150600090a25050505050505050505050565b60008181526008602052604090206002015481906001600160a01b03166127d25760405162461bcd60e51b8152600401610e6290615af6565b6000828152600860205260409020600201546001600160a01b0316331461282f5760405162461bcd60e51b81526020600482015260116024820152702737ba1030bab1ba34b7b71037bbb732b960791b6044820152606401610e62565b6000828152600860205260409020600701541561285e5760405162461bcd60e51b8152600401610e6290615bc4565b61286782614bbd565b5050565b60008281526008602052604090206002015482906001600160a01b03166128a45760405162461bcd60e51b8152600401610e6290615af6565b6000838152600860209081526040808320600581015484526009909252909120600101546001600160a01b03163381146129165760405162461bcd60e51b81526020600482015260136024820152722737ba1030bab1ba34b7b71031bab930ba37b960691b6044820152606401610e62565b6007820154156129385760405162461bcd60e51b8152600401610e6290615bc4565b60018415151480156129555750600682015462010000900460ff16155b806129785750831580156129785750600682015462010000900460ff1615156001145b6129bc5760405162461bcd60e51b8152602060048201526015602482015274416c726561647920696e207468697320737461746560581b6044820152606401610e62565b60068201805462ff00001916620100008615159081029190911790915560011415612a8957600582015460009081526012602052604090206129fe9086614ae2565b60058201546000908152601060205260409020612a1b90866146d6565b50600582015460008052603f6020527fe9090a6e551363283803e59daf1c144cd0ac55c420ac8519a53d83ef396a73b35414612a89576005820154612a6290603e90614b71565b15612a78576005820154612a7890603e90614a7c565b6005820154612a8990603e90614ae2565b847f413683da80d84e9230e77823548d8edb71f904a7ebf1720ac86d7e020f3afb4885604051612abd911515815260200190565b60405180910390a25050505050565b60008281526009602052604090206001015482906001600160a01b03163314612b075760405162461bcd60e51b8152600401610e6290615a7d565b6000838152601560205260409020612b1f908361457f565b15612b5c5760405162461bcd60e51b815260206004820152600d60248201526c105b1c9958591e481859191959609a1b6044820152606401610e62565b6000838152601560205260409020612b749083614d51565b506001600160a01b0382166000908152601460205260409020612b9790846142e5565b50600480546040516340c10f1960e01b81526001600160a01b03909116916340c10f1991612bd1913391670de0b6b3a76400009101615a3b565b600060405180830381600087803b158015612beb57600080fd5b505af1158015612bff573d6000803e3d6000fd5b50506040516001600160a01b03851692508591507fb4bb2554051450eee88f69da851aa30e3c5b5f29b19f8a8dd9b430dd17f4f39b90600090a3505050565b6001600160a01b0381166000908152600e6020526040902054612c62602c8361439e565b10612c7f5760405162461bcd60e51b8152600401610e6290615a54565b6001600160a01b0381166000908152600e602052604090205461127f90602c9083906143bd565b600960205260009081526040902080548190612cc190615abb565b80601f0160208091040260200160405190810160405280929190818152602001828054612ced90615abb565b8015612d3a5780601f10612d0f57610100808354040283529160200191612d3a565b820191906000526020600020905b815481529060010190602001808311612d1d57829003601f168201915b50505050600183015460028401805493946001600160a01b03831694600160a01b840461ffff169450600160b01b90930460ff1692909190612d7b90615abb565b80601f0160208091040260200160405190810160405280929190818152602001828054612da790615abb565b8015612df45780601f10612dc957610100808354040283529160200191612df4565b820191906000526020600020905b815481529060010190602001808311612dd757829003601f168201915b505050505090806003015490806004015490806005015490806006015490806007015490508a565b600081815260096020908152604080832060030154601c9092529091205410612e575760405162461bcd60e51b8152600401610e6290615a54565b60008181526009602052604090206003015461127f90601a908390614dac565b6040516301ffc9a760e01b81526001600160a01b038316906301ffc9a790612eaa906380ac58cd60e01b90600401615c40565b60206040518083038186803b158015612ec257600080fd5b505afa158015612ed6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612efa9190615c55565b612f165760405162461bcd60e51b8152600401610e6290615c72565b60008282604051602001612f2b929190615a3b565b60408051601f1981840301815291815281516020928301206000818152600690935291205490915015612f915760405162461bcd60e51b815260206004820152600e60248201526d41756374696f6e2065786973747360901b6044820152606401610e62565b6001806000828254612fa39190615a23565b9091555050600180546040805160a0810182526001600160a01b038088168252602080830188815233848601908152346060860190815242608087019081526000898152600b8652888120975188549088166001600160a01b031991821617895594519a88019a909a5591516002870180549190961693169290921790935551600384015590516004909201919091558484526019905290912061304790826142e5565b50600480546040516340c10f1960e01b81526001600160a01b03909116916340c10f1991613081913391670de0b6b3a76400009101615a3b565b600060405180830381600087803b15801561309b57600080fd5b505af11580156130af573d6000803e3d6000fd5b5050505050505050565b60008181526008602052604090206002015481906001600160a01b03166130f25760405162461bcd60e51b8152600401610e6290615af6565b6000828152600860205260409020600781015461313f5760405162461bcd60e51b815260206004820152600b60248201526a139bdd081cdd185c9d195960aa1b6044820152606401610e62565b806003015481600701546131539190615a23565b42101561318e5760405162461bcd60e51b8152602060048201526009602482015268139bdd08195b99195960ba1b6044820152606401610e62565b805460098201546001830154604051632142170760e11b81526001600160a01b03938416936342842e0e936131cc9330939290911691600401615c1c565b600060405180830381600087803b1580156131e657600080fd5b505af19250505080156131f7575060015b6132265760098101546008820154613218916001600160a01b03169061498c565b61322183614bbd565b505050565b6005810154600882015460098301546001600160a01b03166000908152600e6020526040812060020180549192839290916001918490613267908490615a23565b909155505060098501546001600160a01b03166000908152600e60205260408120600401805483929061329b908490615a23565b909155505084546001600160a01b031660009081526007602052604081206003018054600192906132cd908490615a23565b909155505084546001600160a01b0316600090815260076020526040812060040180548392906132fe908490615a23565b909155505084546001860154604051631030681960e21b81526001600160a01b03909216916340c1a064916133399160040190815260200190565b60206040518083038186803b15801561335157600080fd5b505afa925050508015613381575060408051601f3d908101601f1916820190925261337e91810190615b90565b60015b6133f65760028501546001600160a01b03166000908152600e6020526040812060019081018054919290916133b7908490615a23565b909155505060028501546001600160a01b03166000908152600e6020526040812060030180548392906133eb908490615a23565b909155506134e59050565b60028601546001600160a01b0382811691161415613477576001600160a01b0381166000908152600d60205260408120600190810180549192909161343c908490615a23565b90915550506001600160a01b0381166000908152600d60205260408120600201805484929061346c908490615a23565b909155506134e39050565b60028601546001600160a01b03166000908152600e6020526040812060019081018054919290916134a9908490615a23565b909155505060028601546001600160a01b03166000908152600e6020526040812060030180548492906134dd908490615a23565b90915550505b505b83156135a9576000848152600960205260408120600180820154600490920180546001600160a01b03909316965090929091613522908490615a23565b909155505060008481526009602052604081206005018054839290613548908490615a23565b90915550506000848152600960205260409020600701541561358c576000848152600960205260408120600701805460019290613586908490615bad565b90915550505b60008481526012602052604090206135a49088614a7c565b6135b4565b6135b4604188614a7c565b6001600160a01b038316158015906135d35750600685015461ffff1615155b15613611576006850154612710906135ef9061ffff1683615b4f565b6135f99190615b6e565b91506136058282615bad565b9050613611838361498c565b6002850154613629906001600160a01b03168261498c565b83156136565760008481526009602052604081206006018054849290613650908490615a23565b90915550505b8454600186015460405160009261367b926001600160a01b0390911691602001615a3b565b60408051601f1981840301815291815281516020928301206000818152601890935291209091506136ac90896142e5565b5060008181526006602052604081205560038601541561374a576000888152601160205260409020545b80156137485760006137006136ec600184615bad565b60008c815260116020526040902090614f09565b6000818152600a60209081526040808320600101546001600160a01b0316835260179091529020909150613734908b6146d6565b508161373f81615ca3565b925050506136d6565b505b60028601546001600160a01b0316600090815260166020526040902061377090896146d6565b50600480546040805163939ddf5960e01b815290516001600160a01b039092169263939ddf5992828201926000929082900301818387803b1580156137b457600080fd5b505af11580156137c8573d6000803e3d6000fd5b5050600480546040516340c10f1960e01b81526001600160a01b0390911693506340c10f199250613805913391678ac7230489e800009101615a3b565b600060405180830381600087803b15801561381f57600080fd5b505af1158015613833573d6000803e3d6000fd5b50506040518a92507f45806e512b1f4f10e33e8b3cb64d1d11d998d8c554a95e0841fc1c701278bd5d9150600090a25050505050505050565b6000610de660415490565b60606113d3602384846147bf565b6000818152600b6020526040902080546001600160a01b03166138ba5760405162461bcd60e51b8152600401610e6290615af6565b805460018201546040516331a9108f60e11b81526001600160a01b0390921691636352211e916138f09160040190815260200190565b60206040518083038186803b15801561390857600080fd5b505afa15801561391c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139409190615b90565b6001600160a01b0316336001600160a01b031614806139f557508054600182015460405163020604bf60e21b81526001600160a01b039092169163081812fc916139909160040190815260200190565b60206040518083038186803b1580156139a857600080fd5b505afa1580156139bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139e09190615b90565b6001600160a01b0316336001600160a01b0316145b613a115760405162461bcd60e51b8152600401610e6290615bed565b805460028201546001830154604051632142170760e11b81526001600160a01b03938416936342842e0e93613a4f9333939290911691600401615c1c565b600060405180830381600087803b158015613a6957600080fd5b505af1158015613a7d573d6000803e3d6000fd5b50505050613a8f33826003015461498c565b80546001820154604051600092613ab4926001600160a01b0390911691602001615a3b565b60408051601f198184030181529181528151602092830120600081815260199093529120909150613ae590846146d6565b506000838152600b602052604080822080546001600160a01b0319908116825560018201849055600282018054909116905560038101839055600490810192909255815490516340c10f1960e01b81526001600160a01b03909116916340c10f1991613b5d913391670de0b6b3a76400009101615a3b565b600060405180830381600087803b158015613b7757600080fd5b505af1158015613b8b573d6000803e3d6000fd5b50505050505050565b60606113d3604184846141c6565b6001600160a01b0381166000908152600d6020526040902054613bc660238361439e565b10613be35760405162461bcd60e51b8152600401610e6290615a54565b6001600160a01b0381166000908152600d602052604090205461127f9060239083906143bd565b60606113d3603e84846141c6565b6000818152601060205260409020606090610e0f90614931565b6000818152601560205260409020606090610e0f9061427f565b6000818152601960205260409020606090610e0f90614931565b6000818152600b6020526040902060028101546001600160a01b03163314613cc75760405162461bcd60e51b81526020600482015260146024820152734e6f74206f776e6572206f72206d697373696e6760601b6044820152606401610e62565b613cd533826003015461498c565b80546001820154604051600092613cfa926001600160a01b0390911691602001615a3b565b60408051601f198184030181529181528151602092830120600081815260199093529120909150613d2b90846146d6565b5050506000908152600b6020526040812080546001600160a01b031990811682556001820183905560028201805490911690556003810182905560040155565b6001600160a01b038181166000908152600760205260409020600101541615613dcb5760405162461bcd60e51b8152602060048201526012602482015271105b1c9958591e481c9959da5cdd195c995960721b6044820152606401610e62565b6040516301ffc9a760e01b81526001600160a01b038216906301ffc9a790613dfe906380ac58cd60e01b90600401615c40565b60206040518083038186803b158015613e1657600080fd5b505afa158015613e2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e4e9190615c55565b613e6a5760405162461bcd60e51b8152600401610e6290615c72565b6040516301ffc9a760e01b81526001600160a01b038216906301ffc9a790613e9d90635b5e139f60e01b90600401615c40565b60206040518083038186803b158015613eb557600080fd5b505afa158015613ec9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613eed9190615c55565b613f395760405162461bcd60e51b815260206004820152601f60248201527f446f6573206e6f7420737570706f7274204552433732314d65746164617461006044820152606401610e62565b6040516301ffc9a760e01b81526001600160a01b038216906301ffc9a790613f6c9063780e9d6360e01b90600401615c40565b60206040518083038186803b158015613f8457600080fd5b505afa158015613f98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fbc9190615c55565b6140125760405162461bcd60e51b815260206004820152602160248201527f446f6573206e6f7420737570706f727420455243373231456e756d657261626c6044820152606560f81b6064820152608401610e62565b806001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b15801561404b57600080fd5b505afa15801561405f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526140879190810190615cba565b6001600160a01b038216600090815260076020908152604090912082516140b493919291909101906153a6565b506001600160a01b03811660008181526007602090815260409182902060010180546001600160a01b031916841790558151638da5cb5b60e01b81529151638da5cb5b926004808201939291829003018186803b15801561411457600080fd5b505afa925050508015614144575060408051601f3d908101601f1916820190925261414191810190615b90565b60015b61414d57614182565b6001600160a01b03811615614180576001600160a01b0381166000908152600f6020526040902061417e9083614d51565b505b505b61127f6035826149d8565b6141968161170a565b61419f816130b9565b50565b6001600160a01b0381166000908152601460205260409020606090610e0f90614931565b60606000826001600160401b038111156141e2576141e261543f565b60405190808252806020026020018201604052801561420b578160200160208202803683370190505b5060008581526001870160205260408120549192505b84811015614274578183828151811061423c5761423c615d30565b60200260200101818152505086600101600083815260200190815260200160002054915060018161426d9190615a23565b9050614221565b509095945050505050565b6060816000018054806020026020016040519081016040528092919081815260200182805480156142d957602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116142bb575b50505050509050919050565b600081815260018301602052604081205461432c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610e0f565b506000610e0f565b6143416006830182614f33565b60008080526001808401602052604082206002810184905580549192909161436a908490615a23565b9091555050600080805260018084016020526040909120015461286757600080805260019283016020526040902090910155565b6001600160a01b03166000908152600291909101602052604090205490565b60008181526001840160205260409020835482111561441f576143e08484614f52565b6001810180546001600160a01b0319166001600160a01b03851617905581845561440d60068501846150aa565b61441a6003850183614ae2565b614527565b6001600160a01b0383166000908152600285016020908152604080832054808452600588018352818420546001808a0190945291909320549091141561447357600082815260048701602052604090205491505b61447d8686614f52565b60008111801561448c57508084115b156144a757600090815260058601602052604090205461447d565b60008181526001878101602081815260408085206002015460048c0183528186205486529290915290922001546144f19160068901916001600160a01b03918216918991166150cd565b82546145245761450660038701828685615155565b6001830180546001600160a01b0319166001600160a01b0387161790555b50505b6002810180546001600160a01b0319166001600160a01b03851617905580546001908290600090614559908490615a23565b9091555050506001600160a01b0390911660009081526002909201602052604090912055565b6001600160a01b031660009081526001919091016020526040902054151590565b6001600160a01b038116600090815260018301602052604081205480156146cc5760006145ce600183615bad565b85549091506000906145e290600190615bad565b905081811461466e57600086600001828154811061460257614602615d30565b60009182526020909120015487546001600160a01b039091169150819088908590811061463157614631615d30565b600091825260208083209190910180546001600160a01b0319166001600160a01b0394851617905592909116815260018801909152604090208390555b855486908061467f5761467f615d46565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0387168252600188810190915260408220919091559350610e0f92505050565b6000915050610e0f565b600081815260018301602052604081205480156146cc5760006146fa600183615bad565b855490915060009061470e90600190615bad565b905081811461477357600086600001828154811061472e5761472e615d30565b906000526020600020015490508087600001848154811061475157614751615d30565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061478457614784615d46565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610e0f565b60606000826001600160401b038111156147db576147db61543f565b604051908082528060200260200182016040528015614804578160200160208202803683370190505b506001600160a01b0380861660009081526007880160205260408120549293509116905b84811015614274578183828151811061484357614843615d30565b6001600160a01b0392831660209182029290920181019190915292811660009081526007890190935260409092205490911690614881600182615a23565b9050614828565b60606000826001600160401b038111156148a4576148a461543f565b6040519080825280602002602001820160405280156148cd578160200160208202803683370190505b5060008581526007870160205260408120549192505b8481101561427457818382815181106148fe576148fe615d30565b60209081029190910181019190915260009283526007880190526040909120549061492a600182615a23565b90506148e3565b6060816000018054806020026020016040519081016040528092919081815260200182805480156142d957602002820191906000526020600020905b81548152602001906001019080831161496d5750505050509050919050565b614996828261519e565b6128675760405162461bcd60e51b8152602060048201526013602482015272115512081d1c985b9cd9995c8819985a5b1959606a1b6044820152606401610e62565b6149e56006830182615205565b60008080526001838101602052604082206002810180546001600160a01b0319166001600160a01b038616179055805491929091614a24908490615a23565b909155505060008080526001808401602052604090912001546001600160a01b0316612867576000808052600180840160205260409091200180546001600160a01b0383166001600160a01b03199091161790555050565b6000818152600183016020818152604080842080546002880180855283872080548852958552838720829055855491875280855292862055858552849055905255815415612867576001826000016000828254614ad99190615bad565b90915550505050565b60008080526001830160205260408120546128679184918490615155565b60008080526007830160205260408120546001600160a01b0383811691161480614b4557506001600160a01b0382811660009081526007850160205260409020541615155b806113d35750506001600160a01b03908116600090815260089290920160205260409091205416151590565b6000808052600183016020526040812054821480614b9e5750600082815260018401602052604090205415155b806113d357505060009081526002919091016020526040902054151590565b600081815260086020526040908190208054600282015460018301549351632142170760e11b815292936001600160a01b03928316936342842e0e93614c0a933093911691600401615c1c565b600060405180830381600087803b158015614c2457600080fd5b505af1158015614c38573d6000803e3d6000fd5b5050505060058101548015614ca3576000818152601260205260409020614c5f9084614a7c565b60008181526009602052604090206007015415614c9e576000818152600960205260408120600701805460019290614c98908490615bad565b90915550505b614cae565b614cae604184614a7c565b60068201805462ff00001916905581546001830154604051600092614ce1926001600160a01b0390911691602001615a3b565b60408051601f198184030181529181528151602092830120600081815260189093529120909150614d1290856142e5565b506000818152600660205260408082208290555185917f28601d865dccc9f113e15a7185c1b38c085d598c71250d3337916a428536d77191a250505050565b6000614d5d838361457f565b61432c57508154600180820184556000848152602080822090930180546001600160a01b0319166001600160a01b03861690811790915585549082528286019093526040902091909155610e0f565b600081815260018401602052604090208354821115614df857614dcf848461522d565b60018101839055818455614de66006850184614ae2565b614df36003850183614ae2565b614ed3565b6000838152600285016020908152604080832054808452600588018352818420546001808a01909452919093205490911415614e4257600082815260048701602052604090205491505b614e4c868661522d565b600081118015614e5b57508084115b15614e76576000908152600586016020526040902054614e4c565b60008181526001878101602081815260408085206002015460048c018352818620548652929091529092200154614eb39160068901918890615155565b8254614ed057614ec860038701828685615155565b600183018590555b50505b6002810183905580546001908290600090614eef908490615a23565b909155505050600091825260029092016020526040902055565b6000826000018281548110614f2057614f20615d30565b9060005260206000200154905092915050565b6000808052600283016020526040812054612867918491908490615155565b6001600160a01b0381166000908152600283016020908152604080832080549084905580845260018601909252909120805415614fa4576001816000016000828254614f9e9190615bad565b90915550505b8054614fff576001810180546001600160a01b031990811690915560028201805490911690558354821415614fe757600082815260048501602052604090205484555b8115614ffa57614ffa6003850183614a7c565b615097565b60018101546001600160a01b038481169116141561504b576001600160a01b0383811660009081526007860160205260409020546001830180546001600160a01b031916919092161790555b60028101546001600160a01b0384811691161415615097576001600160a01b0383811660009081526008860160205260409020546002830180546001600160a01b031916919092161790555b6150a46006850184615311565b50505050565b600080805260018301602052604081205461286791849184906001600160a01b03165b6001600160a01b0380841660008181526001808801602090815260408084208054878a166001600160a01b031991821681179092558186528286208054988a169882168917905596855260028b0190925280842080548716831790559083528220805490941690921790925585549091869161514a908490615a23565b909155505050505050565b600083815260018086016020908152604080842086905585845280842085905584845260028801909152808320859055848352822085905585549091869161514a908490615a23565b60408051600080825260208201928390529182916001600160a01b0386169185916151c8916159cb565b60006040518083038185875af1925050503d8060008114614274576040519150601f19603f3d011682016040523d82523d6000602084013e614274565b60008080526002830160205260408120546128679184916001600160a01b03169084906150cd565b600081815260028301602090815260408083208054908490558084526001860190925290912080541561527557600181600001600082825461526f9190615bad565b90915550505b80546152be57600060018201819055600282015583548214156152a657600082815260048501602052604090205484555b81156152b9576152b96003850183614a7c565b615304565b82816001015414156152e157600083815260078501602052604090205460018201555b828160020154141561530457600083815260088501602052604090205460028201555b6150a46006850184614a7c565b6001600160a01b0381811660008181526001850160208181526040808420805460028a0180855283872080548a1688529585528387208054928a166001600160a01b0319938416179055855483548a168852945291852080549390971692821692909217909555929091528154831690915580549091169055815415612867576001826000016000828254614ad99190615bad565b8280546153b290615abb565b90600052602060002090601f0160209004810192826153d4576000855561541a565b82601f106153ed57805160ff191683800117855561541a565b8280016001018555821561541a579182015b8281111561541a5782518255916020019190600101906153ff565b5061542692915061542a565b5090565b5b80821115615426576000815560010161542b565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561547d5761547d61543f565b604052919050565b60006001600160401b0382111561549e5761549e61543f565b50601f01601f191660200190565b600082601f8301126154bd57600080fd5b81356154d06154cb82615485565b615455565b8181528460208386010111156154e557600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561551457600080fd5b81356001600160401b0381111561552a57600080fd5b610dde848285016154ac565b60008060006060848603121561554b57600080fd5b505081359360208301359350604090920135919050565b6020808252825182820181905260009190848201906040850190845b8181101561559a5783518352928401929184019160010161557e565b50909695505050505050565b6001600160a01b038116811461419f57600080fd5b6000602082840312156155cd57600080fd5b81356113d3816155a6565b6020808252825182820181905260009190848201906040850190845b8181101561559a5783516001600160a01b0316835292840192918401916001016155f4565b60006020828403121561562b57600080fd5b5035919050565b803561ffff8116811461564457600080fd5b919050565b801515811461419f57600080fd5b600080600080600060a0868803121561566f57600080fd5b85356001600160401b038082111561568657600080fd5b61569289838a016154ac565b9650602088013591506156a4826155a6565b8195506156b360408901615632565b9450606088013591506156c582615649565b909250608087013590808211156156db57600080fd5b506156e8888289016154ac565b9150509295509295909350565b6000806040838503121561570857600080fd5b82359150602083013561571a816155a6565b809150509250929050565b6000806040838503121561573857600080fd5b8235615743816155a6565b946020939093013593505050565b6000806040838503121561576457600080fd5b50508035926020909101359150565b6000806040838503121561578657600080fd5b8235915060208301356001600160401b038111156157a357600080fd5b6157af858286016154ac565b9150509250929050565b60005b838110156157d45781810151838201526020016157bc565b838111156150a45750506000910152565b600081518084526157fd8160208601602086016157b9565b601f01601f19169290920160200192915050565b60608152600061582460608301866157e5565b828103602084015261583681866157e5565b9050828103604084015261584a81856157e5565b9695505050505050565b60a08152600061586760a08301886157e5565b6001600160a01b039690961660208301525060408101939093526060830191909152608090910152919050565b600080604083850312156158a757600080fd5b823591506158b760208401615632565b90509250929050565b600080600080600060a086880312156158d857600080fd5b85356158e3816155a6565b97602087013597506040870135966060810135965060800135945092505050565b6000806040838503121561591757600080fd5b82359150602083013561571a81615649565b600061014080835261593d8184018e6157e5565b6001600160a01b038d16602085015261ffff8c1660408501528a1515606085015283810360808501529050615972818a6157e5565b60a0840198909852505060c081019490945260e08401929092526101008301526101209091015295945050505050565b6020808252600f908201526e2737ba103a37b5b2b71037bbb732b960891b604082015260600190565b600082516159dd8184602087016157b9565b9190910192915050565b6020808252600c908201526b08ccaca40e8dede40d0d2ced60a31b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60008219821115615a3657615a36615a0d565b500190565b6001600160a01b03929092168252602082015260400190565b6020808252600f908201526e52616e6b20757020746f206461746560881b604082015260600190565b6020808252601190820152702737ba103437bab9b29031bab930ba37b960791b604082015260600190565b6020815260006113d360208301846157e5565b600181811c90821680615acf57607f821691505b60208210811415615af057634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600e908201526d111bd95cc81b9bdd08195e1a5cdd60921b604082015260600190565b6020808252601790820152762737ba1030b8383937bb32b210313c9031bab930ba37b960491b604082015260600190565b6000816000190483118215151615615b6957615b69615a0d565b500290565b600082615b8b57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215615ba257600080fd5b81516113d3816155a6565b600082821015615bbf57615bbf615a0d565b500390565b6020808252600f908201526e105b1c9958591e481cdd185c9d1959608a1b604082015260600190565b602080825260159082015274139bdd081bdddb995c881bdc88185c1c1c9bdd9959605a1b604082015260600190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160e01b031991909116815260200190565b600060208284031215615c6757600080fd5b81516113d381615649565b602080825260179082015276446f6573206e6f7420737570706f72742045524337323160481b604082015260600190565b600081615cb257615cb2615a0d565b506000190190565b600060208284031215615ccc57600080fd5b81516001600160401b03811115615ce257600080fd5b8201601f81018413615cf357600080fd5b8051615d016154cb82615485565b818152856020838501011115615d1657600080fd5b615d278260208301602086016157b9565b95945050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fdfea264697066735822122089cf9b647bba9eaccb89eeccf586b362cba98ccd9f22f0acf3aafc9603d575d164736f6c63430008090033000000000000000000000000bb76a956ef664c942bc2e952b172e553118a463c

Deployed Bytecode

0x6080604052600436106103385760003560e01c8063745ab66e116101b2578063b2a4706e116100ed578063e244d47811610090578063e244d47814610c84578063e638ebfb14610ca4578063e786646714610cc4578063ec91f2a414610ce4578063ef706adf14610cfa578063f7b0770b14610d1a578063fd8acc4214610d3a578063fe892e6014610d4d57600080fd5b8063b2a4706e14610b9c578063b9a2de3a14610baf578063c128fc4914610bcf578063c7bccac014610be4578063c815729d14610c04578063ceb6a22f14610c24578063d219cfba14610c44578063dafdb1e014610c6457600080fd5b806396eed5601161015557806396eed56014610a8f578063973ddb4a14610abc578063976d577014610adc57806399d2813514610afc578063a09037a914610b1c578063a7fe508b14610b31578063aeda852f14610b46578063b03a4dfe14610b7c57600080fd5b8063745ab66e146109085780637502d7ae1461092857806376487b3814610948578063806139741461096857806384da92a7146109a05780638a72ea6a146109c0578063961c9ae414610a4f57806396b5a75514610a6f57600080fd5b80634163faab1161028257806362910b591161022557806362910b5914610804578063659dd2b41461082457806369ce5d871461083757806369dc9ff3146108575780636f8a41e1146108885780637091d2d3146108a857806370b4768e146108c857806372e93ee8146108e857600080fd5b80634163faab1461056f5780634423c5f11461058f5780634693fcae146105f757806353c8388e1461061757806356d0b82d14610637578063571a26a0146106605780635e5c06e214610763578063603737751461079257600080fd5b8063162d8afb116102ea578063162d8afb1461043657806316a50e941461044b5780632adeee26146104605780632e24c5871461048057806331bcaa99146104d7578063374fea91146104f7578063393a7161146105175780633b7def961461053757600080fd5b806306a992981461033d57806309e6a4b91461035f57806311c0036c14610395578063127f1498146103b45780631328c5b3146103e1578063154df9f51461040157806316002f4a14610421575b600080fd5b34801561034957600080fd5b5061035d610358366004615502565b610d6d565b005b34801561036b57600080fd5b5061037f61037a366004615536565b610dc2565b60405161038c9190615562565b60405180910390f35b3480156103a157600080fd5b506029545b60405190815260200161038c565b3480156103c057600080fd5b506103d46103cf3660046155bb565b610deb565b60405161038c91906155d8565b3480156103ed57600080fd5b506103a66103fc366004615619565b610e15565b34801561040d57600080fd5b5061035d61041c366004615619565b610e29565b34801561042d57600080fd5b506003546103a6565b34801561044257600080fd5b506002546103a6565b34801561045757600080fd5b506103a6610ed1565b34801561046c57600080fd5b5061035d61047b366004615657565b610edc565b34801561048c57600080fd5b506104bc61049b3660046155bb565b600d6020526000908152604090208054600182015460029092015490919083565b6040805193845260208401929092529082015260600161038c565b3480156104e357600080fd5b5061035d6104f23660046155bb565b611211565b34801561050357600080fd5b5061035d6105123660046156f5565b6112b8565b34801561052357600080fd5b506103d4610532366004615725565b6113c5565b34801561054357600080fd5b50600454610557906001600160a01b031681565b6040516001600160a01b03909116815260200161038c565b34801561057b57600080fd5b5061035d61058a366004615751565b6113da565b34801561059b57600080fd5b506105d46105aa366004615619565b600a6020526000908152604090208054600182015460029092015490916001600160a01b03169083565b604080519384526001600160a01b0390921660208401529082015260600161038c565b34801561060357600080fd5b5061037f610612366004615751565b611480565b34801561062357600080fd5b5061035d610632366004615773565b61148e565b34801561064357600080fd5b5061064d6101f481565b60405161ffff909116815260200161038c565b34801561066c57600080fd5b506106ee61067b366004615619565b600860208190526000918252604090912080546001820154600283015460038401546004850154600586015460068701546007880154988801546009890154600a909901546001600160a01b039889169a97999689169895979496939561ffff8416956201000090940460ff169416908c565b604080516001600160a01b039d8e168152602081019c909c52998c16998b019990995260608a0197909752608089019590955260a088019390935261ffff90911660c0870152151560e0860152610100850152610120840152929092166101408201526101608101919091526101800161038c565b34801561076f57600080fd5b5061078361077e3660046155bb565b61152c565b60405161038c93929190615811565b34801561079e57600080fd5b506107dc6107ad3660046155bb565b600e60205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b604080519586526020860194909452928401919091526060830152608082015260a00161038c565b34801561081057600080fd5b5061037f61081f3660046155bb565b6116e6565b61035d610832366004615619565b61170a565b34801561084357600080fd5b5061037f6108523660046155bb565b611d1a565b34801561086357600080fd5b506108776108723660046155bb565b611d3e565b60405161038c959493929190615854565b34801561089457600080fd5b5061035d6108a3366004615751565b611dff565b3480156108b457600080fd5b506103d46108c3366004615725565b611ed6565b3480156108d457600080fd5b5061037f6108e3366004615619565b611ee4565b3480156108f457600080fd5b5061037f6109033660046155bb565b611efe565b34801561091457600080fd5b5061037f610923366004615619565b611f22565b34801561093457600080fd5b5061035d610943366004615894565b611f3c565b34801561095457600080fd5b5061035d610963366004615502565b611ffe565b34801561097457600080fd5b506103a6610983366004615502565b805160208183018101805160058252928201919093012091525481565b3480156109ac57600080fd5b5061035d6109bb366004615502565b612024565b3480156109cc57600080fd5b50610a166109db366004615619565b600b60205260009081526040902080546001820154600283015460038401546004909401546001600160a01b03938416949293909116919085565b604080516001600160a01b039687168152602081019590955292909416918301919091526060820152608081019190915260a00161038c565b348015610a5b57600080fd5b5061035d610a6a3660046158c0565b612044565b348015610a7b57600080fd5b5061035d610a8a366004615619565b612799565b348015610a9b57600080fd5b506103a6610aaa366004615619565b60066020526000908152604090205481565b348015610ac857600080fd5b5061035d610ad7366004615904565b61286b565b348015610ae857600080fd5b5061035d610af73660046156f5565b612acc565b348015610b0857600080fd5b5061035d610b173660046155bb565b612c3e565b348015610b2857600080fd5b50603b546103a6565b348015610b3d57600080fd5b506032546103a6565b348015610b5257600080fd5b50610b66610b61366004615619565b612ca6565b60405161038c9a99989796959493929190615929565b348015610b8857600080fd5b5061035d610b97366004615619565b612e1c565b61035d610baa366004615725565b612e77565b348015610bbb57600080fd5b5061035d610bca366004615619565b6130b9565b348015610bdb57600080fd5b506103a661386c565b348015610bf057600080fd5b506103d4610bff366004615725565b613877565b348015610c1057600080fd5b5061035d610c1f366004615619565b613885565b348015610c3057600080fd5b5061037f610c3f366004615751565b613b94565b348015610c5057600080fd5b5061035d610c5f3660046155bb565b613ba2565b348015610c7057600080fd5b5061037f610c7f366004615751565b613c0a565b348015610c9057600080fd5b5061037f610c9f366004615619565b613c18565b348015610cb057600080fd5b506103d4610cbf366004615619565b613c32565b348015610cd057600080fd5b5061037f610cdf366004615619565b613c4c565b348015610cf057600080fd5b506103a661038481565b348015610d0657600080fd5b5061035d610d15366004615619565b613c66565b348015610d2657600080fd5b5061035d610d353660046155bb565b613d6b565b61035d610d48366004615619565b61418d565b348015610d5957600080fd5b5061037f610d683660046155bb565b6141a2565b336000908152600c602090815260409091208251610d93926002909201918401906153a6565b5060405133907fe7b1fae3a790ceab07642c09617df79428b02832cd512bbfdd4db50272dcdf3090600090a250565b6000838152601260205260409020606090610dde9084846141c6565b949350505050565b905090565b6001600160a01b0381166000908152600f60205260409020606090610e0f9061427f565b92915050565b600081815260126020526040812054610e0f565b6000818152600860205260409020600201546001600160a01b03163314610e6b5760405162461bcd60e51b8152600401610e62906159a2565b60405180910390fd5b600480546040516315f5a0b160e21b81529182018390523360248301526001600160a01b0316906357d682c4906044015b600060405180830381600087803b158015610eb657600080fd5b505af1158015610eca573d6000803e3d6000fd5b5050505050565b6000610de6603e5490565b600585604051610eec91906159cb565b908152602001604051809103902054600014610f3b5760405162461bcd60e51b815260206004820152600e60248201526d416c72656164792065786973747360901b6044820152606401610e62565b6000855111610f7c5760405162461bcd60e51b815260206004820152600d60248201526c13985b59481c995c5d5a5c9959609a1b6044820152606401610e62565b602085511115610fbe5760405162461bcd60e51b815260206004820152600d60248201526c4e616d6520746f6f206c6f6e6760981b6044820152606401610e62565b6001600160a01b0384166110075760405162461bcd60e51b815260206004820152601060248201526f1059191c995cdcc81c995c5d5a5c995960821b6044820152606401610e62565b6127108361ffff161061102c5760405162461bcd60e51b8152600401610e62906159e7565b60016002600082825461103f9190615a23565b909155505060025460008181526009602090815260409091208751611066928901906153a6565b5060008181526009602090815260409091206001810180546001600160a01b0389166001600160b01b031990911617600160a01b61ffff8916021760ff60b01b1916600160b01b8715150217905583516110c8926002909201918501906153a6565b506001600160a01b03851660009081526013602052604090206110eb90826142e5565b506110f7601a82614334565b8060058760405161110891906159cb565b90815260408051918290036020018220929092556004805463939ddf5960e01b835292516001600160a01b039093169263939ddf5992828101926000929182900301818387803b15801561115b57600080fd5b505af115801561116f573d6000803e3d6000fd5b5050600480546040516340c10f1960e01b81526001600160a01b0390911693506340c10f1992506111ac913391674563918244f400009101615a3b565b600060405180830381600087803b1580156111c657600080fd5b505af11580156111da573d6000803e3d6000fd5b50506040518392507f3ef0dde97fa0cc56206f591c9007c69a72f6c75af7e50510fc815b58bbb5434c9150600090a2505050505050565b6001600160a01b03811660009081526007602052604090206002015461123860358361439e565b106112555760405162461bcd60e51b8152600401610e6290615a54565b6001600160a01b03811660009081526007602052604090206002015461127f9060359083906143bd565b600480546040516340c10f1960e01b81526001600160a01b03909116916340c10f1991610e9c913391670de0b6b3a76400009101615a3b565b60008281526009602052604090206001015482906001600160a01b031633146112f35760405162461bcd60e51b8152600401610e6290615a7d565b600083815260156020526040902061130b908361457f565b151560011461134e5760405162461bcd60e51b815260206004820152600f60248201526e105b1c9958591e481c995b5bdd9959608a1b6044820152606401610e62565b600083815260156020526040902061136690836145a0565b506001600160a01b038216600090815260146020526040902061138990846146d6565b506040516001600160a01b0383169084907f7efbfc4ea79118ce5c257ac41ccdcea63de279540e4ba7d10a38072523a05d4f90600090a3505050565b60606113d3602c84846147bf565b9392505050565b6000828152600860205260409020600201546001600160a01b031633146114135760405162461bcd60e51b8152600401610e62906159a2565b600480546040516334c77f8760e01b8152918201849052602482018390523360448301526001600160a01b0316906334c77f8790606401600060405180830381600087803b15801561146457600080fd5b505af1158015611478573d6000803e3d6000fd5b505050505050565b60606113d3601a8484614888565b60008281526009602052604090206001015482906001600160a01b031633146114c95760405162461bcd60e51b8152600401610e6290615a7d565b600083815260096020908152604090912083516114ee926002909201918501906153a6565b50827f459157ba24c7ab9878b165ef465fa6ae2ab42bcd8445f576be378768b0c473098360405161151f9190615aa8565b60405180910390a2505050565b600c6020526000908152604090208054819061154790615abb565b80601f016020809104026020016040519081016040528092919081815260200182805461157390615abb565b80156115c05780601f10611595576101008083540402835291602001916115c0565b820191906000526020600020905b8154815290600101906020018083116115a357829003601f168201915b5050505050908060010180546115d590615abb565b80601f016020809104026020016040519081016040528092919081815260200182805461160190615abb565b801561164e5780601f106116235761010080835404028352916020019161164e565b820191906000526020600020905b81548152906001019060200180831161163157829003601f168201915b50505050509080600201805461166390615abb565b80601f016020809104026020016040519081016040528092919081815260200182805461168f90615abb565b80156116dc5780601f106116b1576101008083540402835291602001916116dc565b820191906000526020600020905b8154815290600101906020018083116116bf57829003601f168201915b5050505050905083565b6001600160a01b0381166000908152601760205260409020606090610e0f90614931565b60008181526008602052604090206002015481906001600160a01b03166117435760405162461bcd60e51b8152600401610e6290615af6565b6000828152600860205260409020600681015462010000900460ff1661177b5760405162461bcd60e51b8152600401610e6290615b1e565b6007810154158061179e57508060030154816007015461179b9190615a23565b42105b6117dc5760405162461bcd60e51b815260206004820152600f60248201526e105d58dd1a5bdb88195e1c1a5c9959608a1b6044820152606401610e62565b6008810154612710906117f2906101f490615b4f565b6117fc9190615b6e565b816008015461180b9190615a23565b34101561184b5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b6044820152606401610e62565b80600401543410156118995760405162461bcd60e51b81526020600482015260176024820152764269642062656c6f77207265736572766520707269636560481b6044820152606401610e62565b60098101546001600160a01b0316600181156118b3575060005b60078301546118c7574260078401556118da565b806118da576118da82846008015461498c565b3460088401556009830180546001600160a01b031916331790556003830154156119a35760016000808282546119109190615a23565b9091555050600080546040805160608101825242815233602080830191825234838501908152858752600a82528487209351845591516001840180546001600160a01b0319166001600160a01b0390921691909117905590516002909201919091558884526011905290912061198690826142e5565b503360009081526017602052604090206119a090876142e5565b50505b82546001600160a01b031660009081526007602052604081206002018054600192906119d0908490615a23565b909155505082546001840154604051631030681960e21b81526001600160a01b03909216916340c1a06491611a0b9160040190815260200190565b60206040518083038186803b158015611a2357600080fd5b505afa925050508015611a53575060408051601f3d908101601f19168201909252611a5091810190615b90565b60015b611a5c57611aa9565b60028401546001600160a01b0382811691161415611aa75760028401546001600160a01b03166000908152600d60205260408120805460019290611aa1908490615a23565b90915550505b505b336000908152600e6020526040902054611ac857611ac8602c336149d8565b336000908152600e60205260408120805460019290611ae8908490615a23565b9091555050600583015415611b5d5760058301546000908152600960205260408120600301805460019290611b1e908490615a23565b909155505060058301546000908152601260205260409020611b409086614a7c565b60058301546000908152601260205260409020611b5d9086614ae2565b600383015460009015611bc25760004285600301548660070154611b819190615a23565b611b8b9190615bad565b9050610384811015611bc057611ba381610384615bad565b856003016000828254611bb69190615a23565b9091555060019250505b505b600480546040805163939ddf5960e01b815290516001600160a01b039092169263939ddf5992828201926000929082900301818387803b158015611c0557600080fd5b505af1158015611c19573d6000803e3d6000fd5b5050600480546040516340c10f1960e01b81526001600160a01b0390911693506340c10f199250611c56913391678ac7230489e800009101615a3b565b600060405180830381600087803b158015611c7057600080fd5b505af1158015611c84573d6000803e3d6000fd5b50506040805134815285151560208201528415158183015290513393508992507fac7b4956ef620044e10f430450c0069d356507570c460567101eebac99165c0a9181900360600190a3801561147857857f8fdd260941d3b80e0b9ee888471b99a809d93315f1c2ccd41ac35dbfd64f22698560030154604051611d0a91815260200190565b60405180910390a2505050505050565b6001600160a01b0381166000908152601660205260409020606090610e0f90614931565b600760205260009081526040902080548190611d5990615abb565b80601f0160208091040260200160405190810160405280929190818152602001828054611d8590615abb565b8015611dd25780601f10611da757610100808354040283529160200191611dd2565b820191906000526020600020905b815481529060010190602001808311611db557829003601f168201915b5050505060018301546002840154600385015460049095015493946001600160a01b039092169390925085565b60008281526008602052604090206002015482906001600160a01b0316611e385760405162461bcd60e51b8152600401610e6290615af6565b600083815260086020526040902060028101546001600160a01b03163314611e725760405162461bcd60e51b8152600401610e62906159a2565b600781015415611e945760405162461bcd60e51b8152600401610e6290615bc4565b6004810183905560405183815284907fd44c1f367e4b7835166bd3805433cc6133391fa6e0099d7303ec10205c9efcb89060200160405180910390a250505050565b60606113d3603584846147bf565b6000818152601160205260409020606090610e0f90614931565b6001600160a01b0381166000908152601360205260409020606090610e0f90614931565b6000818152601860205260409020606090610e0f90614931565b60008281526009602052604090206001015482906001600160a01b03163314611f775760405162461bcd60e51b8152600401610e6290615a7d565b6127108261ffff1610611f9c5760405162461bcd60e51b8152600401610e62906159e7565b600083815260096020908152604091829020600101805461ffff60a01b1916600160a01b61ffff871690810291909117909155915191825284917fa20d223dfabc409c327adda1eca96fc2d4f1d446eac9110e8225d4a529489ffd910161151f565b336000908152600c602090815260409091208251610d93926001909201918401906153a6565b336000908152600c602090815260409091208251610d93928401906153a6565b6001600160a01b038581166000908152600760205260409020600101541661206f5761206f85613d6b565b6040516331a9108f60e11b8152600481018590526000906001600160a01b03871690636352211e9060240160206040518083038186803b1580156120b257600080fd5b505afa1580156120c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ea9190615b90565b9050336001600160a01b038216148061218b575060405163020604bf60e21b8152600481018690526001600160a01b0387169063081812fc9060240160206040518083038186803b15801561213e57600080fd5b505afa158015612152573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121769190615b90565b6001600160a01b0316336001600160a01b0316145b6121a75760405162461bcd60e51b8152600401610e6290615bed565b600060018184156122a357506000848152600960205260409020600101546001600160a01b0316806122125760405162461bcd60e51b8152602060048201526014602482015273121bdd5cd948191bd95cc81b9bdd08195e1a5cdd60621b6044820152606401610e62565b600085815260156020526040902061222a908561457f565b8061223d5750336001600160a01b038216145b6122595760405162461bcd60e51b8152600401610e6290615b1e565b600085815260096020526040812060018082015460079092018054600160a01b840461ffff169750600160b01b90930460ff1695509092909161229d908490615a23565b90915550505b604051631030681960e21b8152600481018990526001600160a01b038a16906340c1a0649060240160206040518083038186803b1580156122e357600080fd5b505afa925050508015612313575060408051601f3d908101601f1916820190925261231091810190615b90565b60015b61231c57612338565b612327602382614b00565b612336576123366023826149d8565b505b60016003600082825461234b9190615a23565b9091555050600354604051819060069060009061236e908e908e90602001615a3b565b60408051601f1981840301815291815281516020928301208352828201939093529082016000908120939093556001600160a01b03881683526016905290206123b790826142e5565b5060006001600160a01b03831615806123cd5750835b806123e95750856001600160a01b0316836001600160a01b0316145b9050861561248e57600181151514156124705760008781526012602052604090206124149083614ae2565b60008052603f6020527fe9090a6e551363283803e59daf1c144cd0ac55c420ac8519a53d83ef396a73b354871461246b57612450603e88614b71565b1561246057612460603e88614a7c565b61246b603e88614ae2565b612499565b600087815260106020526040902061248890836142e5565b50612499565b612499604183614ae2565b6040518061018001604052808c6001600160a01b031681526020018b8152602001876001600160a01b031681526020018a81526020018981526020018881526020018661ffff1681526020018215158152602001600081526020016000815260200160006001600160a01b03168152602001428152506008600084815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015560408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550606082015181600301556080820151816004015560a0820151816005015560c08201518160060160006101000a81548161ffff021916908361ffff16021790555060e08201518160060160026101000a81548160ff021916908315150217905550610100820151816007015561012082015181600801556101408201518160090160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555061016082015181600a01559050508a6001600160a01b03166323b872dd87308d6040518463ffffffff1660e01b815260040161266993929190615c1c565b600060405180830381600087803b15801561268357600080fd5b505af1158015612697573d6000803e3d6000fd5b5050600480546040805163939ddf5960e01b815290516001600160a01b03909216945063939ddf599350808301926000929182900301818387803b1580156126de57600080fd5b505af11580156126f2573d6000803e3d6000fd5b5050600480546040516340c10f1960e01b81526001600160a01b0390911693506340c10f19925061272f913391678ac7230489e800009101615a3b565b600060405180830381600087803b15801561274957600080fd5b505af115801561275d573d6000803e3d6000fd5b50506040518492507f7e0e356457a92dacd3760ddf327a24dd226c6ca01b2cc41a7fd6f28469c7ab9b9150600090a25050505050505050505050565b60008181526008602052604090206002015481906001600160a01b03166127d25760405162461bcd60e51b8152600401610e6290615af6565b6000828152600860205260409020600201546001600160a01b0316331461282f5760405162461bcd60e51b81526020600482015260116024820152702737ba1030bab1ba34b7b71037bbb732b960791b6044820152606401610e62565b6000828152600860205260409020600701541561285e5760405162461bcd60e51b8152600401610e6290615bc4565b61286782614bbd565b5050565b60008281526008602052604090206002015482906001600160a01b03166128a45760405162461bcd60e51b8152600401610e6290615af6565b6000838152600860209081526040808320600581015484526009909252909120600101546001600160a01b03163381146129165760405162461bcd60e51b81526020600482015260136024820152722737ba1030bab1ba34b7b71031bab930ba37b960691b6044820152606401610e62565b6007820154156129385760405162461bcd60e51b8152600401610e6290615bc4565b60018415151480156129555750600682015462010000900460ff16155b806129785750831580156129785750600682015462010000900460ff1615156001145b6129bc5760405162461bcd60e51b8152602060048201526015602482015274416c726561647920696e207468697320737461746560581b6044820152606401610e62565b60068201805462ff00001916620100008615159081029190911790915560011415612a8957600582015460009081526012602052604090206129fe9086614ae2565b60058201546000908152601060205260409020612a1b90866146d6565b50600582015460008052603f6020527fe9090a6e551363283803e59daf1c144cd0ac55c420ac8519a53d83ef396a73b35414612a89576005820154612a6290603e90614b71565b15612a78576005820154612a7890603e90614a7c565b6005820154612a8990603e90614ae2565b847f413683da80d84e9230e77823548d8edb71f904a7ebf1720ac86d7e020f3afb4885604051612abd911515815260200190565b60405180910390a25050505050565b60008281526009602052604090206001015482906001600160a01b03163314612b075760405162461bcd60e51b8152600401610e6290615a7d565b6000838152601560205260409020612b1f908361457f565b15612b5c5760405162461bcd60e51b815260206004820152600d60248201526c105b1c9958591e481859191959609a1b6044820152606401610e62565b6000838152601560205260409020612b749083614d51565b506001600160a01b0382166000908152601460205260409020612b9790846142e5565b50600480546040516340c10f1960e01b81526001600160a01b03909116916340c10f1991612bd1913391670de0b6b3a76400009101615a3b565b600060405180830381600087803b158015612beb57600080fd5b505af1158015612bff573d6000803e3d6000fd5b50506040516001600160a01b03851692508591507fb4bb2554051450eee88f69da851aa30e3c5b5f29b19f8a8dd9b430dd17f4f39b90600090a3505050565b6001600160a01b0381166000908152600e6020526040902054612c62602c8361439e565b10612c7f5760405162461bcd60e51b8152600401610e6290615a54565b6001600160a01b0381166000908152600e602052604090205461127f90602c9083906143bd565b600960205260009081526040902080548190612cc190615abb565b80601f0160208091040260200160405190810160405280929190818152602001828054612ced90615abb565b8015612d3a5780601f10612d0f57610100808354040283529160200191612d3a565b820191906000526020600020905b815481529060010190602001808311612d1d57829003601f168201915b50505050600183015460028401805493946001600160a01b03831694600160a01b840461ffff169450600160b01b90930460ff1692909190612d7b90615abb565b80601f0160208091040260200160405190810160405280929190818152602001828054612da790615abb565b8015612df45780601f10612dc957610100808354040283529160200191612df4565b820191906000526020600020905b815481529060010190602001808311612dd757829003601f168201915b505050505090806003015490806004015490806005015490806006015490806007015490508a565b600081815260096020908152604080832060030154601c9092529091205410612e575760405162461bcd60e51b8152600401610e6290615a54565b60008181526009602052604090206003015461127f90601a908390614dac565b6040516301ffc9a760e01b81526001600160a01b038316906301ffc9a790612eaa906380ac58cd60e01b90600401615c40565b60206040518083038186803b158015612ec257600080fd5b505afa158015612ed6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612efa9190615c55565b612f165760405162461bcd60e51b8152600401610e6290615c72565b60008282604051602001612f2b929190615a3b565b60408051601f1981840301815291815281516020928301206000818152600690935291205490915015612f915760405162461bcd60e51b815260206004820152600e60248201526d41756374696f6e2065786973747360901b6044820152606401610e62565b6001806000828254612fa39190615a23565b9091555050600180546040805160a0810182526001600160a01b038088168252602080830188815233848601908152346060860190815242608087019081526000898152600b8652888120975188549088166001600160a01b031991821617895594519a88019a909a5591516002870180549190961693169290921790935551600384015590516004909201919091558484526019905290912061304790826142e5565b50600480546040516340c10f1960e01b81526001600160a01b03909116916340c10f1991613081913391670de0b6b3a76400009101615a3b565b600060405180830381600087803b15801561309b57600080fd5b505af11580156130af573d6000803e3d6000fd5b5050505050505050565b60008181526008602052604090206002015481906001600160a01b03166130f25760405162461bcd60e51b8152600401610e6290615af6565b6000828152600860205260409020600781015461313f5760405162461bcd60e51b815260206004820152600b60248201526a139bdd081cdd185c9d195960aa1b6044820152606401610e62565b806003015481600701546131539190615a23565b42101561318e5760405162461bcd60e51b8152602060048201526009602482015268139bdd08195b99195960ba1b6044820152606401610e62565b805460098201546001830154604051632142170760e11b81526001600160a01b03938416936342842e0e936131cc9330939290911691600401615c1c565b600060405180830381600087803b1580156131e657600080fd5b505af19250505080156131f7575060015b6132265760098101546008820154613218916001600160a01b03169061498c565b61322183614bbd565b505050565b6005810154600882015460098301546001600160a01b03166000908152600e6020526040812060020180549192839290916001918490613267908490615a23565b909155505060098501546001600160a01b03166000908152600e60205260408120600401805483929061329b908490615a23565b909155505084546001600160a01b031660009081526007602052604081206003018054600192906132cd908490615a23565b909155505084546001600160a01b0316600090815260076020526040812060040180548392906132fe908490615a23565b909155505084546001860154604051631030681960e21b81526001600160a01b03909216916340c1a064916133399160040190815260200190565b60206040518083038186803b15801561335157600080fd5b505afa925050508015613381575060408051601f3d908101601f1916820190925261337e91810190615b90565b60015b6133f65760028501546001600160a01b03166000908152600e6020526040812060019081018054919290916133b7908490615a23565b909155505060028501546001600160a01b03166000908152600e6020526040812060030180548392906133eb908490615a23565b909155506134e59050565b60028601546001600160a01b0382811691161415613477576001600160a01b0381166000908152600d60205260408120600190810180549192909161343c908490615a23565b90915550506001600160a01b0381166000908152600d60205260408120600201805484929061346c908490615a23565b909155506134e39050565b60028601546001600160a01b03166000908152600e6020526040812060019081018054919290916134a9908490615a23565b909155505060028601546001600160a01b03166000908152600e6020526040812060030180548492906134dd908490615a23565b90915550505b505b83156135a9576000848152600960205260408120600180820154600490920180546001600160a01b03909316965090929091613522908490615a23565b909155505060008481526009602052604081206005018054839290613548908490615a23565b90915550506000848152600960205260409020600701541561358c576000848152600960205260408120600701805460019290613586908490615bad565b90915550505b60008481526012602052604090206135a49088614a7c565b6135b4565b6135b4604188614a7c565b6001600160a01b038316158015906135d35750600685015461ffff1615155b15613611576006850154612710906135ef9061ffff1683615b4f565b6135f99190615b6e565b91506136058282615bad565b9050613611838361498c565b6002850154613629906001600160a01b03168261498c565b83156136565760008481526009602052604081206006018054849290613650908490615a23565b90915550505b8454600186015460405160009261367b926001600160a01b0390911691602001615a3b565b60408051601f1981840301815291815281516020928301206000818152601890935291209091506136ac90896142e5565b5060008181526006602052604081205560038601541561374a576000888152601160205260409020545b80156137485760006137006136ec600184615bad565b60008c815260116020526040902090614f09565b6000818152600a60209081526040808320600101546001600160a01b0316835260179091529020909150613734908b6146d6565b508161373f81615ca3565b925050506136d6565b505b60028601546001600160a01b0316600090815260166020526040902061377090896146d6565b50600480546040805163939ddf5960e01b815290516001600160a01b039092169263939ddf5992828201926000929082900301818387803b1580156137b457600080fd5b505af11580156137c8573d6000803e3d6000fd5b5050600480546040516340c10f1960e01b81526001600160a01b0390911693506340c10f199250613805913391678ac7230489e800009101615a3b565b600060405180830381600087803b15801561381f57600080fd5b505af1158015613833573d6000803e3d6000fd5b50506040518a92507f45806e512b1f4f10e33e8b3cb64d1d11d998d8c554a95e0841fc1c701278bd5d9150600090a25050505050505050565b6000610de660415490565b60606113d3602384846147bf565b6000818152600b6020526040902080546001600160a01b03166138ba5760405162461bcd60e51b8152600401610e6290615af6565b805460018201546040516331a9108f60e11b81526001600160a01b0390921691636352211e916138f09160040190815260200190565b60206040518083038186803b15801561390857600080fd5b505afa15801561391c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139409190615b90565b6001600160a01b0316336001600160a01b031614806139f557508054600182015460405163020604bf60e21b81526001600160a01b039092169163081812fc916139909160040190815260200190565b60206040518083038186803b1580156139a857600080fd5b505afa1580156139bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139e09190615b90565b6001600160a01b0316336001600160a01b0316145b613a115760405162461bcd60e51b8152600401610e6290615bed565b805460028201546001830154604051632142170760e11b81526001600160a01b03938416936342842e0e93613a4f9333939290911691600401615c1c565b600060405180830381600087803b158015613a6957600080fd5b505af1158015613a7d573d6000803e3d6000fd5b50505050613a8f33826003015461498c565b80546001820154604051600092613ab4926001600160a01b0390911691602001615a3b565b60408051601f198184030181529181528151602092830120600081815260199093529120909150613ae590846146d6565b506000838152600b602052604080822080546001600160a01b0319908116825560018201849055600282018054909116905560038101839055600490810192909255815490516340c10f1960e01b81526001600160a01b03909116916340c10f1991613b5d913391670de0b6b3a76400009101615a3b565b600060405180830381600087803b158015613b7757600080fd5b505af1158015613b8b573d6000803e3d6000fd5b50505050505050565b60606113d3604184846141c6565b6001600160a01b0381166000908152600d6020526040902054613bc660238361439e565b10613be35760405162461bcd60e51b8152600401610e6290615a54565b6001600160a01b0381166000908152600d602052604090205461127f9060239083906143bd565b60606113d3603e84846141c6565b6000818152601060205260409020606090610e0f90614931565b6000818152601560205260409020606090610e0f9061427f565b6000818152601960205260409020606090610e0f90614931565b6000818152600b6020526040902060028101546001600160a01b03163314613cc75760405162461bcd60e51b81526020600482015260146024820152734e6f74206f776e6572206f72206d697373696e6760601b6044820152606401610e62565b613cd533826003015461498c565b80546001820154604051600092613cfa926001600160a01b0390911691602001615a3b565b60408051601f198184030181529181528151602092830120600081815260199093529120909150613d2b90846146d6565b5050506000908152600b6020526040812080546001600160a01b031990811682556001820183905560028201805490911690556003810182905560040155565b6001600160a01b038181166000908152600760205260409020600101541615613dcb5760405162461bcd60e51b8152602060048201526012602482015271105b1c9958591e481c9959da5cdd195c995960721b6044820152606401610e62565b6040516301ffc9a760e01b81526001600160a01b038216906301ffc9a790613dfe906380ac58cd60e01b90600401615c40565b60206040518083038186803b158015613e1657600080fd5b505afa158015613e2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e4e9190615c55565b613e6a5760405162461bcd60e51b8152600401610e6290615c72565b6040516301ffc9a760e01b81526001600160a01b038216906301ffc9a790613e9d90635b5e139f60e01b90600401615c40565b60206040518083038186803b158015613eb557600080fd5b505afa158015613ec9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613eed9190615c55565b613f395760405162461bcd60e51b815260206004820152601f60248201527f446f6573206e6f7420737570706f7274204552433732314d65746164617461006044820152606401610e62565b6040516301ffc9a760e01b81526001600160a01b038216906301ffc9a790613f6c9063780e9d6360e01b90600401615c40565b60206040518083038186803b158015613f8457600080fd5b505afa158015613f98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fbc9190615c55565b6140125760405162461bcd60e51b815260206004820152602160248201527f446f6573206e6f7420737570706f727420455243373231456e756d657261626c6044820152606560f81b6064820152608401610e62565b806001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b15801561404b57600080fd5b505afa15801561405f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526140879190810190615cba565b6001600160a01b038216600090815260076020908152604090912082516140b493919291909101906153a6565b506001600160a01b03811660008181526007602090815260409182902060010180546001600160a01b031916841790558151638da5cb5b60e01b81529151638da5cb5b926004808201939291829003018186803b15801561411457600080fd5b505afa925050508015614144575060408051601f3d908101601f1916820190925261414191810190615b90565b60015b61414d57614182565b6001600160a01b03811615614180576001600160a01b0381166000908152600f6020526040902061417e9083614d51565b505b505b61127f6035826149d8565b6141968161170a565b61419f816130b9565b50565b6001600160a01b0381166000908152601460205260409020606090610e0f90614931565b60606000826001600160401b038111156141e2576141e261543f565b60405190808252806020026020018201604052801561420b578160200160208202803683370190505b5060008581526001870160205260408120549192505b84811015614274578183828151811061423c5761423c615d30565b60200260200101818152505086600101600083815260200190815260200160002054915060018161426d9190615a23565b9050614221565b509095945050505050565b6060816000018054806020026020016040519081016040528092919081815260200182805480156142d957602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116142bb575b50505050509050919050565b600081815260018301602052604081205461432c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610e0f565b506000610e0f565b6143416006830182614f33565b60008080526001808401602052604082206002810184905580549192909161436a908490615a23565b9091555050600080805260018084016020526040909120015461286757600080805260019283016020526040902090910155565b6001600160a01b03166000908152600291909101602052604090205490565b60008181526001840160205260409020835482111561441f576143e08484614f52565b6001810180546001600160a01b0319166001600160a01b03851617905581845561440d60068501846150aa565b61441a6003850183614ae2565b614527565b6001600160a01b0383166000908152600285016020908152604080832054808452600588018352818420546001808a0190945291909320549091141561447357600082815260048701602052604090205491505b61447d8686614f52565b60008111801561448c57508084115b156144a757600090815260058601602052604090205461447d565b60008181526001878101602081815260408085206002015460048c0183528186205486529290915290922001546144f19160068901916001600160a01b03918216918991166150cd565b82546145245761450660038701828685615155565b6001830180546001600160a01b0319166001600160a01b0387161790555b50505b6002810180546001600160a01b0319166001600160a01b03851617905580546001908290600090614559908490615a23565b9091555050506001600160a01b0390911660009081526002909201602052604090912055565b6001600160a01b031660009081526001919091016020526040902054151590565b6001600160a01b038116600090815260018301602052604081205480156146cc5760006145ce600183615bad565b85549091506000906145e290600190615bad565b905081811461466e57600086600001828154811061460257614602615d30565b60009182526020909120015487546001600160a01b039091169150819088908590811061463157614631615d30565b600091825260208083209190910180546001600160a01b0319166001600160a01b0394851617905592909116815260018801909152604090208390555b855486908061467f5761467f615d46565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0387168252600188810190915260408220919091559350610e0f92505050565b6000915050610e0f565b600081815260018301602052604081205480156146cc5760006146fa600183615bad565b855490915060009061470e90600190615bad565b905081811461477357600086600001828154811061472e5761472e615d30565b906000526020600020015490508087600001848154811061475157614751615d30565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061478457614784615d46565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610e0f565b60606000826001600160401b038111156147db576147db61543f565b604051908082528060200260200182016040528015614804578160200160208202803683370190505b506001600160a01b0380861660009081526007880160205260408120549293509116905b84811015614274578183828151811061484357614843615d30565b6001600160a01b0392831660209182029290920181019190915292811660009081526007890190935260409092205490911690614881600182615a23565b9050614828565b60606000826001600160401b038111156148a4576148a461543f565b6040519080825280602002602001820160405280156148cd578160200160208202803683370190505b5060008581526007870160205260408120549192505b8481101561427457818382815181106148fe576148fe615d30565b60209081029190910181019190915260009283526007880190526040909120549061492a600182615a23565b90506148e3565b6060816000018054806020026020016040519081016040528092919081815260200182805480156142d957602002820191906000526020600020905b81548152602001906001019080831161496d5750505050509050919050565b614996828261519e565b6128675760405162461bcd60e51b8152602060048201526013602482015272115512081d1c985b9cd9995c8819985a5b1959606a1b6044820152606401610e62565b6149e56006830182615205565b60008080526001838101602052604082206002810180546001600160a01b0319166001600160a01b038616179055805491929091614a24908490615a23565b909155505060008080526001808401602052604090912001546001600160a01b0316612867576000808052600180840160205260409091200180546001600160a01b0383166001600160a01b03199091161790555050565b6000818152600183016020818152604080842080546002880180855283872080548852958552838720829055855491875280855292862055858552849055905255815415612867576001826000016000828254614ad99190615bad565b90915550505050565b60008080526001830160205260408120546128679184918490615155565b60008080526007830160205260408120546001600160a01b0383811691161480614b4557506001600160a01b0382811660009081526007850160205260409020541615155b806113d35750506001600160a01b03908116600090815260089290920160205260409091205416151590565b6000808052600183016020526040812054821480614b9e5750600082815260018401602052604090205415155b806113d357505060009081526002919091016020526040902054151590565b600081815260086020526040908190208054600282015460018301549351632142170760e11b815292936001600160a01b03928316936342842e0e93614c0a933093911691600401615c1c565b600060405180830381600087803b158015614c2457600080fd5b505af1158015614c38573d6000803e3d6000fd5b5050505060058101548015614ca3576000818152601260205260409020614c5f9084614a7c565b60008181526009602052604090206007015415614c9e576000818152600960205260408120600701805460019290614c98908490615bad565b90915550505b614cae565b614cae604184614a7c565b60068201805462ff00001916905581546001830154604051600092614ce1926001600160a01b0390911691602001615a3b565b60408051601f198184030181529181528151602092830120600081815260189093529120909150614d1290856142e5565b506000818152600660205260408082208290555185917f28601d865dccc9f113e15a7185c1b38c085d598c71250d3337916a428536d77191a250505050565b6000614d5d838361457f565b61432c57508154600180820184556000848152602080822090930180546001600160a01b0319166001600160a01b03861690811790915585549082528286019093526040902091909155610e0f565b600081815260018401602052604090208354821115614df857614dcf848461522d565b60018101839055818455614de66006850184614ae2565b614df36003850183614ae2565b614ed3565b6000838152600285016020908152604080832054808452600588018352818420546001808a01909452919093205490911415614e4257600082815260048701602052604090205491505b614e4c868661522d565b600081118015614e5b57508084115b15614e76576000908152600586016020526040902054614e4c565b60008181526001878101602081815260408085206002015460048c018352818620548652929091529092200154614eb39160068901918890615155565b8254614ed057614ec860038701828685615155565b600183018590555b50505b6002810183905580546001908290600090614eef908490615a23565b909155505050600091825260029092016020526040902055565b6000826000018281548110614f2057614f20615d30565b9060005260206000200154905092915050565b6000808052600283016020526040812054612867918491908490615155565b6001600160a01b0381166000908152600283016020908152604080832080549084905580845260018601909252909120805415614fa4576001816000016000828254614f9e9190615bad565b90915550505b8054614fff576001810180546001600160a01b031990811690915560028201805490911690558354821415614fe757600082815260048501602052604090205484555b8115614ffa57614ffa6003850183614a7c565b615097565b60018101546001600160a01b038481169116141561504b576001600160a01b0383811660009081526007860160205260409020546001830180546001600160a01b031916919092161790555b60028101546001600160a01b0384811691161415615097576001600160a01b0383811660009081526008860160205260409020546002830180546001600160a01b031916919092161790555b6150a46006850184615311565b50505050565b600080805260018301602052604081205461286791849184906001600160a01b03165b6001600160a01b0380841660008181526001808801602090815260408084208054878a166001600160a01b031991821681179092558186528286208054988a169882168917905596855260028b0190925280842080548716831790559083528220805490941690921790925585549091869161514a908490615a23565b909155505050505050565b600083815260018086016020908152604080842086905585845280842085905584845260028801909152808320859055848352822085905585549091869161514a908490615a23565b60408051600080825260208201928390529182916001600160a01b0386169185916151c8916159cb565b60006040518083038185875af1925050503d8060008114614274576040519150601f19603f3d011682016040523d82523d6000602084013e614274565b60008080526002830160205260408120546128679184916001600160a01b03169084906150cd565b600081815260028301602090815260408083208054908490558084526001860190925290912080541561527557600181600001600082825461526f9190615bad565b90915550505b80546152be57600060018201819055600282015583548214156152a657600082815260048501602052604090205484555b81156152b9576152b96003850183614a7c565b615304565b82816001015414156152e157600083815260078501602052604090205460018201555b828160020154141561530457600083815260088501602052604090205460028201555b6150a46006850184614a7c565b6001600160a01b0381811660008181526001850160208181526040808420805460028a0180855283872080548a1688529585528387208054928a166001600160a01b0319938416179055855483548a168852945291852080549390971692821692909217909555929091528154831690915580549091169055815415612867576001826000016000828254614ad99190615bad565b8280546153b290615abb565b90600052602060002090601f0160209004810192826153d4576000855561541a565b82601f106153ed57805160ff191683800117855561541a565b8280016001018555821561541a579182015b8281111561541a5782518255916020019190600101906153ff565b5061542692915061542a565b5090565b5b80821115615426576000815560010161542b565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561547d5761547d61543f565b604052919050565b60006001600160401b0382111561549e5761549e61543f565b50601f01601f191660200190565b600082601f8301126154bd57600080fd5b81356154d06154cb82615485565b615455565b8181528460208386010111156154e557600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561551457600080fd5b81356001600160401b0381111561552a57600080fd5b610dde848285016154ac565b60008060006060848603121561554b57600080fd5b505081359360208301359350604090920135919050565b6020808252825182820181905260009190848201906040850190845b8181101561559a5783518352928401929184019160010161557e565b50909695505050505050565b6001600160a01b038116811461419f57600080fd5b6000602082840312156155cd57600080fd5b81356113d3816155a6565b6020808252825182820181905260009190848201906040850190845b8181101561559a5783516001600160a01b0316835292840192918401916001016155f4565b60006020828403121561562b57600080fd5b5035919050565b803561ffff8116811461564457600080fd5b919050565b801515811461419f57600080fd5b600080600080600060a0868803121561566f57600080fd5b85356001600160401b038082111561568657600080fd5b61569289838a016154ac565b9650602088013591506156a4826155a6565b8195506156b360408901615632565b9450606088013591506156c582615649565b909250608087013590808211156156db57600080fd5b506156e8888289016154ac565b9150509295509295909350565b6000806040838503121561570857600080fd5b82359150602083013561571a816155a6565b809150509250929050565b6000806040838503121561573857600080fd5b8235615743816155a6565b946020939093013593505050565b6000806040838503121561576457600080fd5b50508035926020909101359150565b6000806040838503121561578657600080fd5b8235915060208301356001600160401b038111156157a357600080fd5b6157af858286016154ac565b9150509250929050565b60005b838110156157d45781810151838201526020016157bc565b838111156150a45750506000910152565b600081518084526157fd8160208601602086016157b9565b601f01601f19169290920160200192915050565b60608152600061582460608301866157e5565b828103602084015261583681866157e5565b9050828103604084015261584a81856157e5565b9695505050505050565b60a08152600061586760a08301886157e5565b6001600160a01b039690961660208301525060408101939093526060830191909152608090910152919050565b600080604083850312156158a757600080fd5b823591506158b760208401615632565b90509250929050565b600080600080600060a086880312156158d857600080fd5b85356158e3816155a6565b97602087013597506040870135966060810135965060800135945092505050565b6000806040838503121561591757600080fd5b82359150602083013561571a81615649565b600061014080835261593d8184018e6157e5565b6001600160a01b038d16602085015261ffff8c1660408501528a1515606085015283810360808501529050615972818a6157e5565b60a0840198909852505060c081019490945260e08401929092526101008301526101209091015295945050505050565b6020808252600f908201526e2737ba103a37b5b2b71037bbb732b960891b604082015260600190565b600082516159dd8184602087016157b9565b9190910192915050565b6020808252600c908201526b08ccaca40e8dede40d0d2ced60a31b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60008219821115615a3657615a36615a0d565b500190565b6001600160a01b03929092168252602082015260400190565b6020808252600f908201526e52616e6b20757020746f206461746560881b604082015260600190565b6020808252601190820152702737ba103437bab9b29031bab930ba37b960791b604082015260600190565b6020815260006113d360208301846157e5565b600181811c90821680615acf57607f821691505b60208210811415615af057634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600e908201526d111bd95cc81b9bdd08195e1a5cdd60921b604082015260600190565b6020808252601790820152762737ba1030b8383937bb32b210313c9031bab930ba37b960491b604082015260600190565b6000816000190483118215151615615b6957615b69615a0d565b500290565b600082615b8b57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215615ba257600080fd5b81516113d3816155a6565b600082821015615bbf57615bbf615a0d565b500390565b6020808252600f908201526e105b1c9958591e481cdd185c9d1959608a1b604082015260600190565b602080825260159082015274139bdd081bdddb995c881bdc88185c1c1c9bdd9959605a1b604082015260600190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160e01b031991909116815260200190565b600060208284031215615c6757600080fd5b81516113d381615649565b602080825260179082015276446f6573206e6f7420737570706f72742045524337323160481b604082015260600190565b600081615cb257615cb2615a0d565b506000190190565b600060208284031215615ccc57600080fd5b81516001600160401b03811115615ce257600080fd5b8201601f81018413615cf357600080fd5b8051615d016154cb82615485565b818152856020838501011115615d1657600080fd5b615d278260208301602086016157b9565b95945050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fdfea264697066735822122089cf9b647bba9eaccb89eeccf586b362cba98ccd9f22f0acf3aafc9603d575d164736f6c63430008090033

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

000000000000000000000000bb76a956ef664c942bc2e952b172e553118a463c

-----Decoded View---------------
Arg [0] : tuxERC20_ (address): 0xBb76A956eF664c942bC2e952B172e553118a463c

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000bb76a956ef664c942bc2e952b172e553118a463c


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.