ETH Price: $3,276.19 (+0.90%)

Contract

0xd8DB2B119E0c1aDdb7969Ea2031963e373ebfFdE
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Settle Auction176747412023-07-12 3:11:59549 days ago1689131519IN
0xd8DB2B11...373ebfFdE
0 ETH0.0022988513.2617311
Settle Auction176747382023-07-12 3:11:23549 days ago1689131483IN
0xd8DB2B11...373ebfFdE
0 ETH0.0023078713.31379587
Create Bid176741012023-07-12 1:03:35549 days ago1689123815IN
0xd8DB2B11...373ebfFdE
0.235 ETH0.001030115.15355762
Create Bid176740972023-07-12 1:02:47549 days ago1689123767IN
0xd8DB2B11...373ebfFdE
0.2 ETH0.0010129114.90060563
Create Bid176740922023-07-12 1:01:47549 days ago1689123707IN
0xd8DB2B11...373ebfFdE
0.175 ETH0.0009707214.27995996
Create Bid176740662023-07-12 0:56:11549 days ago1689123371IN
0xd8DB2B11...373ebfFdE
0.15 ETH0.0007987412.31590671
Create Bid176739932023-07-12 0:41:35549 days ago1689122495IN
0xd8DB2B11...373ebfFdE
0.125 ETH0.0008647713.3339187
Create Bid176739222023-07-12 0:27:11549 days ago1689121631IN
0xd8DB2B11...373ebfFdE
0.1 ETH0.0008647513.33374187
Create Bid176736112023-07-11 23:24:11549 days ago1689117851IN
0xd8DB2B11...373ebfFdE
0.175 ETH0.0008975413.83925707
Settle Auction176734002023-07-11 22:41:23549 days ago1689115283IN
0xd8DB2B11...373ebfFdE
0 ETH0.0027707715.98415911
Create Bid176733472023-07-11 22:30:35549 days ago1689114635IN
0xd8DB2B11...373ebfFdE
0.4 ETH0.0011520216.94706561
Create Bid176733252023-07-11 22:26:11549 days ago1689114371IN
0xd8DB2B11...373ebfFdE
0.35 ETH0.0012879615.13861379
Create Bid176733132023-07-11 22:23:47549 days ago1689114227IN
0xd8DB2B11...373ebfFdE
0.325 ETH0.0010561316.28453166
Create Bid176733132023-07-11 22:23:47549 days ago1689114227IN
0xd8DB2B11...373ebfFdE
0.275 ETH0.0011125916.36705391
Create Bid176733102023-07-11 22:23:11549 days ago1689114191IN
0xd8DB2B11...373ebfFdE
0.25 ETH0.0010278715.12066159
Create Bid176732972023-07-11 22:20:35549 days ago1689114035IN
0xd8DB2B11...373ebfFdE
0.25 ETH0.0010314915.90461249
Create Bid176732892023-07-11 22:18:59549 days ago1689113939IN
0xd8DB2B11...373ebfFdE
0.225 ETH0.001052616.23007739
Settle Auction176732072023-07-11 22:02:23549 days ago1689112943IN
0xd8DB2B11...373ebfFdE
0 ETH0.0041481723.54976604
Create Bid176724372023-07-11 19:25:35549 days ago1689103535IN
0xd8DB2B11...373ebfFdE
0.2 ETH0.0011911918.36699717
Create Bid176724152023-07-11 19:21:11549 days ago1689103271IN
0xd8DB2B11...373ebfFdE
0.075 ETH0.001451922.3868672
Create Bid176718142023-07-11 17:19:59549 days ago1689095999IN
0xd8DB2B11...373ebfFdE
0.3525 ETH0.0021869132.17085911
Create Bid176717932023-07-11 17:15:47549 days ago1689095747IN
0xd8DB2B11...373ebfFdE
0.3275 ETH0.0021032130.93970637
Create Bid176717872023-07-11 17:14:35549 days ago1689095675IN
0xd8DB2B11...373ebfFdE
0.25 ETH0.0021189531.17116891
Create Bid176717822023-07-11 17:13:35549 days ago1689095615IN
0xd8DB2B11...373ebfFdE
0.225 ETH0.0013742331.51563278
Create Bid176717822023-07-11 17:13:35549 days ago1689095615IN
0xd8DB2B11...373ebfFdE
0.225 ETH0.0013742331.51563278
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block
From
To
176747412023-07-12 3:11:59549 days ago1689131519
0xd8DB2B11...373ebfFdE
0.175 ETH
176747382023-07-12 3:11:23549 days ago1689131483
0xd8DB2B11...373ebfFdE
0.235 ETH
176741012023-07-12 1:03:35549 days ago1689123815
0xd8DB2B11...373ebfFdE
0.2 ETH
176740972023-07-12 1:02:47549 days ago1689123767
0xd8DB2B11...373ebfFdE
0.175 ETH
176740922023-07-12 1:01:47549 days ago1689123707
0xd8DB2B11...373ebfFdE
0.15 ETH
176740662023-07-12 0:56:11549 days ago1689123371
0xd8DB2B11...373ebfFdE
0.125 ETH
176739932023-07-12 0:41:35549 days ago1689122495
0xd8DB2B11...373ebfFdE
0.1 ETH
176739222023-07-12 0:27:11549 days ago1689121631
0xd8DB2B11...373ebfFdE
0.075 ETH
176736112023-07-11 23:24:11549 days ago1689117851
0xd8DB2B11...373ebfFdE
0.15 ETH
176734002023-07-11 22:41:23549 days ago1689115283
0xd8DB2B11...373ebfFdE
0.4 ETH
176733472023-07-11 22:30:35549 days ago1689114635
0xd8DB2B11...373ebfFdE
0.35 ETH
176733252023-07-11 22:26:11549 days ago1689114371
0xd8DB2B11...373ebfFdE
0.325 ETH
176733132023-07-11 22:23:47549 days ago1689114227
0xd8DB2B11...373ebfFdE
0.275 ETH
176733132023-07-11 22:23:47549 days ago1689114227
0xd8DB2B11...373ebfFdE
0.25 ETH
176733102023-07-11 22:23:11549 days ago1689114191
0xd8DB2B11...373ebfFdE
0.225 ETH
176732972023-07-11 22:20:35549 days ago1689114035
0xd8DB2B11...373ebfFdE
0.225 ETH
176732892023-07-11 22:18:59549 days ago1689113939
0xd8DB2B11...373ebfFdE
0.2 ETH
176732072023-07-11 22:02:23549 days ago1689112943
0xd8DB2B11...373ebfFdE
0.3525 ETH
176724372023-07-11 19:25:35549 days ago1689103535
0xd8DB2B11...373ebfFdE
0.175 ETH
176724152023-07-11 19:21:11549 days ago1689103271
0xd8DB2B11...373ebfFdE
0.05 ETH
176718142023-07-11 17:19:59549 days ago1689095999
0xd8DB2B11...373ebfFdE
0.3275 ETH
176717932023-07-11 17:15:47549 days ago1689095747
0xd8DB2B11...373ebfFdE
0.25 ETH
176717872023-07-11 17:14:35549 days ago1689095675
0xd8DB2B11...373ebfFdE
0.225 ETH
176717812023-07-11 17:13:23549 days ago1689095603
0xd8DB2B11...373ebfFdE
0.2 ETH
176717782023-07-11 17:12:47549 days ago1689095567
0xd8DB2B11...373ebfFdE
0.175 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FigmataAuction

Compiler Version
v0.8.18+commit.87f61d96

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
File 1 of 13 : FigmataAuction.sol
// SPDX-License-Identifier: MIT
// Archetype ParallelAutoAuctionExtension
//
//        d8888                 888               888
//       d88888                 888               888
//      d88P888                 888               888
//     d88P 888 888d888 .d8888b 88888b.   .d88b.  888888 888  888 88888b.   .d88b.
//    d88P  888 888P"  d88P"    888 "88b d8P  Y8b 888    888  888 888 "88b d8P  Y8b
//   d88P   888 888    888      888  888 88888888 888    888  888 888  888 88888888
//  d8888888888 888    Y88b.    888  888 Y8b.     Y88b.  Y88b 888 888 d88P Y8b.
// d88P     888 888     "Y8888P 888  888  "Y8888   "Y888  "Y88888 88888P"   "Y8888
//                                                            888 888
//                                                       Y8b d88P 888
//                                                        "Y88P"  888

pragma solidity ^0.8.4;

import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "./interfaces/ISharesHolder.sol";
import "./ParallelAutoAuction.sol";


error NotVip();

struct Options {
    bool sharesUpdaterUpdatingLocked;
    bool vipRequiredTokensLocked;
    bool vipIdsLocked;
}


contract FigmataAuction is ParallelAutoAuction, ISharesHolder {

    mapping(address => uint256) private _rewardTokenShares;
	mapping(address => bool) private _allowSharesUpdate;
    mapping(uint24 => bool) private _tokenIdIsVip;

    address[] public tokensRequiredToOwnToBeVip;

    Options public options;

    function createBid(uint24 nftId) override public payable {

        if (_tokenIdIsVip[nftId] && !userIsVip(msg.sender))
            revert NotVip();

		super.createBid(nftId);
		_rewardTokenShares[msg.sender] += msg.value;
	}

    /* ----------------------- *\
    |* Vip token configuration *|
    \* ----------------------- */
    function setVipIds(uint24[] memory ids, bool areVip) external onlyOwner {
        if (options.vipIdsLocked) revert OptionLocked();
        for (uint256 i = 0; i < ids.length; i++) _tokenIdIsVip[ids[i]] = areVip;
    }

    function isVipId(uint24 id) external view returns (bool) {
        return _tokenIdIsVip[id];
    }

    function setTokensRequiredToHoldToBeVip(address[] memory tokens) external onlyOwner {
        if (options.vipRequiredTokensLocked) revert OptionLocked(); 
        tokensRequiredToOwnToBeVip = tokens;
    }

    /**
     * @return itIs Only if `user` holds at least one `tokensRequiredToOwnToBeVip`.
     */
    function userIsVip(address user) public view returns (bool itIs) {
        for (uint256 i = 0; i < tokensRequiredToOwnToBeVip.length; i++)
            if (IERC721(tokensRequiredToOwnToBeVip[i]).balanceOf(user) > 0)
                return true;
    }


    /* ---------------------------- *\
    |* ISharesHolder implementation *|
    \* ---------------------------- */
	function getAndClearSharesFor(address user) external returns (uint256 shares) {
		require(_allowSharesUpdate[msg.sender]);
		shares = _rewardTokenShares[user];
		delete _rewardTokenShares[user];
	}

	function addSharesUpdater(address updater) external onlyOwner {
        if (options.sharesUpdaterUpdatingLocked) revert OptionLocked();
		_allowSharesUpdate[updater] = true;
	}

	function removeSharesUpdater(address updater) external onlyOwner {
        if (options.sharesUpdaterUpdatingLocked) revert OptionLocked();
		_allowSharesUpdate[updater] = false;
	}

	function getIsSharesUpdater(address updater) external view returns (bool) {
		return _allowSharesUpdate[updater];
	}

	function getTokenShares(address user) external view returns (uint256) {
		return _rewardTokenShares[user];
	}

    /* ---------------------------------- *\
    |* Contract locking and configuration *|
    \* ---------------------------------- */
    function lockSharesUpdaterUpdatingForever() external onlyOwner {
        options.sharesUpdaterUpdatingLocked = true;
    }
    
    function lockTokensRequiredToHoldToBeVipForever() external onlyOwner {
        options.vipRequiredTokensLocked = true;
    }

    function lockVipIdsForever() external onlyOwner {
        options.vipIdsLocked = true;
    }

}

File 2 of 13 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 3 of 13 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)

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`.
     *
     * 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;

    /**
     * @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 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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * 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 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 the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

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

File 4 of 13 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

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

pragma solidity ^0.8.0;

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

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

pragma solidity ^0.8.4;

interface IAuctionInfo {
    /**
     * @return The auctioned NFT (or maybe any other type of token).
     */
    function getAuctionedToken() external view returns (address);

    /**
     * @return An array with all the token ids that 
     * can currently get auctioned.
     */
    function getIdsToAuction() external view returns (uint24[] memory);

    /**
     * @return The current minimum bid price for an auctionable `tokenId`.
     * If `tokenId` not in `this.getIdsToAuction()`, it should revert.
     */
    function getMinPriceFor(uint24 tokenId) external view returns (uint96);
}

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

pragma solidity ^0.8.4;

import "./IAuctionInfo.sol";

interface IEthAuction is IAuctionInfo {
    /**
     * @dev Create a `msg.value` bid for a NFT.
     */
    function createBid(uint24 nftId) external payable;
}

File 8 of 13 : IExternallyMintable.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.4;

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

interface IExternallyMintable is IERC721 {
    /**
     * @dev Allows the minter to mint a NFT to `to`.
     */
    function mint(uint24 tokenId, address to) external;
    
    /**
     * @return If `tokenId` was already minted (ie, if it exists).
     */
    function exists(uint24 tokenId) external view returns (bool);
    
    /**
     * @dev Sets a `minter` so it can use the `mint` method.
     */
    function addMinter(address minter) external;

    /**
     * @dev Disallow `minter` from using the `mint` method.
     */
    function removeMinter(address minter) external;

    /**
     * @return If `minter` is allowed to call the `mint` function.
     */
    function isMinter(address minter) external view returns (bool);

    /**
     * @return The max supply of the token, so the auction that will
     * use it knows wheres the mints limit.
     */
    function maxSupply() external view returns (uint24);
}

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

pragma solidity ^0.8.4;

struct AuctionConfig {
    address auctionedNft;
    /**
     * @notice The number of auctions that can happen at the same time. For
     * example, if `lines == 3`, those will be the auctioned token ids over
     * time:
     *
     * --- TIME --->
     * 
     *  line 1: |--- 1 ---|---- 4 ----|--- 7 ---|---- 10 ---- ...
     *  line 2: |-- 2 --|----- 5 -----|-- 8 --|---- 11 ---- ...
     *  line 3: |---- 3 ----|-- 6 --|---- 9 ----|----- 12 ----- ...
     *
     * Then, from the front-end, you only need to call `lineToState[l].head`
     * to query the current auctioned nft at line `l`. For example, in the
     * graph above, `lineToState[2].head == 11`.
     */
    uint8 lines;
    // @notice The base duration is the time that takes a single auction
    // without considering time buffering.
    uint32 baseDuration;
    // @notice Extra auction time if a bid happens close to the auction end.
    uint32 timeBuffer;
    // @notice The minimum price accepted in an auction.
    uint96 startingPrice;
    // @notice The minimum bid increment.
    uint96 bidIncrement;
}

    
/**
 * @dev LineState represents a single auction line, so there will be
 * exactly `_auctionConfig.lines` LineStates.
 */
struct LineState {
    // @notice head Is the current auctioned token id at the line.
    uint24 head;
    uint40 startTime;
    uint40 endTime;
    address currentWinner;
    uint96 currentPrice;
}

interface IHoldsParallelAutoAuctionData {
    function auctionConfig() external view returns (AuctionConfig memory);
    /**
     * @return Current line state at `tokenId`, with data updated if the
     * auction for that line should get settled.
     */
    function lineState(uint24 tokenId) external view returns (LineState memory);
    /**
     * @return All `LineState`s.
     */
    function lineStates() external view returns (LineState[] memory);
}

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

pragma solidity ^0.8.4;

import "./IEthAuction.sol";
import "./IHoldsParallelAutoAuctionData.sol";

interface IParallelAutoAuction is IEthAuction, IHoldsParallelAutoAuctionData {
    
    event Bid(uint24 indexed tokenId, address bidder, uint256 value);
    event Won(uint24 indexed tokenId, address bidder, uint256 value);

    /**
     * @dev This method lets a `nftId` winner to claim it after an aunction ends,
     * It can also be used to claim the last auctioned `nftIds`s. Note that this
     * has to do with the original `BonklerAuction` contract, which automatically
     * settles auction when the auction for the next `nftId` starts.
     */
    function settleAuction(uint24 nftId) external;
}

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

pragma solidity ^0.8.4;

interface ISharesHolder {

	/**
	 * @param updater Should be an IRewardClaimer.
	 */
	function addSharesUpdater(address updater) external;

	/**
	 * @dev An IRewardClaimer will use this function to calculate rewards for
	 * a bidder.
	 */
	function getAndClearSharesFor(address user) external returns (uint256);

	function getTokenShares(address user) external view returns (uint256);

	function getIsSharesUpdater(address updater) external view returns (bool);

}

File 12 of 13 : ParallelAutoAuction.sol
// SPDX-License-Identifier: MIT
// Archetype ParallelAutoAuction
//
//        d8888                 888               888
//       d88888                 888               888
//      d88P888                 888               888
//     d88P 888 888d888 .d8888b 88888b.   .d88b.  888888 888  888 88888b.   .d88b.
//    d88P  888 888P"  d88P"    888 "88b d8P  Y8b 888    888  888 888 "88b d8P  Y8b
//   d88P   888 888    888      888  888 88888888 888    888  888 888  888 88888888
//  d8888888888 888    Y88b.    888  888 Y8b.     Y88b.  Y88b 888 888 d88P Y8b.
// d88P     888 888     "Y8888P 888  888  "Y8888   "Y888  "Y88888 88888P"   "Y8888
//                                                            888 888
//                                                       Y8b d88P 888
//                                                        "Y88P"  888

pragma solidity ^0.8.4;

import "./interfaces/IParallelAutoAuction.sol";
import "./interfaces/IExternallyMintable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "solady/src/utils/SafeTransferLib.sol";


error WrongTokenId();
error WrongBidAmount();
error AuctionPaused();
error OptionLocked();

struct StateLocks {
    bool initializationLocked;
    bool baseDurationLocked;
    bool timeBufferLocked;
    bool startingPriceLocked;
    bool bidIncrementLocked;
}


contract ParallelAutoAuction is IParallelAutoAuction, Ownable {
    
    // @notice The config for the auction should be immutable.
    AuctionConfig private _auctionConfig;
    
    StateLocks private _stateLocks;

    // @notice `_lineToState[i]` should only be mutable from the line `i`. 
    mapping(uint8 => LineState) private _lineToState;

    function initialize(
        address nftToAuction,
        uint8 lines,
        uint32 baseDuration,
        uint32 timeBuffer,
        uint96 startingPrice,
        uint96 bidIncrement
    ) external onlyOwner {
        require(!_stateLocks.initializationLocked); 
        _stateLocks.initializationLocked = true;

        require(bidIncrement > 0);

        _auctionConfig.auctionedNft = nftToAuction;
        _auctionConfig.lines = lines;
        _auctionConfig.baseDuration = baseDuration;
        _auctionConfig.timeBuffer = timeBuffer;
        _auctionConfig.startingPrice = startingPrice;
        _auctionConfig.bidIncrement = bidIncrement;
    }

    /* ------------- *\
    |* Bidding logic *|
    \* ------------- */
    /**
     * @dev Create a bid for a NFT, with a given amount.
     * This contract only accepts payment in ETH.
     */
    function createBid(uint24 nftId) public payable virtual {
        
        uint8 lineNumber = tokenIdToLineNumber(nftId);
        LineState storage line = _lineToState[lineNumber];
        IExternallyMintable token = IExternallyMintable(_auctionConfig.auctionedNft);
        
        if (!token.isMinter(address(this)))
            revert AuctionPaused();

        /* ---------- AUCTION UPDATING AND SETTLEMENT ---------- */
        if (block.timestamp > line.endTime) {
            if (!token.exists(line.head) && line.head > 0) _settleAuction(line);
            _updateLine(line, lineNumber);
        }

        if (line.head != nftId || nftId > token.maxSupply())
            revert WrongTokenId();
        
        /* ------------------ BIDDING LOGIC ------------------ */
        bool winnerExists = line.currentWinner != address(0);
        if (
            (!winnerExists && _auctionConfig.startingPrice > msg.value) ||
            (winnerExists && line.currentPrice + _auctionConfig.bidIncrement > msg.value)
        ) revert WrongBidAmount();

        if (line.currentPrice != 0)
            SafeTransferLib.forceSafeTransferETH(line.currentWinner, line.currentPrice);

        line.currentPrice = uint96(msg.value);
        line.currentWinner = msg.sender;

        emit Bid(nftId, msg.sender, msg.value);
        
        uint40 extendedTime = uint40(block.timestamp + _auctionConfig.timeBuffer);
        if (extendedTime > line.endTime)
            line.endTime = extendedTime;

    }

    function settleAuction(uint24 nftId) external {
        LineState memory line = _lineToState[tokenIdToLineNumber(nftId)];
        IExternallyMintable token = IExternallyMintable(_auctionConfig.auctionedNft);
        require(block.timestamp > line.endTime, "Auction still ongoing.");
        require(line.head != 0, "Auction not started.");
        require(!token.exists(nftId), "Token already settled.");
        _settleAuction(line);
    }

    function _settleAuction(LineState memory line) private {
        emit Won(line.head, line.currentWinner, line.currentPrice);
        address nftContract = _auctionConfig.auctionedNft;
        IExternallyMintable(nftContract).mint(line.head, line.currentWinner);
        payable(nftContract).transfer(line.currentPrice);
    }
    
    /**
     * @dev `line.head` will be the current token id auctioned at the
     * `line`. If is the first auction for this line (if `line.head == 0`)
     * then the token id should be the line number itself. Otherwise
     * increment the id by the number of lines. For more info about the 
     * second case check the `AuctionConfig.lines` doc.
     * @notice This function should be the only one allowed to change
     * `line.startTime`, `line.endTime` and `line.head` state, and it should
     * do so only when the dev is sure thats its time to auction the next
     * token id.
     */
    function _updateLine(LineState storage line, uint8 lineNumber) private {
        line.startTime = uint40(block.timestamp);
        line.endTime = uint40(block.timestamp + _auctionConfig.baseDuration);

        if (line.head == 0) line.head = lineNumber; 
        else {
            line.head += _auctionConfig.lines;
            line.currentPrice = 0;
            line.currentWinner = address(0);
        }
    }

    /* --------------------------- *\
    |* IAuctionInfo implementation *|
    \* --------------------------- */
    function getIdsToAuction() external view returns (uint24[] memory) {
        uint24[] memory ids = new uint24[](_auctionConfig.lines);
        for (uint8 i = 0; i < _auctionConfig.lines; i++) {
            LineState memory line = _lineToState[i+1];
            uint24 lineId = line.head;
            if (lineId == 0) lineId = i + 1;
            else if (block.timestamp > line.endTime) lineId += _auctionConfig.lines;
            ids[i] = lineId;
        }
        return ids;
    }

    function getAuctionedToken() external view returns (address) {
        return _auctionConfig.auctionedNft;
    }
    
    // TODO it should revert if `tokenId != expectedHead`
    function getMinPriceFor(uint24 tokenId) external view returns (uint96) {
        uint8 lineNumber = uint8(tokenId % _auctionConfig.lines);
        LineState memory line = _lineToState[lineNumber];
        if (block.timestamp > line.endTime) return _auctionConfig.startingPrice;
        else return line.currentPrice + _auctionConfig.bidIncrement;
    }
    

    /* -------------------------------------------- *\
    |* IHoldsParallelAutoAuctionData implementation *|
    \* -------------------------------------------- */
    function auctionConfig() external view returns (AuctionConfig memory) {
        return _auctionConfig;    
    }

    function lineState(uint24 tokenId) external view returns (LineState memory) {
        return _lineState(tokenId);
    }

    function lineStates() external view returns (LineState[] memory lines) {
        lines = new LineState[](_auctionConfig.lines);
        for (uint8 i = 0; i < _auctionConfig.lines; i++)
            lines[i] = _lineState(i+1);
    }
    
    function _lineState(uint24 tokenId) private view returns (LineState memory line) {
        uint8 lineNumber = tokenIdToLineNumber(tokenId);
        line = _lineToState[lineNumber];
        
        if (block.timestamp > line.endTime) {
            line.head += line.head == 0 ? lineNumber : _auctionConfig.lines;
            line.startTime = uint40(block.timestamp);
            line.endTime = uint40(block.timestamp + _auctionConfig.baseDuration);
            line.currentWinner = address(0);
            line.currentPrice = 0;
        }
    }

    /**
     * @return A value that will always be in {1, 2, ..., _auctionConfig.lines}.
     * So the returned value will always be a valid line number.
     */
    function tokenIdToLineNumber(uint24 tokenId) public view returns (uint8) {
        return uint8((tokenId - 1) % _auctionConfig.lines) + 1;
    }


    /* ----------------------------------- *\
    |* General contract state manipulation *|
    \* ----------------------------------- */
    /**
     * @dev Updating `baseDuration` will only affect to future auctions.
     */
    function setBaseDuration(uint32 baseDuration) external onlyOwner {
        if (_stateLocks.baseDurationLocked) revert OptionLocked();
        _auctionConfig.baseDuration = baseDuration;
    }

    /**
     * @dev Updating `timeBuffer` will only affect to future bufferings.
     */
    function setTimeBuffer(uint32 timeBuffer) external onlyOwner {
        if (_stateLocks.timeBufferLocked) revert OptionLocked();
        _auctionConfig.timeBuffer = timeBuffer; 
    }

    /**
     * @dev Updating `startingPrice` will only affect to future auctions.
     */
    function setStartingPrice(uint96 startingPrice) external onlyOwner {
        if (_stateLocks.startingPriceLocked) revert OptionLocked();
        _auctionConfig.startingPrice = startingPrice;
    }

    /**
     * @dev Updating `bidIncrement` will only affect to future increments.
     */
    function setBidIncrement(uint96 bidIncrement) external onlyOwner {
        if (_stateLocks.bidIncrementLocked) revert OptionLocked();
        _auctionConfig.bidIncrement = bidIncrement;
    }
    

    /* ---------------- *\
    |* Contract locking *|
    \* ---------------- */
    function lockBaseDurationForever() external onlyOwner {
        _stateLocks.baseDurationLocked = true;
    }

    function lockTimeBufferForever() external onlyOwner {
        _stateLocks.timeBufferLocked = true;
    }

    function lockStartingPriceForever() external onlyOwner {
        _stateLocks.startingPriceLocked = true;
    }

    function lockBidIncrementForever() external onlyOwner {
        _stateLocks.bidIncrementLocked = true;
    }
}

File 13 of 13 : SafeTransferLib.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Caution! This library won't check that a token has code, responsibility is delegated to the caller.
library SafeTransferLib {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The ETH transfer has failed.
    error ETHTransferFailed();

    /// @dev The ERC20 `transferFrom` has failed.
    error TransferFromFailed();

    /// @dev The ERC20 `transfer` has failed.
    error TransferFailed();

    /// @dev The ERC20 `approve` has failed.
    error ApproveFailed();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Suggested gas stipend for contract receiving ETH
    /// that disallows any storage writes.
    uint256 internal constant _GAS_STIPEND_NO_STORAGE_WRITES = 2300;

    /// @dev Suggested gas stipend for contract receiving ETH to perform a few
    /// storage reads and writes, but low enough to prevent griefing.
    /// Multiply by a small constant (e.g. 2), if needed.
    uint256 internal constant _GAS_STIPEND_NO_GRIEF = 100000;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       ETH OPERATIONS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Sends `amount` (in wei) ETH to `to`.
    /// Reverts upon failure.
    function safeTransferETH(address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // Transfer the ETH and check if it succeeded or not.
            if iszero(call(gas(), to, amount, 0, 0, 0, 0)) {
                // Store the function selector of `ETHTransferFailed()`.
                mstore(0x00, 0xb12d13eb)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
    /// The `gasStipend` can be set to a low enough value to prevent
    /// storage writes or gas griefing.
    ///
    /// If sending via the normal procedure fails, force sends the ETH by
    /// creating a temporary contract which uses `SELFDESTRUCT` to force send the ETH.
    ///
    /// Reverts if the current contract has insufficient balance.
    function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // If insufficient balance, revert.
            if lt(selfbalance(), amount) {
                // Store the function selector of `ETHTransferFailed()`.
                mstore(0x00, 0xb12d13eb)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
            // Transfer the ETH and check if it succeeded or not.
            if iszero(call(gasStipend, to, amount, 0, 0, 0, 0)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                // We can directly use `SELFDESTRUCT` in the contract creation.
                // Compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758
                if iszero(create(amount, 0x0b, 0x16)) {
                    // For better gas estimation.
                    if iszero(gt(gas(), 1000000)) { revert(0, 0) }
                }
            }
        }
    }

    /// @dev Force sends `amount` (in wei) ETH to `to`, with a gas stipend
    /// equal to `_GAS_STIPEND_NO_GRIEF`. This gas stipend is a reasonable default
    /// for 99% of cases and can be overriden with the three-argument version of this
    /// function if necessary.
    ///
    /// If sending via the normal procedure fails, force sends the ETH by
    /// creating a temporary contract which uses `SELFDESTRUCT` to force send the ETH.
    ///
    /// Reverts if the current contract has insufficient balance.
    function forceSafeTransferETH(address to, uint256 amount) internal {
        // Manually inlined because the compiler doesn't inline functions with branches.
        /// @solidity memory-safe-assembly
        assembly {
            // If insufficient balance, revert.
            if lt(selfbalance(), amount) {
                // Store the function selector of `ETHTransferFailed()`.
                mstore(0x00, 0xb12d13eb)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
            // Transfer the ETH and check if it succeeded or not.
            if iszero(call(_GAS_STIPEND_NO_GRIEF, to, amount, 0, 0, 0, 0)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                // We can directly use `SELFDESTRUCT` in the contract creation.
                // Compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758
                if iszero(create(amount, 0x0b, 0x16)) {
                    // For better gas estimation.
                    if iszero(gt(gas(), 1000000)) { revert(0, 0) }
                }
            }
        }
    }

    /// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
    /// The `gasStipend` can be set to a low enough value to prevent
    /// storage writes or gas griefing.
    ///
    /// Simply use `gasleft()` for `gasStipend` if you don't need a gas stipend.
    ///
    /// Note: Does NOT revert upon failure.
    /// Returns whether the transfer of ETH is successful instead.
    function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)
        internal
        returns (bool success)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Transfer the ETH and check if it succeeded or not.
            success := call(gasStipend, to, amount, 0, 0, 0, 0)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      ERC20 OPERATIONS                      */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
    /// Reverts upon failure.
    ///
    /// The `from` account must have at least `amount` approved for
    /// the current contract to manage.
    function safeTransferFrom(address token, address from, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.

            mstore(0x60, amount) // Store the `amount` argument.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(96, from)) // Store the `from` argument.
            // Store the function selector of `transferFrom(address,address,uint256)`.
            mstore(0x0c, 0x23b872dd000000000000000000000000)

            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    // Set success to whether the call reverted, if not we check it either
                    // returned exactly 1 (can't just be non-zero data), or had no return data.
                    or(eq(mload(0x00), 1), iszero(returndatasize())),
                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
                )
            ) {
                // Store the function selector of `TransferFromFailed()`.
                mstore(0x00, 0x7939f424)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }

            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends all of ERC20 `token` from `from` to `to`.
    /// Reverts upon failure.
    ///
    /// The `from` account must have at least `amount` approved for
    /// the current contract to manage.
    function safeTransferAllFrom(address token, address from, address to)
        internal
        returns (uint256 amount)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.

            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(96, from)) // Store the `from` argument.
            // Store the function selector of `balanceOf(address)`.
            mstore(0x0c, 0x70a08231000000000000000000000000)
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                    staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)
                )
            ) {
                // Store the function selector of `TransferFromFailed()`.
                mstore(0x00, 0x7939f424)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }

            // Store the function selector of `transferFrom(address,address,uint256)`.
            mstore(0x00, 0x23b872dd)
            // The `amount` argument is already written to the memory word at 0x6c.
            amount := mload(0x60)

            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    // Set success to whether the call reverted, if not we check it either
                    // returned exactly 1 (can't just be non-zero data), or had no return data.
                    or(eq(mload(0x00), 1), iszero(returndatasize())),
                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
                )
            ) {
                // Store the function selector of `TransferFromFailed()`.
                mstore(0x00, 0x7939f424)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }

            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.
    /// Reverts upon failure.
    function safeTransfer(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            // Store the function selector of `transfer(address,uint256)`.
            mstore(0x00, 0xa9059cbb000000000000000000000000)

            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    // Set success to whether the call reverted, if not we check it either
                    // returned exactly 1 (can't just be non-zero data), or had no return data.
                    or(eq(mload(0x00), 1), iszero(returndatasize())),
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                // Store the function selector of `TransferFailed()`.
                mstore(0x00, 0x90b8ec18)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
            // Restore the part of the free memory pointer that was overwritten.
            mstore(0x34, 0)
        }
    }

    /// @dev Sends all of ERC20 `token` from the current contract to `to`.
    /// Reverts upon failure.
    function safeTransferAll(address token, address to) internal returns (uint256 amount) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`.
            mstore(0x20, address()) // Store the address of the current contract.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                    staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20)
                )
            ) {
                // Store the function selector of `TransferFailed()`.
                mstore(0x00, 0x90b8ec18)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }

            mstore(0x14, to) // Store the `to` argument.
            // The `amount` argument is already written to the memory word at 0x34.
            amount := mload(0x34)
            // Store the function selector of `transfer(address,uint256)`.
            mstore(0x00, 0xa9059cbb000000000000000000000000)

            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    // Set success to whether the call reverted, if not we check it either
                    // returned exactly 1 (can't just be non-zero data), or had no return data.
                    or(eq(mload(0x00), 1), iszero(returndatasize())),
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                // Store the function selector of `TransferFailed()`.
                mstore(0x00, 0x90b8ec18)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
            // Restore the part of the free memory pointer that was overwritten.
            mstore(0x34, 0)
        }
    }

    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
    /// Reverts upon failure.
    function safeApprove(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            // Store the function selector of `approve(address,uint256)`.
            mstore(0x00, 0x095ea7b3000000000000000000000000)

            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    // Set success to whether the call reverted, if not we check it either
                    // returned exactly 1 (can't just be non-zero data), or had no return data.
                    or(eq(mload(0x00), 1), iszero(returndatasize())),
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                // Store the function selector of `ApproveFailed()`.
                mstore(0x00, 0x3e3f8f73)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
            // Restore the part of the free memory pointer that was overwritten.
            mstore(0x34, 0)
        }
    }

    /// @dev Returns the amount of ERC20 `token` owned by `account`.
    /// Returns zero if the `token` does not exist.
    function balanceOf(address token, address account) internal view returns (uint256 amount) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, account) // Store the `account` argument.
            // Store the function selector of `balanceOf(address)`.
            mstore(0x00, 0x70a08231000000000000000000000000)
            amount :=
                mul(
                    mload(0x20),
                    and( // The arguments of `and` are evaluated from right to left.
                        gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                        staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)
                    )
                )
        }
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[],"name":"AuctionPaused","type":"error"},{"inputs":[],"name":"NotVip","type":"error"},{"inputs":[],"name":"OptionLocked","type":"error"},{"inputs":[],"name":"WrongBidAmount","type":"error"},{"inputs":[],"name":"WrongTokenId","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint24","name":"tokenId","type":"uint24"},{"indexed":false,"internalType":"address","name":"bidder","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Bid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint24","name":"tokenId","type":"uint24"},{"indexed":false,"internalType":"address","name":"bidder","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Won","type":"event"},{"inputs":[{"internalType":"address","name":"updater","type":"address"}],"name":"addSharesUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"auctionConfig","outputs":[{"components":[{"internalType":"address","name":"auctionedNft","type":"address"},{"internalType":"uint8","name":"lines","type":"uint8"},{"internalType":"uint32","name":"baseDuration","type":"uint32"},{"internalType":"uint32","name":"timeBuffer","type":"uint32"},{"internalType":"uint96","name":"startingPrice","type":"uint96"},{"internalType":"uint96","name":"bidIncrement","type":"uint96"}],"internalType":"struct AuctionConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint24","name":"nftId","type":"uint24"}],"name":"createBid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getAndClearSharesFor","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAuctionedToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getIdsToAuction","outputs":[{"internalType":"uint24[]","name":"","type":"uint24[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"updater","type":"address"}],"name":"getIsSharesUpdater","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint24","name":"tokenId","type":"uint24"}],"name":"getMinPriceFor","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getTokenShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nftToAuction","type":"address"},{"internalType":"uint8","name":"lines","type":"uint8"},{"internalType":"uint32","name":"baseDuration","type":"uint32"},{"internalType":"uint32","name":"timeBuffer","type":"uint32"},{"internalType":"uint96","name":"startingPrice","type":"uint96"},{"internalType":"uint96","name":"bidIncrement","type":"uint96"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"id","type":"uint24"}],"name":"isVipId","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint24","name":"tokenId","type":"uint24"}],"name":"lineState","outputs":[{"components":[{"internalType":"uint24","name":"head","type":"uint24"},{"internalType":"uint40","name":"startTime","type":"uint40"},{"internalType":"uint40","name":"endTime","type":"uint40"},{"internalType":"address","name":"currentWinner","type":"address"},{"internalType":"uint96","name":"currentPrice","type":"uint96"}],"internalType":"struct LineState","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lineStates","outputs":[{"components":[{"internalType":"uint24","name":"head","type":"uint24"},{"internalType":"uint40","name":"startTime","type":"uint40"},{"internalType":"uint40","name":"endTime","type":"uint40"},{"internalType":"address","name":"currentWinner","type":"address"},{"internalType":"uint96","name":"currentPrice","type":"uint96"}],"internalType":"struct LineState[]","name":"lines","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockBaseDurationForever","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockBidIncrementForever","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockSharesUpdaterUpdatingForever","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockStartingPriceForever","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockTimeBufferForever","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockTokensRequiredToHoldToBeVipForever","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockVipIdsForever","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"options","outputs":[{"internalType":"bool","name":"sharesUpdaterUpdatingLocked","type":"bool"},{"internalType":"bool","name":"vipRequiredTokensLocked","type":"bool"},{"internalType":"bool","name":"vipIdsLocked","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"updater","type":"address"}],"name":"removeSharesUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"baseDuration","type":"uint32"}],"name":"setBaseDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"bidIncrement","type":"uint96"}],"name":"setBidIncrement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"startingPrice","type":"uint96"}],"name":"setStartingPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"timeBuffer","type":"uint32"}],"name":"setTimeBuffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"setTokensRequiredToHoldToBeVip","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24[]","name":"ids","type":"uint24[]"},{"internalType":"bool","name":"areVip","type":"bool"}],"name":"setVipIds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"nftId","type":"uint24"}],"name":"settleAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"tokenId","type":"uint24"}],"name":"tokenIdToLineNumber","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokensRequiredToOwnToBeVip","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"userIsVip","outputs":[{"internalType":"bool","name":"itIs","type":"bool"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b5062000032620000266200003860201b60201c565b6200004060201b60201c565b62000104565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b613d9d80620001146000396000f3fe6080604052600436106102045760003560e01c8063a11e8c8411610118578063d168aa85116100a0578063e0b55e561161006f578063e0b55e56146106f8578063e99ce4c51461070f578063ea45977c1461073a578063eb4c3f2c14610763578063f2fde38b146107a057610204565b8063d168aa8514610652578063d3befb9e1461067b578063d6b7e10214610692578063de9c9879146106cf57610204565b8063bff1be17116100e7578063bff1be171461055b578063c0e7af6914610586578063c99537b0146105af578063d0b6baf2146105ec578063d0f1828d1461061557610204565b8063a11e8c84146104b3578063ad1c9ac7146104dc578063b85372a4146104f3578063bb4061351461053057610204565b8063715018a61161019b5780638da5cb5b1161016a5780638da5cb5b146103ce578063937ec3ba146103f95780639a04c295146104365780639e2c98cd1461045f5780639f7195891461049c57610204565b8063715018a61461033a5780637422e05e146103515780638003ffa61461037a57806383c3bb231461039157610204565b806332d5ea02116101d757806332d5ea02146102c75780634013ce1a146102e35780634870d8ce146102fa578063542a53151461031157610204565b8063063e26ba14610209578063087dd350146102345780631069143a1461025d57806329566a041461028a575b600080fd5b34801561021557600080fd5b5061021e6107c9565b60405161022b9190612ccf565b60405180910390f35b34801561024057600080fd5b5061025b60048036038101906102569190612d3a565b6107f6565b005b34801561026957600080fd5b5061027261086f565b60405161028193929190612d82565b60405180910390f35b34801561029657600080fd5b506102b160048036038101906102ac9190612de5565b6108ae565b6040516102be9190612e2b565b60405180910390f35b6102e160048036038101906102dc9190612e81565b6108f7565b005b3480156102ef57600080fd5b506102f86109cd565b005b34801561030657600080fd5b5061030f6109f5565b005b34801561031d57600080fd5b5061033860048036038101906103339190612ef2565b610a1d565b005b34801561034657600080fd5b5061034f610aa5565b005b34801561035d57600080fd5b5061037860048036038101906103739190612de5565b610ab9565b005b34801561038657600080fd5b5061038f610b66565b005b34801561039d57600080fd5b506103b860048036038101906103b39190612e81565b610b8e565b6040516103c59190612fd4565b60405180910390f35b3480156103da57600080fd5b506103e3610ba6565b6040516103f09190612ccf565b60405180910390f35b34801561040557600080fd5b50610420600480360381019061041b9190612de5565b610bcf565b60405161042d9190612fef565b60405180910390f35b34801561044257600080fd5b5061045d60048036038101906104589190612ef2565b610c25565b005b34801561046b57600080fd5b5061048660048036038101906104819190612de5565b610cad565b6040516104939190612e2b565b60405180910390f35b3480156104a857600080fd5b506104b1610d8f565b005b3480156104bf57600080fd5b506104da60048036038101906104d59190612de5565b610db7565b005b3480156104e857600080fd5b506104f1610e64565b005b3480156104ff57600080fd5b5061051a60048036038101906105159190613036565b610e8c565b6040516105279190612ccf565b60405180910390f35b34801561053c57600080fd5b50610545610ecb565b6040516105529190613109565b60405180910390f35b34801561056757600080fd5b50610570611020565b60405161057d91906131d3565b60405180910390f35b34801561059257600080fd5b506105ad60048036038101906105a89190612d3a565b611295565b005b3480156105bb57600080fd5b506105d660048036038101906105d19190612e81565b61130e565b6040516105e39190612fef565b60405180910390f35b3480156105f857600080fd5b50610613600480360381019061060e9190612e81565b611342565b005b34801561062157600080fd5b5061063c60048036038101906106379190612e81565b611606565b6040516106499190613204565b60405180910390f35b34801561065e57600080fd5b506106796004803603810190610674919061324b565b6117cc565b005b34801561068757600080fd5b50610690611942565b005b34801561069e57600080fd5b506106b960048036038101906106b49190612e81565b61196a565b6040516106c691906132e7565b60405180910390f35b3480156106db57600080fd5b506106f660048036038101906106f1919061345b565b6119ab565b005b34801561070457600080fd5b5061070d611a17565b005b34801561071b57600080fd5b50610724611a3f565b60405161073191906135bb565b60405180910390f35b34801561074657600080fd5b50610761600480360381019061075c91906136cc565b611b1f565b005b34801561076f57600080fd5b5061078a60048036038101906107859190612de5565b611be4565b6040516107979190612fef565b60405180910390f35b3480156107ac57600080fd5b506107c760048036038101906107c29190612de5565b611cdd565b005b6000600160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6107fe611d60565b600360000160029054906101000a900460ff1615610848576040517f9ec38b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600160000160196101000a81548163ffffffff021916908363ffffffff16021790555050565b60098060000160009054906101000a900460ff16908060000160019054906101000a900460ff16908060000160029054906101000a900460ff16905083565b6000600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600760008262ffffff1662ffffff16815260200190815260200160002060009054906101000a900460ff168015610934575061093233611be4565b155b1561096b576040517f3e5bb0c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61097481611dde565b34600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546109c39190613757565b9250508190555050565b6109d5611d60565b6001600360000160026101000a81548160ff021916908315150217905550565b6109fd611d60565b6001600960000160016101000a81548160ff021916908315150217905550565b610a25611d60565b600360000160049054906101000a900460ff1615610a6f576040517f9ec38b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060018001600c6101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555050565b610aad611d60565b610ab760006124ae565b565b610ac1611d60565b600960000160009054906101000a900460ff1615610b0b576040517f9ec38b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b610b6e611d60565b6001600360000160046101000a81548160ff021916908315150217905550565b610b96612b0a565b610b9f82612572565b9050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b610c2d611d60565b600360000160039054906101000a900460ff1615610c77576040517f9ec38b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001800160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555050565b6000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610d0557600080fd5b600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009055919050565b610d97611d60565b6001600360000160036101000a81548160ff021916908315150217905550565b610dbf611d60565b600960000160009054906101000a900460ff1615610e09576040517f9ec38b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b610e6c611d60565b6001600960000160006101000a81548160ff021916908315150217905550565b60088181548110610e9c57600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610ed3612b70565b60016040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900460ff1660ff1660ff1681526020016000820160159054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160199054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016001820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160018201600c9054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff1681525050905090565b60606000600160000160149054906101000a900460ff1660ff1667ffffffffffffffff81111561105357611052613318565b5b6040519080825280602002602001820160405280156110815781602001602082028036833780820191505090505b50905060005b600160000160149054906101000a900460ff1660ff168160ff16101561128d576000600460006001846110ba919061378b565b60ff1660ff1681526020019081526020016000206040518060a00160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016000820160089054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff1681525050905060008160000151905060008162ffffff160361121157600183611207919061378b565b60ff169050611249565b816040015164ffffffffff1642111561124857600160000160149054906101000a900460ff1660ff168161124591906137c0565b90505b5b80848460ff16815181106112605761125f6137f7565b5b602002602001019062ffffff16908162ffffff16815250505050808061128590613826565b915050611087565b508091505090565b61129d611d60565b600360000160019054906101000a900460ff16156112e7576040517f9ec38b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600160000160156101000a81548163ffffffff021916908363ffffffff16021790555050565b6000600760008362ffffff1662ffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000600460006113518461196a565b60ff1660ff1681526020019081526020016000206040518060a00160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016000820160089054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090506000600160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816040015164ffffffffff1642116114f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e9906138ac565b60405180910390fd5b6000826000015162ffffff160361153e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161153590613918565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166354e4a80d846040518263ffffffff1660e01b81526004016115779190613947565b602060405180830381865afa158015611594573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b89190613977565b156115f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ef906139f0565b60405180910390fd5b611601826127de565b505050565b600080600160000160149054906101000a900460ff1660ff168361162a9190613a3f565b90506000600460008360ff1660ff1681526020019081526020016000206040518060a00160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016000820160089054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050806040015164ffffffffff16421115611796576001800160009054906101000a90046bffffffffffffffffffffffff16925050506117c7565b60018001600c9054906101000a90046bffffffffffffffffffffffff1681608001516117c29190613a70565b925050505b919050565b6117d4611d60565b600360000160009054906101000a900460ff16156117f157600080fd5b6001600360000160006101000a81548160ff0219169083151502179055506000816bffffffffffffffffffffffff161161182a57600080fd5b85600160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084600160000160146101000a81548160ff021916908360ff16021790555083600160000160156101000a81548163ffffffff021916908363ffffffff16021790555082600160000160196101000a81548163ffffffff021916908363ffffffff160217905550816001800160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508060018001600c6101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505050505050565b61194a611d60565b6001600360000160016101000a81548160ff021916908315150217905550565b600060018060000160149054906101000a900460ff1660ff166001846119909190613ab0565b61199a9190613a3f565b6119a4919061378b565b9050919050565b6119b3611d60565b600960000160019054906101000a900460ff16156119fd576040517f9ec38b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060089080519060200190611a13929190612be7565b5050565b611a1f611d60565b6001600960000160026101000a81548160ff021916908315150217905550565b6060600160000160149054906101000a900460ff1660ff1667ffffffffffffffff811115611a7057611a6f613318565b5b604051908082528060200260200182016040528015611aa957816020015b611a96612b0a565b815260200190600190039081611a8e5790505b50905060005b600160000160149054906101000a900460ff1660ff168160ff161015611b1b57611ae7600182611adf919061378b565b60ff16612572565b828260ff1681518110611afd57611afc6137f7565b5b60200260200101819052508080611b1390613826565b915050611aaf565b5090565b611b27611d60565b600960000160029054906101000a900460ff1615611b71576040517f9ec38b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611bdf578160076000858481518110611b9557611b946137f7565b5b602002602001015162ffffff1662ffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611bd790613ae7565b915050611b74565b505050565b600080600090505b600880549050811015611cd657600060088281548110611c0f57611c0e6137f7565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b8152600401611c729190612ccf565b602060405180830381865afa158015611c8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb39190613b44565b1115611cc3576001915050611cd8565b8080611cce90613ae7565b915050611bec565b505b919050565b611ce5611d60565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611d54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d4b90613be3565b60405180910390fd5b611d5d816124ae565b50565b611d68612925565b73ffffffffffffffffffffffffffffffffffffffff16611d86610ba6565b73ffffffffffffffffffffffffffffffffffffffff1614611ddc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dd390613c4f565b60405180910390fd5b565b6000611de98261196a565b90506000600460008360ff1660ff16815260200190815260200160002090506000600160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663aa271e1a306040518263ffffffff1660e01b8152600401611e6b9190612ccf565b602060405180830381865afa158015611e88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eac9190613977565b611ee2576040517f749d6d7900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160000160089054906101000a900464ffffffffff1664ffffffffff164211156120e6578073ffffffffffffffffffffffffffffffffffffffff166354e4a80d8360000160009054906101000a900462ffffff166040518263ffffffff1660e01b8152600401611f529190613947565b602060405180830381865afa158015611f6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f939190613977565b158015611fb8575060008260000160009054906101000a900462ffffff1662ffffff16115b156120db576120da826040518060a00160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016000820160089054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250506127de565b5b6120e5828461292d565b5b8362ffffff168260000160009054906101000a900462ffffff1662ffffff1614158061218957508073ffffffffffffffffffffffffffffffffffffffff1663d5abeb016040518163ffffffff1660e01b8152600401602060405180830381865afa158015612158573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217c9190613c84565b62ffffff168462ffffff16115b156121c0576040517f749aeece00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008073ffffffffffffffffffffffffffffffffffffffff168360010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141590508015801561224f5750346001800160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff16115b806122b357508080156122b257503460018001600c9054906101000a90046bffffffffffffffffffffffff168460010160149054906101000a90046bffffffffffffffffffffffff166122a29190613a70565b6bffffffffffffffffffffffff16115b5b156122ea576040517f69444a5400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008360010160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff1614612375576123748360010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168460010160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff16612ab6565b5b348360010160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550338360010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508462ffffff167f1822fdccb79ce001e8d0adbd19a40933da7b1c48c9723b9fff4235c7575ecf333334604051612422929190613cb1565b60405180910390a26000600160000160199054906101000a900463ffffffff1663ffffffff16426124539190613757565b90508360000160089054906101000a900464ffffffffff1664ffffffffff168164ffffffffff1611156124a657808460000160086101000a81548164ffffffffff021916908364ffffffffff1602179055505b505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61257a612b0a565b60006125858361196a565b9050600460008260ff1660ff1681526020019081526020016000206040518060a00160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016000820160089054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509150816040015164ffffffffff164211156127d8576000826000015162ffffff16146126f257600160000160149054906101000a900460ff166126f4565b805b60ff168260000181815161270891906137c0565b91509062ffffff16908162ffffff168152505042826020019064ffffffffff16908164ffffffffff1681525050600160000160159054906101000a900463ffffffff1663ffffffff164261275c9190613757565b826040019064ffffffffff16908164ffffffffff16815250506000826060019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600082608001906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff16815250505b50919050565b806000015162ffffff167f49bf5fcb911de2b0d2dbd50851c65a4a5eed15363cd7140030787ecbf9289c5582606001518360800151604051612821929190613d15565b60405180910390a26000600160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff16639d7282e2836000015184606001516040518363ffffffff1660e01b8152600401612896929190613d3e565b600060405180830381600087803b1580156128b057600080fd5b505af11580156128c4573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff166108fc83608001516bffffffffffffffffffffffff169081150290604051600060405180830381858888f19350505050158015612920573d6000803e3d6000fd5b505050565b600033905090565b428260000160036101000a81548164ffffffffff021916908364ffffffffff160217905550600160000160159054906101000a900463ffffffff1663ffffffff16426129799190613757565b8260000160086101000a81548164ffffffffff021916908364ffffffffff16021790555060008260000160009054906101000a900462ffffff1662ffffff16036129e6578060ff168260000160006101000a81548162ffffff021916908362ffffff160217905550612ab2565b600160000160149054906101000a900460ff1660ff168260000160008282829054906101000a900462ffffff16612a1d91906137c0565b92506101000a81548162ffffff021916908362ffffff16021790555060008260010160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555060008260010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5050565b80471015612acc5763b12d13eb6000526004601cfd5b6000806000808486620186a0f1612b0657816000526073600b5360ff6020536016600b82f0612b0557620f42405a11612b0457600080fd5b5b5b5050565b6040518060a00160405280600062ffffff168152602001600064ffffffffff168152602001600064ffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff1681525090565b6040518060c00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600060ff168152602001600063ffffffff168152602001600063ffffffff16815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff1681525090565b828054828255906000526020600020908101928215612c60579160200282015b82811115612c5f5782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555091602001919060010190612c07565b5b509050612c6d9190612c71565b5090565b5b80821115612c8a576000816000905550600101612c72565b5090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612cb982612c8e565b9050919050565b612cc981612cae565b82525050565b6000602082019050612ce46000830184612cc0565b92915050565b6000604051905090565b600080fd5b600080fd5b600063ffffffff82169050919050565b612d1781612cfe565b8114612d2257600080fd5b50565b600081359050612d3481612d0e565b92915050565b600060208284031215612d5057612d4f612cf4565b5b6000612d5e84828501612d25565b91505092915050565b60008115159050919050565b612d7c81612d67565b82525050565b6000606082019050612d976000830186612d73565b612da46020830185612d73565b612db16040830184612d73565b949350505050565b612dc281612cae565b8114612dcd57600080fd5b50565b600081359050612ddf81612db9565b92915050565b600060208284031215612dfb57612dfa612cf4565b5b6000612e0984828501612dd0565b91505092915050565b6000819050919050565b612e2581612e12565b82525050565b6000602082019050612e406000830184612e1c565b92915050565b600062ffffff82169050919050565b612e5e81612e46565b8114612e6957600080fd5b50565b600081359050612e7b81612e55565b92915050565b600060208284031215612e9757612e96612cf4565b5b6000612ea584828501612e6c565b91505092915050565b60006bffffffffffffffffffffffff82169050919050565b612ecf81612eae565b8114612eda57600080fd5b50565b600081359050612eec81612ec6565b92915050565b600060208284031215612f0857612f07612cf4565b5b6000612f1684828501612edd565b91505092915050565b612f2881612e46565b82525050565b600064ffffffffff82169050919050565b612f4881612f2e565b82525050565b612f5781612cae565b82525050565b612f6681612eae565b82525050565b60a082016000820151612f826000850182612f1f565b506020820151612f956020850182612f3f565b506040820151612fa86040850182612f3f565b506060820151612fbb6060850182612f4e565b506080820151612fce6080850182612f5d565b50505050565b600060a082019050612fe96000830184612f6c565b92915050565b60006020820190506130046000830184612d73565b92915050565b61301381612e12565b811461301e57600080fd5b50565b6000813590506130308161300a565b92915050565b60006020828403121561304c5761304b612cf4565b5b600061305a84828501613021565b91505092915050565b600060ff82169050919050565b61307981613063565b82525050565b61308881612cfe565b82525050565b60c0820160008201516130a46000850182612f4e565b5060208201516130b76020850182613070565b5060408201516130ca604085018261307f565b5060608201516130dd606085018261307f565b5060808201516130f06080850182612f5d565b5060a082015161310360a0850182612f5d565b50505050565b600060c08201905061311e600083018461308e565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600061315c8383612f1f565b60208301905092915050565b6000602082019050919050565b600061318082613124565b61318a818561312f565b935061319583613140565b8060005b838110156131c65781516131ad8882613150565b97506131b883613168565b925050600181019050613199565b5085935050505092915050565b600060208201905081810360008301526131ed8184613175565b905092915050565b6131fe81612eae565b82525050565b600060208201905061321960008301846131f5565b92915050565b61322881613063565b811461323357600080fd5b50565b6000813590506132458161321f565b92915050565b60008060008060008060c0878903121561326857613267612cf4565b5b600061327689828a01612dd0565b965050602061328789828a01613236565b955050604061329889828a01612d25565b94505060606132a989828a01612d25565b93505060806132ba89828a01612edd565b92505060a06132cb89828a01612edd565b9150509295509295509295565b6132e181613063565b82525050565b60006020820190506132fc60008301846132d8565b92915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61335082613307565b810181811067ffffffffffffffff8211171561336f5761336e613318565b5b80604052505050565b6000613382612cea565b905061338e8282613347565b919050565b600067ffffffffffffffff8211156133ae576133ad613318565b5b602082029050602081019050919050565b600080fd5b60006133d76133d284613393565b613378565b905080838252602082019050602084028301858111156133fa576133f96133bf565b5b835b81811015613423578061340f8882612dd0565b8452602084019350506020810190506133fc565b5050509392505050565b600082601f83011261344257613441613302565b5b81356134528482602086016133c4565b91505092915050565b60006020828403121561347157613470612cf4565b5b600082013567ffffffffffffffff81111561348f5761348e612cf9565b5b61349b8482850161342d565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60a0820160008201516134e66000850182612f1f565b5060208201516134f96020850182612f3f565b50604082015161350c6040850182612f3f565b50606082015161351f6060850182612f4e565b5060808201516135326080850182612f5d565b50505050565b600061354483836134d0565b60a08301905092915050565b6000602082019050919050565b6000613568826134a4565b61357281856134af565b935061357d836134c0565b8060005b838110156135ae5781516135958882613538565b97506135a083613550565b925050600181019050613581565b5085935050505092915050565b600060208201905081810360008301526135d5818461355d565b905092915050565b600067ffffffffffffffff8211156135f8576135f7613318565b5b602082029050602081019050919050565b600061361c613617846135dd565b613378565b9050808382526020820190506020840283018581111561363f5761363e6133bf565b5b835b8181101561366857806136548882612e6c565b845260208401935050602081019050613641565b5050509392505050565b600082601f83011261368757613686613302565b5b8135613697848260208601613609565b91505092915050565b6136a981612d67565b81146136b457600080fd5b50565b6000813590506136c6816136a0565b92915050565b600080604083850312156136e3576136e2612cf4565b5b600083013567ffffffffffffffff81111561370157613700612cf9565b5b61370d85828601613672565b925050602061371e858286016136b7565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061376282612e12565b915061376d83612e12565b925082820190508082111561378557613784613728565b5b92915050565b600061379682613063565b91506137a183613063565b9250828201905060ff8111156137ba576137b9613728565b5b92915050565b60006137cb82612e46565b91506137d683612e46565b9250828201905062ffffff8111156137f1576137f0613728565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061383182613063565b915060ff820361384457613843613728565b5b600182019050919050565b600082825260208201905092915050565b7f41756374696f6e207374696c6c206f6e676f696e672e00000000000000000000600082015250565b600061389660168361384f565b91506138a182613860565b602082019050919050565b600060208201905081810360008301526138c581613889565b9050919050565b7f41756374696f6e206e6f7420737461727465642e000000000000000000000000600082015250565b600061390260148361384f565b915061390d826138cc565b602082019050919050565b60006020820190508181036000830152613931816138f5565b9050919050565b61394181612e46565b82525050565b600060208201905061395c6000830184613938565b92915050565b600081519050613971816136a0565b92915050565b60006020828403121561398d5761398c612cf4565b5b600061399b84828501613962565b91505092915050565b7f546f6b656e20616c726561647920736574746c65642e00000000000000000000600082015250565b60006139da60168361384f565b91506139e5826139a4565b602082019050919050565b60006020820190508181036000830152613a09816139cd565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613a4a82612e46565b9150613a5583612e46565b925082613a6557613a64613a10565b5b828206905092915050565b6000613a7b82612eae565b9150613a8683612eae565b925082820190506bffffffffffffffffffffffff811115613aaa57613aa9613728565b5b92915050565b6000613abb82612e46565b9150613ac683612e46565b9250828203905062ffffff811115613ae157613ae0613728565b5b92915050565b6000613af282612e12565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613b2457613b23613728565b5b600182019050919050565b600081519050613b3e8161300a565b92915050565b600060208284031215613b5a57613b59612cf4565b5b6000613b6884828501613b2f565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613bcd60268361384f565b9150613bd882613b71565b604082019050919050565b60006020820190508181036000830152613bfc81613bc0565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613c3960208361384f565b9150613c4482613c03565b602082019050919050565b60006020820190508181036000830152613c6881613c2c565b9050919050565b600081519050613c7e81612e55565b92915050565b600060208284031215613c9a57613c99612cf4565b5b6000613ca884828501613c6f565b91505092915050565b6000604082019050613cc66000830185612cc0565b613cd36020830184612e1c565b9392505050565b6000819050919050565b6000613cff613cfa613cf584612eae565b613cda565b612e12565b9050919050565b613d0f81613ce4565b82525050565b6000604082019050613d2a6000830185612cc0565b613d376020830184613d06565b9392505050565b6000604082019050613d536000830185613938565b613d606020830184612cc0565b939250505056fea264697066735822122046bd576990ab2c4498681d66c88f348a1c09dd6c0fa6b2aead65058c644dad2c64736f6c63430008120033

Deployed Bytecode

0x6080604052600436106102045760003560e01c8063a11e8c8411610118578063d168aa85116100a0578063e0b55e561161006f578063e0b55e56146106f8578063e99ce4c51461070f578063ea45977c1461073a578063eb4c3f2c14610763578063f2fde38b146107a057610204565b8063d168aa8514610652578063d3befb9e1461067b578063d6b7e10214610692578063de9c9879146106cf57610204565b8063bff1be17116100e7578063bff1be171461055b578063c0e7af6914610586578063c99537b0146105af578063d0b6baf2146105ec578063d0f1828d1461061557610204565b8063a11e8c84146104b3578063ad1c9ac7146104dc578063b85372a4146104f3578063bb4061351461053057610204565b8063715018a61161019b5780638da5cb5b1161016a5780638da5cb5b146103ce578063937ec3ba146103f95780639a04c295146104365780639e2c98cd1461045f5780639f7195891461049c57610204565b8063715018a61461033a5780637422e05e146103515780638003ffa61461037a57806383c3bb231461039157610204565b806332d5ea02116101d757806332d5ea02146102c75780634013ce1a146102e35780634870d8ce146102fa578063542a53151461031157610204565b8063063e26ba14610209578063087dd350146102345780631069143a1461025d57806329566a041461028a575b600080fd5b34801561021557600080fd5b5061021e6107c9565b60405161022b9190612ccf565b60405180910390f35b34801561024057600080fd5b5061025b60048036038101906102569190612d3a565b6107f6565b005b34801561026957600080fd5b5061027261086f565b60405161028193929190612d82565b60405180910390f35b34801561029657600080fd5b506102b160048036038101906102ac9190612de5565b6108ae565b6040516102be9190612e2b565b60405180910390f35b6102e160048036038101906102dc9190612e81565b6108f7565b005b3480156102ef57600080fd5b506102f86109cd565b005b34801561030657600080fd5b5061030f6109f5565b005b34801561031d57600080fd5b5061033860048036038101906103339190612ef2565b610a1d565b005b34801561034657600080fd5b5061034f610aa5565b005b34801561035d57600080fd5b5061037860048036038101906103739190612de5565b610ab9565b005b34801561038657600080fd5b5061038f610b66565b005b34801561039d57600080fd5b506103b860048036038101906103b39190612e81565b610b8e565b6040516103c59190612fd4565b60405180910390f35b3480156103da57600080fd5b506103e3610ba6565b6040516103f09190612ccf565b60405180910390f35b34801561040557600080fd5b50610420600480360381019061041b9190612de5565b610bcf565b60405161042d9190612fef565b60405180910390f35b34801561044257600080fd5b5061045d60048036038101906104589190612ef2565b610c25565b005b34801561046b57600080fd5b5061048660048036038101906104819190612de5565b610cad565b6040516104939190612e2b565b60405180910390f35b3480156104a857600080fd5b506104b1610d8f565b005b3480156104bf57600080fd5b506104da60048036038101906104d59190612de5565b610db7565b005b3480156104e857600080fd5b506104f1610e64565b005b3480156104ff57600080fd5b5061051a60048036038101906105159190613036565b610e8c565b6040516105279190612ccf565b60405180910390f35b34801561053c57600080fd5b50610545610ecb565b6040516105529190613109565b60405180910390f35b34801561056757600080fd5b50610570611020565b60405161057d91906131d3565b60405180910390f35b34801561059257600080fd5b506105ad60048036038101906105a89190612d3a565b611295565b005b3480156105bb57600080fd5b506105d660048036038101906105d19190612e81565b61130e565b6040516105e39190612fef565b60405180910390f35b3480156105f857600080fd5b50610613600480360381019061060e9190612e81565b611342565b005b34801561062157600080fd5b5061063c60048036038101906106379190612e81565b611606565b6040516106499190613204565b60405180910390f35b34801561065e57600080fd5b506106796004803603810190610674919061324b565b6117cc565b005b34801561068757600080fd5b50610690611942565b005b34801561069e57600080fd5b506106b960048036038101906106b49190612e81565b61196a565b6040516106c691906132e7565b60405180910390f35b3480156106db57600080fd5b506106f660048036038101906106f1919061345b565b6119ab565b005b34801561070457600080fd5b5061070d611a17565b005b34801561071b57600080fd5b50610724611a3f565b60405161073191906135bb565b60405180910390f35b34801561074657600080fd5b50610761600480360381019061075c91906136cc565b611b1f565b005b34801561076f57600080fd5b5061078a60048036038101906107859190612de5565b611be4565b6040516107979190612fef565b60405180910390f35b3480156107ac57600080fd5b506107c760048036038101906107c29190612de5565b611cdd565b005b6000600160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6107fe611d60565b600360000160029054906101000a900460ff1615610848576040517f9ec38b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600160000160196101000a81548163ffffffff021916908363ffffffff16021790555050565b60098060000160009054906101000a900460ff16908060000160019054906101000a900460ff16908060000160029054906101000a900460ff16905083565b6000600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600760008262ffffff1662ffffff16815260200190815260200160002060009054906101000a900460ff168015610934575061093233611be4565b155b1561096b576040517f3e5bb0c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61097481611dde565b34600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546109c39190613757565b9250508190555050565b6109d5611d60565b6001600360000160026101000a81548160ff021916908315150217905550565b6109fd611d60565b6001600960000160016101000a81548160ff021916908315150217905550565b610a25611d60565b600360000160049054906101000a900460ff1615610a6f576040517f9ec38b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060018001600c6101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555050565b610aad611d60565b610ab760006124ae565b565b610ac1611d60565b600960000160009054906101000a900460ff1615610b0b576040517f9ec38b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b610b6e611d60565b6001600360000160046101000a81548160ff021916908315150217905550565b610b96612b0a565b610b9f82612572565b9050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b610c2d611d60565b600360000160039054906101000a900460ff1615610c77576040517f9ec38b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001800160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555050565b6000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610d0557600080fd5b600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009055919050565b610d97611d60565b6001600360000160036101000a81548160ff021916908315150217905550565b610dbf611d60565b600960000160009054906101000a900460ff1615610e09576040517f9ec38b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b610e6c611d60565b6001600960000160006101000a81548160ff021916908315150217905550565b60088181548110610e9c57600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610ed3612b70565b60016040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900460ff1660ff1660ff1681526020016000820160159054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160199054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016001820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160018201600c9054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff1681525050905090565b60606000600160000160149054906101000a900460ff1660ff1667ffffffffffffffff81111561105357611052613318565b5b6040519080825280602002602001820160405280156110815781602001602082028036833780820191505090505b50905060005b600160000160149054906101000a900460ff1660ff168160ff16101561128d576000600460006001846110ba919061378b565b60ff1660ff1681526020019081526020016000206040518060a00160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016000820160089054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff1681525050905060008160000151905060008162ffffff160361121157600183611207919061378b565b60ff169050611249565b816040015164ffffffffff1642111561124857600160000160149054906101000a900460ff1660ff168161124591906137c0565b90505b5b80848460ff16815181106112605761125f6137f7565b5b602002602001019062ffffff16908162ffffff16815250505050808061128590613826565b915050611087565b508091505090565b61129d611d60565b600360000160019054906101000a900460ff16156112e7576040517f9ec38b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600160000160156101000a81548163ffffffff021916908363ffffffff16021790555050565b6000600760008362ffffff1662ffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000600460006113518461196a565b60ff1660ff1681526020019081526020016000206040518060a00160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016000820160089054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090506000600160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816040015164ffffffffff1642116114f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e9906138ac565b60405180910390fd5b6000826000015162ffffff160361153e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161153590613918565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166354e4a80d846040518263ffffffff1660e01b81526004016115779190613947565b602060405180830381865afa158015611594573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b89190613977565b156115f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ef906139f0565b60405180910390fd5b611601826127de565b505050565b600080600160000160149054906101000a900460ff1660ff168361162a9190613a3f565b90506000600460008360ff1660ff1681526020019081526020016000206040518060a00160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016000820160089054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050806040015164ffffffffff16421115611796576001800160009054906101000a90046bffffffffffffffffffffffff16925050506117c7565b60018001600c9054906101000a90046bffffffffffffffffffffffff1681608001516117c29190613a70565b925050505b919050565b6117d4611d60565b600360000160009054906101000a900460ff16156117f157600080fd5b6001600360000160006101000a81548160ff0219169083151502179055506000816bffffffffffffffffffffffff161161182a57600080fd5b85600160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084600160000160146101000a81548160ff021916908360ff16021790555083600160000160156101000a81548163ffffffff021916908363ffffffff16021790555082600160000160196101000a81548163ffffffff021916908363ffffffff160217905550816001800160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508060018001600c6101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505050505050565b61194a611d60565b6001600360000160016101000a81548160ff021916908315150217905550565b600060018060000160149054906101000a900460ff1660ff166001846119909190613ab0565b61199a9190613a3f565b6119a4919061378b565b9050919050565b6119b3611d60565b600960000160019054906101000a900460ff16156119fd576040517f9ec38b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060089080519060200190611a13929190612be7565b5050565b611a1f611d60565b6001600960000160026101000a81548160ff021916908315150217905550565b6060600160000160149054906101000a900460ff1660ff1667ffffffffffffffff811115611a7057611a6f613318565b5b604051908082528060200260200182016040528015611aa957816020015b611a96612b0a565b815260200190600190039081611a8e5790505b50905060005b600160000160149054906101000a900460ff1660ff168160ff161015611b1b57611ae7600182611adf919061378b565b60ff16612572565b828260ff1681518110611afd57611afc6137f7565b5b60200260200101819052508080611b1390613826565b915050611aaf565b5090565b611b27611d60565b600960000160029054906101000a900460ff1615611b71576040517f9ec38b9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611bdf578160076000858481518110611b9557611b946137f7565b5b602002602001015162ffffff1662ffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611bd790613ae7565b915050611b74565b505050565b600080600090505b600880549050811015611cd657600060088281548110611c0f57611c0e6137f7565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b8152600401611c729190612ccf565b602060405180830381865afa158015611c8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb39190613b44565b1115611cc3576001915050611cd8565b8080611cce90613ae7565b915050611bec565b505b919050565b611ce5611d60565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611d54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d4b90613be3565b60405180910390fd5b611d5d816124ae565b50565b611d68612925565b73ffffffffffffffffffffffffffffffffffffffff16611d86610ba6565b73ffffffffffffffffffffffffffffffffffffffff1614611ddc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dd390613c4f565b60405180910390fd5b565b6000611de98261196a565b90506000600460008360ff1660ff16815260200190815260200160002090506000600160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663aa271e1a306040518263ffffffff1660e01b8152600401611e6b9190612ccf565b602060405180830381865afa158015611e88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eac9190613977565b611ee2576040517f749d6d7900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160000160089054906101000a900464ffffffffff1664ffffffffff164211156120e6578073ffffffffffffffffffffffffffffffffffffffff166354e4a80d8360000160009054906101000a900462ffffff166040518263ffffffff1660e01b8152600401611f529190613947565b602060405180830381865afa158015611f6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f939190613977565b158015611fb8575060008260000160009054906101000a900462ffffff1662ffffff16115b156120db576120da826040518060a00160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016000820160089054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250506127de565b5b6120e5828461292d565b5b8362ffffff168260000160009054906101000a900462ffffff1662ffffff1614158061218957508073ffffffffffffffffffffffffffffffffffffffff1663d5abeb016040518163ffffffff1660e01b8152600401602060405180830381865afa158015612158573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217c9190613c84565b62ffffff168462ffffff16115b156121c0576040517f749aeece00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008073ffffffffffffffffffffffffffffffffffffffff168360010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141590508015801561224f5750346001800160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff16115b806122b357508080156122b257503460018001600c9054906101000a90046bffffffffffffffffffffffff168460010160149054906101000a90046bffffffffffffffffffffffff166122a29190613a70565b6bffffffffffffffffffffffff16115b5b156122ea576040517f69444a5400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008360010160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff1614612375576123748360010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168460010160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff16612ab6565b5b348360010160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550338360010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508462ffffff167f1822fdccb79ce001e8d0adbd19a40933da7b1c48c9723b9fff4235c7575ecf333334604051612422929190613cb1565b60405180910390a26000600160000160199054906101000a900463ffffffff1663ffffffff16426124539190613757565b90508360000160089054906101000a900464ffffffffff1664ffffffffff168164ffffffffff1611156124a657808460000160086101000a81548164ffffffffff021916908364ffffffffff1602179055505b505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61257a612b0a565b60006125858361196a565b9050600460008260ff1660ff1681526020019081526020016000206040518060a00160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016000820160089054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509150816040015164ffffffffff164211156127d8576000826000015162ffffff16146126f257600160000160149054906101000a900460ff166126f4565b805b60ff168260000181815161270891906137c0565b91509062ffffff16908162ffffff168152505042826020019064ffffffffff16908164ffffffffff1681525050600160000160159054906101000a900463ffffffff1663ffffffff164261275c9190613757565b826040019064ffffffffff16908164ffffffffff16815250506000826060019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600082608001906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff16815250505b50919050565b806000015162ffffff167f49bf5fcb911de2b0d2dbd50851c65a4a5eed15363cd7140030787ecbf9289c5582606001518360800151604051612821929190613d15565b60405180910390a26000600160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff16639d7282e2836000015184606001516040518363ffffffff1660e01b8152600401612896929190613d3e565b600060405180830381600087803b1580156128b057600080fd5b505af11580156128c4573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff166108fc83608001516bffffffffffffffffffffffff169081150290604051600060405180830381858888f19350505050158015612920573d6000803e3d6000fd5b505050565b600033905090565b428260000160036101000a81548164ffffffffff021916908364ffffffffff160217905550600160000160159054906101000a900463ffffffff1663ffffffff16426129799190613757565b8260000160086101000a81548164ffffffffff021916908364ffffffffff16021790555060008260000160009054906101000a900462ffffff1662ffffff16036129e6578060ff168260000160006101000a81548162ffffff021916908362ffffff160217905550612ab2565b600160000160149054906101000a900460ff1660ff168260000160008282829054906101000a900462ffffff16612a1d91906137c0565b92506101000a81548162ffffff021916908362ffffff16021790555060008260010160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555060008260010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5050565b80471015612acc5763b12d13eb6000526004601cfd5b6000806000808486620186a0f1612b0657816000526073600b5360ff6020536016600b82f0612b0557620f42405a11612b0457600080fd5b5b5b5050565b6040518060a00160405280600062ffffff168152602001600064ffffffffff168152602001600064ffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff1681525090565b6040518060c00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600060ff168152602001600063ffffffff168152602001600063ffffffff16815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff1681525090565b828054828255906000526020600020908101928215612c60579160200282015b82811115612c5f5782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555091602001919060010190612c07565b5b509050612c6d9190612c71565b5090565b5b80821115612c8a576000816000905550600101612c72565b5090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612cb982612c8e565b9050919050565b612cc981612cae565b82525050565b6000602082019050612ce46000830184612cc0565b92915050565b6000604051905090565b600080fd5b600080fd5b600063ffffffff82169050919050565b612d1781612cfe565b8114612d2257600080fd5b50565b600081359050612d3481612d0e565b92915050565b600060208284031215612d5057612d4f612cf4565b5b6000612d5e84828501612d25565b91505092915050565b60008115159050919050565b612d7c81612d67565b82525050565b6000606082019050612d976000830186612d73565b612da46020830185612d73565b612db16040830184612d73565b949350505050565b612dc281612cae565b8114612dcd57600080fd5b50565b600081359050612ddf81612db9565b92915050565b600060208284031215612dfb57612dfa612cf4565b5b6000612e0984828501612dd0565b91505092915050565b6000819050919050565b612e2581612e12565b82525050565b6000602082019050612e406000830184612e1c565b92915050565b600062ffffff82169050919050565b612e5e81612e46565b8114612e6957600080fd5b50565b600081359050612e7b81612e55565b92915050565b600060208284031215612e9757612e96612cf4565b5b6000612ea584828501612e6c565b91505092915050565b60006bffffffffffffffffffffffff82169050919050565b612ecf81612eae565b8114612eda57600080fd5b50565b600081359050612eec81612ec6565b92915050565b600060208284031215612f0857612f07612cf4565b5b6000612f1684828501612edd565b91505092915050565b612f2881612e46565b82525050565b600064ffffffffff82169050919050565b612f4881612f2e565b82525050565b612f5781612cae565b82525050565b612f6681612eae565b82525050565b60a082016000820151612f826000850182612f1f565b506020820151612f956020850182612f3f565b506040820151612fa86040850182612f3f565b506060820151612fbb6060850182612f4e565b506080820151612fce6080850182612f5d565b50505050565b600060a082019050612fe96000830184612f6c565b92915050565b60006020820190506130046000830184612d73565b92915050565b61301381612e12565b811461301e57600080fd5b50565b6000813590506130308161300a565b92915050565b60006020828403121561304c5761304b612cf4565b5b600061305a84828501613021565b91505092915050565b600060ff82169050919050565b61307981613063565b82525050565b61308881612cfe565b82525050565b60c0820160008201516130a46000850182612f4e565b5060208201516130b76020850182613070565b5060408201516130ca604085018261307f565b5060608201516130dd606085018261307f565b5060808201516130f06080850182612f5d565b5060a082015161310360a0850182612f5d565b50505050565b600060c08201905061311e600083018461308e565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600061315c8383612f1f565b60208301905092915050565b6000602082019050919050565b600061318082613124565b61318a818561312f565b935061319583613140565b8060005b838110156131c65781516131ad8882613150565b97506131b883613168565b925050600181019050613199565b5085935050505092915050565b600060208201905081810360008301526131ed8184613175565b905092915050565b6131fe81612eae565b82525050565b600060208201905061321960008301846131f5565b92915050565b61322881613063565b811461323357600080fd5b50565b6000813590506132458161321f565b92915050565b60008060008060008060c0878903121561326857613267612cf4565b5b600061327689828a01612dd0565b965050602061328789828a01613236565b955050604061329889828a01612d25565b94505060606132a989828a01612d25565b93505060806132ba89828a01612edd565b92505060a06132cb89828a01612edd565b9150509295509295509295565b6132e181613063565b82525050565b60006020820190506132fc60008301846132d8565b92915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61335082613307565b810181811067ffffffffffffffff8211171561336f5761336e613318565b5b80604052505050565b6000613382612cea565b905061338e8282613347565b919050565b600067ffffffffffffffff8211156133ae576133ad613318565b5b602082029050602081019050919050565b600080fd5b60006133d76133d284613393565b613378565b905080838252602082019050602084028301858111156133fa576133f96133bf565b5b835b81811015613423578061340f8882612dd0565b8452602084019350506020810190506133fc565b5050509392505050565b600082601f83011261344257613441613302565b5b81356134528482602086016133c4565b91505092915050565b60006020828403121561347157613470612cf4565b5b600082013567ffffffffffffffff81111561348f5761348e612cf9565b5b61349b8482850161342d565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60a0820160008201516134e66000850182612f1f565b5060208201516134f96020850182612f3f565b50604082015161350c6040850182612f3f565b50606082015161351f6060850182612f4e565b5060808201516135326080850182612f5d565b50505050565b600061354483836134d0565b60a08301905092915050565b6000602082019050919050565b6000613568826134a4565b61357281856134af565b935061357d836134c0565b8060005b838110156135ae5781516135958882613538565b97506135a083613550565b925050600181019050613581565b5085935050505092915050565b600060208201905081810360008301526135d5818461355d565b905092915050565b600067ffffffffffffffff8211156135f8576135f7613318565b5b602082029050602081019050919050565b600061361c613617846135dd565b613378565b9050808382526020820190506020840283018581111561363f5761363e6133bf565b5b835b8181101561366857806136548882612e6c565b845260208401935050602081019050613641565b5050509392505050565b600082601f83011261368757613686613302565b5b8135613697848260208601613609565b91505092915050565b6136a981612d67565b81146136b457600080fd5b50565b6000813590506136c6816136a0565b92915050565b600080604083850312156136e3576136e2612cf4565b5b600083013567ffffffffffffffff81111561370157613700612cf9565b5b61370d85828601613672565b925050602061371e858286016136b7565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061376282612e12565b915061376d83612e12565b925082820190508082111561378557613784613728565b5b92915050565b600061379682613063565b91506137a183613063565b9250828201905060ff8111156137ba576137b9613728565b5b92915050565b60006137cb82612e46565b91506137d683612e46565b9250828201905062ffffff8111156137f1576137f0613728565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061383182613063565b915060ff820361384457613843613728565b5b600182019050919050565b600082825260208201905092915050565b7f41756374696f6e207374696c6c206f6e676f696e672e00000000000000000000600082015250565b600061389660168361384f565b91506138a182613860565b602082019050919050565b600060208201905081810360008301526138c581613889565b9050919050565b7f41756374696f6e206e6f7420737461727465642e000000000000000000000000600082015250565b600061390260148361384f565b915061390d826138cc565b602082019050919050565b60006020820190508181036000830152613931816138f5565b9050919050565b61394181612e46565b82525050565b600060208201905061395c6000830184613938565b92915050565b600081519050613971816136a0565b92915050565b60006020828403121561398d5761398c612cf4565b5b600061399b84828501613962565b91505092915050565b7f546f6b656e20616c726561647920736574746c65642e00000000000000000000600082015250565b60006139da60168361384f565b91506139e5826139a4565b602082019050919050565b60006020820190508181036000830152613a09816139cd565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613a4a82612e46565b9150613a5583612e46565b925082613a6557613a64613a10565b5b828206905092915050565b6000613a7b82612eae565b9150613a8683612eae565b925082820190506bffffffffffffffffffffffff811115613aaa57613aa9613728565b5b92915050565b6000613abb82612e46565b9150613ac683612e46565b9250828203905062ffffff811115613ae157613ae0613728565b5b92915050565b6000613af282612e12565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613b2457613b23613728565b5b600182019050919050565b600081519050613b3e8161300a565b92915050565b600060208284031215613b5a57613b59612cf4565b5b6000613b6884828501613b2f565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613bcd60268361384f565b9150613bd882613b71565b604082019050919050565b60006020820190508181036000830152613bfc81613bc0565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613c3960208361384f565b9150613c4482613c03565b602082019050919050565b60006020820190508181036000830152613c6881613c2c565b9050919050565b600081519050613c7e81612e55565b92915050565b600060208284031215613c9a57613c99612cf4565b5b6000613ca884828501613c6f565b91505092915050565b6000604082019050613cc66000830185612cc0565b613cd36020830184612e1c565b9392505050565b6000819050919050565b6000613cff613cfa613cf584612eae565b613cda565b612e12565b9050919050565b613d0f81613ce4565b82525050565b6000604082019050613d2a6000830185612cc0565b613d376020830184613d06565b9392505050565b6000604082019050613d536000830185613938565b613d606020830184612cc0565b939250505056fea264697066735822122046bd576990ab2c4498681d66c88f348a1c09dd6c0fa6b2aead65058c644dad2c64736f6c63430008120033

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.