Base Sepolia Testnet

Contract

0x925C42A57328FD8a7b07ecA444A34963e07C8999

Overview

ETH Balance

0.267973165563852716 ETH

Token Holdings

More Info

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Amount
Mint Tokens Same...341084392025-11-24 11:52:4615 days ago1763985166IN
0x925C42A5...3e07C8999
0.000055 ETH0.000000050.0012
Mint Tokens Same...341066792025-11-24 10:54:0615 days ago1763981646IN
0x925C42A5...3e07C8999
0.00001575 ETH0.000000050.0012
Mint Tokens Same...341066012025-11-24 10:51:3015 days ago1763981490IN
0x925C42A5...3e07C8999
0.00001218 ETH0.000000050.0012
Mint Tokens Same...341064332025-11-24 10:45:5415 days ago1763981154IN
0x925C42A5...3e07C8999
0.00001683 ETH0.000000050.0012
Mint Tokens Same...341063332025-11-24 10:42:3415 days ago1763980954IN
0x925C42A5...3e07C8999
0.000055 ETH0.000000170.0012
Mint Tokens Same...340761382025-11-23 17:56:0416 days ago1763920564IN
0x925C42A5...3e07C8999
0.00001507 ETH0.000000160.0012
Mint Tokens Same...340760452025-11-23 17:52:5816 days ago1763920378IN
0x925C42A5...3e07C8999
0.00001066 ETH0.000000110.0012
Mint Tokens Same...340759532025-11-23 17:49:5416 days ago1763920194IN
0x925C42A5...3e07C8999
0.00000847 ETH0.000000050.0012
Mint Tokens Same...340759362025-11-23 17:49:2016 days ago1763920160IN
0x925C42A5...3e07C8999
0.00000931 ETH0.000000050.0012
Mint Tokens Same...340757732025-11-23 17:43:5416 days ago1763919834IN
0x925C42A5...3e07C8999
0.00001562 ETH0.000000160.0012
Mint Tokens Same...340756742025-11-23 17:40:3616 days ago1763919636IN
0x925C42A5...3e07C8999
0.00001578 ETH0.000000150.0012
Mint Tokens Same...340755762025-11-23 17:37:2016 days ago1763919440IN
0x925C42A5...3e07C8999
0.00000866 ETH0.000000160.0012
Mint Tokens Same...340755722025-11-23 17:37:1216 days ago1763919432IN
0x925C42A5...3e07C8999
0.0000085 ETH0.000000050.0012
Mint Tokens Same...340753662025-11-23 17:30:2016 days ago1763919020IN
0x925C42A5...3e07C8999
0.00001562 ETH0.000000150.0012
Mint Tokens Same...340752442025-11-23 17:26:1616 days ago1763918776IN
0x925C42A5...3e07C8999
0.00002 ETH0.000000160.00120024
Mint Tokens Same...340752432025-11-23 17:26:1416 days ago1763918774IN
0x925C42A5...3e07C8999
0.00002 ETH0.000000150.00120143
Mint Tokens Same...340752102025-11-23 17:25:0816 days ago1763918708IN
0x925C42A5...3e07C8999
0.00002 ETH0.000000160.0012
Mint Tokens Same...340751822025-11-23 17:24:1216 days ago1763918652IN
0x925C42A5...3e07C8999
0.00002 ETH0.000000150.0012
Mint Tokens Same...340751642025-11-23 17:23:3616 days ago1763918616IN
0x925C42A5...3e07C8999
0.00005 ETH0.000000170.0012
Mint Tokens Same...340654422025-11-23 11:59:3216 days ago1763899172IN
0x925C42A5...3e07C8999
0.00001012 ETH0.000389252.93007258
Mint Tokens Same...340651962025-11-23 11:51:2016 days ago1763898680IN
0x925C42A5...3e07C8999
0.000014 ETH0.000364042.51225609
Mint Tokens Same...340648522025-11-23 11:39:5216 days ago1763897992IN
0x925C42A5...3e07C8999
0.00001162 ETH0.000182691.40225937
Mint Tokens Same...340647212025-11-23 11:35:3016 days ago1763897730IN
0x925C42A5...3e07C8999
0.00001562 ETH0.000132890.97274404
Mint Tokens Same...340646232025-11-23 11:32:1416 days ago1763897534IN
0x925C42A5...3e07C8999
0.00001578 ETH0.000094280.7253689
Mint Tokens Same...340645272025-11-23 11:29:0216 days ago1763897342IN
0x925C42A5...3e07C8999
0.00001562 ETH0.000070220.51396928
View all transactions

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To Amount
341063332025-11-24 10:42:3415 days ago1763980954
0x925C42A5...3e07C8999
0.00005568 ETH
340761382025-11-23 17:56:0416 days ago1763920564
0x925C42A5...3e07C8999
0.00000024 ETH
340757732025-11-23 17:43:5416 days ago1763919834
0x925C42A5...3e07C8999
0.00000054 ETH
340756742025-11-23 17:40:3616 days ago1763919636
0x925C42A5...3e07C8999
0.00000054 ETH
340755762025-11-23 17:37:2016 days ago1763919440
0x925C42A5...3e07C8999
0.00000008 ETH
340753662025-11-23 17:30:2016 days ago1763919020
0x925C42A5...3e07C8999
0.00000341 ETH
340752442025-11-23 17:26:1616 days ago1763918776
0x925C42A5...3e07C8999
0 ETH
340752432025-11-23 17:26:1416 days ago1763918774
0x925C42A5...3e07C8999
0.00000001 ETH
340752102025-11-23 17:25:0816 days ago1763918708
0x925C42A5...3e07C8999
0.00000001 ETH
340751822025-11-23 17:24:1216 days ago1763918652
0x925C42A5...3e07C8999
0 ETH
340751642025-11-23 17:23:3616 days ago1763918616
0x925C42A5...3e07C8999
0.00005068 ETH
340654422025-11-23 11:59:3216 days ago1763899172
0x925C42A5...3e07C8999
0.00000008 ETH
340651962025-11-23 11:51:2016 days ago1763898680
0x925C42A5...3e07C8999
0.00000001 ETH
340648522025-11-23 11:39:5216 days ago1763897992
0x925C42A5...3e07C8999
0.00000026 ETH
340647212025-11-23 11:35:3016 days ago1763897730
0x925C42A5...3e07C8999
0.00000038 ETH
340646232025-11-23 11:32:1416 days ago1763897534
0x925C42A5...3e07C8999
0.00000022 ETH
340645272025-11-23 11:29:0216 days ago1763897342
0x925C42A5...3e07C8999
0.00000038 ETH
340644292025-11-23 11:25:4616 days ago1763897146
0x925C42A5...3e07C8999
0.00005068 ETH
340329002025-11-22 17:54:4817 days ago1763834088
0x925C42A5...3e07C8999
0.00000011 ETH
340327072025-11-22 17:48:2217 days ago1763833702
0x925C42A5...3e07C8999
0.00000019 ETH
340325922025-11-22 17:44:3217 days ago1763833472
0x925C42A5...3e07C8999
0.00000021 ETH
340324942025-11-22 17:41:1617 days ago1763833276
0x925C42A5...3e07C8999
0.00000018 ETH
340323262025-11-22 17:35:4017 days ago1763832940
0x925C42A5...3e07C8999
0.00000037 ETH
340322272025-11-22 17:32:2217 days ago1763832742
0x925C42A5...3e07C8999
0.00005068 ETH
340252972025-11-22 13:41:2217 days ago1763818882
0x925C42A5...3e07C8999
0.00000018 ETH
View All Internal Transactions

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
B0x_Mining_Proof_of_Work

Compiler Version
v0.8.28+commit.7893614a

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 1 : B0x_Proof_Of_Work.sol
//CHANGES NEEDED FOR MAINNET//

//    uint public immutable startTime =  block.timestamp; //1738771200;  //Date and time (GMT): Wednesday, Feb 5, 2025 4:00:00 PM GMT Unix Epoch: 1738771200
//    uint public immutable startTime =  block.timestamp-24*60*60*2; //1738771200;  //Date and time (GMT): Wednesday, Feb 5, 2025 4:00:00 PM GMT Unix Epoch: 1738771200
//Must make correct startTime
  //  uint public immutable startTime =  block.timestamp-24*60*60*2; //1738771200;  //Date and time (GMT): Wednesday, Feb 5, 2025 4:00:00 PM GMT Unix Epoch: 1738771200
        // MUST REMOVE THE STATIC PRICE IN getETHPricePrecise please!
    // Returns price multiplied by 10^22 (10^12 for USDC decimals + 10^10 for full precision)
   // function getETHPricePrecise() public view returns (uint256 price) {
    //    return 3744799707501163;
        //Fix return for now until mainnet then remove!

        // MUST REMOVE THE STATIC PRICE IN getETHPricePrecise please!
       //      blocks = 1; //Use for testing NFT minting
       //MUST make normal for blocks = 1 and
    //     uint public slowBlocks = 2048; //Number of slow blocks (12+ minutes)
    //slow blocks should be 0
    //
	//in openMining	miningTarget = (2**252); SHOULD BE 2**234!!!! //0xBTCs starting difficulty of 1 //change it to 2**234 for launch please
	//in openMining	miningTarget = (2**252); SHOULD BE 2**234!!!! //0xBTCs starting difficulty of 1 //change it to 2**234 for launch please
    //
      //  miningTarget = 2**234; in readjustDifficulty
        //for now to check stuff
//Make sure to change startTime to ur actual startTime

//    address public B0x_Mining_TOKEN_ADDRESS = address(0x677F124CD209489F6621eebDFdA1E32c625214d4);     MAKE IMMUTABLE TO CURRENT TOKEN WHEN LAUNCHING
//    address public B0x_Mining_TOKEN_ADDRESS = address(0x677F124CD209489F6621eebDFdA1E32c625214d4);     MAKE IMMUTABLE TO CURRENT TOKEN WHEN LAUNCHING
    //SHOULD BE Base Network and BASED WORK TOKEN PLEASE ADJUST BEFORE REAL LAUNCH
    //address constant public B0x_Mining_TOKEN_ADDRESS = address(0x677F124CD209489F6621eebDFdA1E32c625214d4); //SHOULD BE Base Network and BASED WORK TOKEN 
    //should be constant when deployed
    //SHOULD BE Base Network and BASED WORK TOKEN PLEASE ADJUST BEFORE REAL LAUNCH
    //address constant public B0x_Mining_TOKEN_ADDRESS = address(0x677F124CD209489F6621eebDFdA1E32c625214d4); //SHOULD BE Base Network and BASED WORK TOKEN 
//    address public B0x_Mining_TOKEN_ADDRESS = address(0x677F124CD209489F6621eebDFdA1E32c625214d4);     MAKE IMMUTABLE TO CURRENT TOKEN WHEN LAUNCHING
//    address public B0x_Mining_TOKEN_ADDRESS = address(0x677F124CD209489F6621eebDFdA1E32c625214d4);     MAKE IMMUTABLE TO CURRENT TOKEN WHEN LAUNCHING
///**
//**MUST REMOVE THIS FUNCTION BEFORE WE LAUNCH setDifficultyOnlyTestnet must be removed before mainnet launches, this is just for extra help testnet stuff 
//function setDifficultyOnlyTestnet(uint _newDifficulty) public onlyOwner returns (bool) {
 //   **////**
//**MUST REMOVE THIS FUNCTION BEFORE WE LAUNCH setDifficultyOnlyTestnet must be removed before mainnet launches, this is just for extra help testnet stuff 
//function setDifficultyOnlyTestnet(uint _newDifficulty) public onlyOwner returns (bool) {
 //   **/

//Remove Ownable2 we dont need it for mainnet only for testnet to reset difficulty
//Remove Ownable2 we dont need it for mainnet only for testnet to reset difficulty
//Remove Ownable2 we dont need it for mainnet only for testnet to reset difficulty
/*


    MUST HAVE BASE MAINNET TOKEN ADDRESS HERE Uniswap v3 USDC/ETH pool here test this function seperatly on mainnet first before launch

    /// @notice USDC/ETH pool address on Base for price reference
    /// @dev Used for sqrtPricex96 calculations, Uniswap V3 pool on Base mainnet
    address constant POOL_ADDRESS = 0xd0b53D9277642d899DF5C87A3966A349A798F224;

*/




// B ZERO X Token - B0x Token Proof of Work Mining Contract
//
// Website: https://bzerox.com/
// Github: https://github.com/B0x-Token/
// Discord: https://discord.gg/K89uF2C8vJ
// Twitter: https://x.com/B0x_Token/
//
//
// Distrubtion of B ZERO X Tokens - B0x Token is as follows:
//
// B0x Token is distributed to users by using Proof of work and is considered a Version 2 & Layer 2 of 0xBitcoin.  Our contract allows all 0xBitcoin to be converted to B0x Tokens.
// Computers solve a complicated problem to gain tokens!
// 100% of 0xBitcoin accepted for B0x Tokens
// 100% Of the Token is distributed to the users! No dev fee!
// Token Mining will take place on Base Blockchain, while having the token reside on Mainnet Ethereum for maximum security.
//
// Symbol: B0x
// Decimals: 18
//
// Total supply: 31,165,100.000000000000000000
//   =
// 10,835,900 0xBitcoin Tokens able to transfered to B0x Tokens.
// +
// 10,164,100 Mined over 100+ years using Bitcoins Distrubtion halvings every ~4 years. Uses Proof-oF-Work to distribute the tokens. Public Miner is available see https://bzerox.com/
// +
// 10,164,100 sent to Liquidity Providers of the 0xBTC/B0x liquidity pool. Distributes 1 token to the Staking contract for every 1 token minted by Proof-of-Work miners
//  
//
// No dev cut, or advantage taken at launch. Public miner available at launch. 100% of the token is given away fairly over 100+ years using Bitcoins model!
// 
// Mint 2016 answers per challenge in this cost savings Bitcoin!! Less failed transactions as the challenge only changes every 2016 answers instead of every answer.
//
// Credits: 0xBitcoin
//
// startTime =  1738771200;  //Date and time (GMT): Wednesday, Feb 5, 2025 4:00:00 PM GMT then openMining functioncan then be called and mining will have rewards, until then all rewards will be 0.




pragma solidity ^0.8.11;


/// @title Ownable2
/// @notice Basic ownership contract providing access control functionality
/// @dev Implements ownership transfer with event logging for transparency
contract Ownable2 {
    /// @notice Address of the current contract owner with administrative privileges
    /// @dev Set to deployer initially, can be transferred to another address
    address public owner;
    
    /// @notice Emitted when ownership is transferred from one address to another
    /// @param from The previous owner address (address(0) for initial assignment)
    /// @param to The new owner address receiving ownership privileges
    event TransferOwnership(address from, address to);
    
    /// @notice Initializes the contract and sets the deployer as the initial owner
    /// @dev Emits TransferOwnership event with address(0) as the from address
    constructor() {
        owner = msg.sender;
        emit TransferOwnership(address(0), msg.sender);
    }
    
    /// @notice Restricts function access to only the current contract owner
    /// @dev Reverts with "Only Owner" message if called by non-owner address
    modifier onlyOwner() {
        require(msg.sender == owner, "Only Owner");
        _;
    }
    
    /// @notice Internal function to transfer ownership to a new address
    /// @dev Can only be called by the current owner, emits TransferOwnership event
    /// @param _owner The address to transfer ownership to
    function setOwner(address _owner) internal onlyOwner {
        emit TransferOwnership(owner, _owner);
        owner = _owner;
    }
}


// File: contracts/utils/SafeMath.sol

library SafeMath2 {
    function add(uint256 x, uint256 y) internal pure returns (uint256) {
        uint256 z = x + y;
        require(z >= x);
        return z;
    }

    function sub(uint256 x, uint256 y) internal pure returns (uint256) {
        require(x >= y);
        return x - y;
    }

    function mult(uint256 x, uint256 y) internal pure returns (uint256) {
        if (x == 0) {
            return 0;
        }

        uint256 z = x * y;
        require(z / x == y);
        return z;
    }

    function div(uint256 x, uint256 y) internal pure returns (uint256) {
        require(y != 0);
        return x / y;
    }

    function divRound(uint256 x, uint256 y) internal pure returns (uint256) {
        require(y != 0);
        uint256 r = x / y;
        if (x % y != 0) {
            r = r + 1;
        }

        return r;
    }
}





interface IERC721 {
    /**
     * @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 be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

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

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

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

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


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

interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC
     5MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
        external
        view
        returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}
interface IERC1155Receiver is IERC165 {
    /**
     * @dev Handles the receipt of a single ERC1155 token type. This function is
     * called at the end of a `safeTransferFrom` after the balance has been updated.
     *
     * NOTE: To accept the transfer, this must return
     * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
     * (i.e. 0xf23a6e61, or its own function selector).
     *
     * @param operator The address which initiated the transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param id The ID of the token being transferred
     * @param value The amount of tokens being transferred
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
     */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
     * @dev Handles the receipt of a multiple ERC1155 token types. This function
     * is called at the end of a `safeBatchTransferFrom` after the balances have
     * been updated.
     *
     * NOTE: To accept the transfer(s), this must return
     * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
     * (i.e. 0xbc197c81, or its own function selector).
     *
     * @param operator The address which initiated the batch transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param ids An array containing ids of each token being transferred (order and length must match values array)
     * @param values An array containing amounts of each token being transferred (order and length must match ids array)
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
     */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}


interface IUniswapV3Pool {
    function slot0()
        external
        view
        returns (
            uint160 sqrtPriceX96,
            int24 tick,
            uint16 observationIndex,
            uint16 observationCardinality,
            uint16 observationCardinalityNext,
            uint8 feeProtocol,
            bool unlocked
        );
}
interface IPoolFactory {
    function getPool(
        address tokenA,
        address tokenB,
        uint24 fee
    ) external view returns (address pool);
}


interface IETHConverter {
    /**
     * @notice Convert ETH to WETH
     * @dev Converts all ETH sent with the transaction to WETH
     */
    function convertETHtoWETH() external payable;
    
}



// File: contracts/interfaces/IERC20.sol

interface IERC20 {
    function transfer(address _to, uint _value) external returns (bool success);
    function transferFrom(address _from, address _to, uint256 _value) external returns (bool success);
    function balanceOf(address _owner) external view returns (uint256 balance);
}




// File: contracts/B0x_Mining_Proof_Of_Work.sol


// B ZERO X Token - B0x Token Proof of Work Mining Contract.
//
// Website: https://bzerox.com/
// Github: https://github.com/B0x-Token/
// Discord: https://discord.gg/K89uF2C8vJ
// Twitter: https://x.com/B0x_Token/
//
//
// Distrubtion of B ZERO X Tokens - B0x Token is as follows:
//
// B0x Token is distributed to users by using Proof of work and is considered a Version 2 & Layer 2 of 0xBitcoin.  Our contract allows all 0xBitcoin to be converted to B0x Tokens.
// Computers solve a complicated problem to gain tokens!
// 100% of 0xBitcoin accepted for B0x Tokens
// 100% Of the Token is distributed to the users! No dev fee!
// Token Mining will take place on Base Blockchain, while having the token reside on Mainnet Ethereum for maximum security.
//
// Symbol: B0x
// Decimals: 18
//
// Total supply: 31,165,100.000000000000000000
//   =
// 10,835,900 0xBitcoin Tokens able to transfered to B0x Tokens.
// +
// 10,164,100 Mined over 100+ years using Bitcoins Distrubtion halvings every ~4 years. Uses Proof-oF-Work to distribute the tokens. Public Miner is available see https://bzerox.com/
// +
// 10,164,100 sent to Liquidity Providers of the 0xBTC/B0x liquidity pool. Distributes 1 token to the Staking contract for every 1 token minted by Proof-of-Work miners
//  
//
// No dev cut, or advantage taken at launch. Public miner available at launch. 100% of the token is given away fairly over 100+ years using Bitcoins model!
// 
// Mint 2016 answers per challenge in this cost savings Bitcoin!! Less failed transactions as the challenge only changes every 2016 answers instead of every answer.
//
// Credits: 0xBitcoin
//
// startTime =  1738771200;  //Date and time (GMT): Wednesday, Feb 5, 2025 4:00:00 PM GMT then openMining functioncan then be called and mining will have rewards, until then all rewards will be 0.



//Remove the Ownable2 for mainnet release

/// @title B0x Mining Proof of Work
/// @notice Proof of Work mining contract for B0x tokens on Base network
/// @dev Implements Bitcoin-style mining with difficulty adjustments and reward halvings
contract B0x_Mining_Proof_of_Work is Ownable2 {

    ////
    // Based Work Token Mining Initializations 
    ////
    
    /// @notice Address of the B0x token contract on Base network
    /// @dev Should be made immutable for mainnet deployment to prevent changes
    address public B0x_Mining_TOKEN_ADDRESS = address(0x677F124CD209489F6621eebDFdA1E32c625214d4);

    /// @notice USDC/ETH pool address on Base for price reference
    /// @dev Used for sqrtPricex96 calculations, Uniswap V3 pool on Base mainnet
    address constant POOL_ADDRESS = 0xd0b53D9277642d899DF5C87A3966A349A798F224;

    /// @notice Target time between blocks in seconds (10 minutes)
    /// @dev Used for difficulty adjustments to maintain consistent block times
    uint public targetTime = 60 * 10;
    
    /// @notice Immutable start time for mining operations
    /// @dev Set to 2 days before deployment for initial calculations
    uint public immutable startTime = block.timestamp - 24 * 60 * 60 * 2;

    using SafeMath2 for uint256;

    /// @notice Emitted when a standard mining reward is claimed
    /// @param from Address of the miner who found the solution
    /// @param reward_amount Amount of tokens minted as reward
    /// @param epochCount Current epoch number when mined
    /// @param newChallengeNumber The new challenge for the next block
    event Mint(address indexed from, uint reward_amount, uint epochCount, bytes32 newChallengeNumber);
    
    /// @notice Emitted when a mega mining reward is claimed with multiplier
    /// @param from Address of the miner who found the solution
    /// @param epochCount Current epoch number when mined
    /// @param newChallengeNumber The new challenge for the next block
    /// @param NumberOfTokensMinted Total number of tokens minted
    /// @param TokenMultipler Multiplier applied to the base reward
    event MegaMint(address indexed from, uint epochCount, bytes32 newChallengeNumber, uint NumberOfTokensMinted, uint256 TokenMultipler);

    /// @notice Prevents reuse of challenge-digest combinations
    /// @dev Maps challenge hash to digest hash to boolean (used/unused)
    mapping(bytes32 => mapping(bytes32 => bool)) public usedCombinations;

    /// @notice Prevents the same challenge from being used multiple times
    /// @dev Maps challenge hash to boolean (used/unused)
    mapping(bytes32 => bool) public usedChallenges;
    
    /// @notice Maps used challenges to their sequential number
    /// @dev Tracks the order in which challenges were used
    mapping(bytes32 => uint) public usedChallengesNumber;

    /// @notice Number of blocks between difficulty adjustments (Bitcoin-style)
    /// @dev Should be 2016 blocks to align with Bitcoin's adjustment period
    uint public constant _BLOCKS_PER_READJUSTMENT = 2016;
    
    /// @notice Maximum mining target to prevent difficulty from becoming too easy
    /// @dev Large number at least 5x smaller than max to prevent overflow (max 4x increases)
    uint public constant _MAXIMUM_TARGET = 2**253;

    /// @notice Minimum mining target to prevent difficulty from becoming impossible
    /// @dev Small number ensuring mining remains feasible
    uint public constant _MINIMUM_TARGET = 2**16;

    /// @notice Current mining target for difficulty calculation
    /// @dev Normalized to 0xBitcoin's starting difficulty (2**234)
    uint public miningTarget = 2**234;

    /// @notice Maximum total supply of tokens (21 million, Bitcoin-style)
    /// @dev Hard cap on total token creation
    uint public constant _maxTotalSupply = 21000000000000000000000000;

    /// @notice Timestamp of the last difficulty adjustment
    /// @dev Used for calculating time-based difficulty adjustments
    uint public latestDifficultyPeriodStarted2 = block.timestamp;
    
    /// @notice Block number of the last difficulty adjustment
    /// @dev Used for block-based difficulty adjustments
    uint public latestDifficultyPeriodStarted = block.number;
    
    /// @notice Number of blocks mined (epochs completed)
    /// @dev Incremented with each successful mine
    uint public epochCount = 0;

    /// @notice Current challenge that miners must solve
    /// @dev Based on previous block hash, changes with each successful mine
    bytes32 public challengeNumber = blockhash(block.number - 1);

    /// @notice Current reward era for halving calculations
    /// @dev Determines the current reward amount based on total supply
    uint public rewardEra = 1;
    
    /// @notice Maximum supply allowed for the current reward era
    /// @dev Calculated based on reward era for halving mechanics
    uint public maxSupplyForEra = (_maxTotalSupply - _maxTotalSupply.div(2**(rewardEra + 1)));
    
    /// @notice Current reward amount per successful mine
    /// @dev Calculated based on current era and supply
    uint public reward_amount = 0;
    
    /// @notice Minimum ETH amount for price calculations
    /// @dev 0.0000005 ETH * $4500/ETH = $0.00225 minimum price per token
    uint constant minAmountETH = 0.0000005 ether;

    /// @notice Total tokens minted so far
    /// @dev Starts at 10,835,900 tokens (matching 0xBitcoin's mined amount)
    uint public tokensMinted = 10_835_900 * 10**18;
    
    /// @notice Total ETH distributed to miners
    /// @dev Tracks cumulative ETH rewards paid out
    uint public totalETH_MintedToMiners = 0;
    
    /// @notice Last recorded token count for calculations
    /// @dev Used in reward distribution calculations
    uint lastRunB0x = tokensMinted;
    
    /// @notice Last recorded ETH amount for calculations
    /// @dev Used in reward distribution calculations
    uint lastRunETH = 0;
    
    /// @notice Epoch count at the last readjustment
    /// @dev Used for tracking adjustment periods
    uint public epochOld = 0;
    
    /// @notice Startup lock to prevent premature operations
    /// @dev Security mechanism for controlled contract initialization
    bool public locked = false;

    /// @notice Handles safe receipt of ERC721 tokens
    /// @dev Required for receiving NFTs sent to this contract
    /// @return bytes4 The function selector to confirm receipt
    function onERC721Received(address, address, uint256, bytes calldata) external pure returns (bytes4) {
        return IERC721Receiver.onERC721Received.selector;
    }
    
    /// @notice Handles safe receipt of ERC1155 tokens
    /// @dev Required for receiving ERC1155 tokens sent to this contract
    /// @return bytes4 The function selector to confirm receipt
    function onERC1155Received(address, address, uint256, uint256, bytes calldata) external pure returns (bytes4) {
        return IERC1155Receiver.onERC1155Received.selector;
    }
    
    /// @notice Handles safe batch receipt of ERC1155 tokens
    /// @dev Required for receiving batch ERC1155 transfers
    /// @return bytes4 The function selector to confirm receipt
    function onERC1155BatchReceived(address, address, uint256, uint256, bytes calldata) external pure returns (bytes4) {
        return IERC1155Receiver.onERC1155Received.selector;
    }

    // SUPPORTING CONTRACTS
    /// @notice Address of the LP reward distribution contract
    /// @dev Contract responsible for distributing rewards to liquidity providers
    address public AddressLPReward;

    /// @notice Total B0x tokens sent to LP reward pool
    /// @dev Tracks cumulative tokens allocated to liquidity providers
    uint public sentToLP = 0;

    /// @notice Multiplier based on held Ethereum amount
    /// @dev Higher ETH holdings reduce the percentage distributed (inverse relationship)
    uint public multipler = 0;
    
    /// @notice Previous epoch count for reward calculations
    /// @dev Used in ArewardSender function for tracking changes
    uint public oldecount = 0;
    
    /// @notice Previous block timestamp for time calculations
    /// @dev Used for measuring time intervals between operations
    uint public previousBlockTime = block.timestamp;
    
    /// @notice Amount of ETH distributed per mint operation
    /// @dev Tracks ETH distribution rate per successful mine
    uint public Token2Per = 0;
    
    /// @notice Number of slow blocks (taking 12+ minutes to mine)
    /// @dev Tracks mining performance and difficulty appropriateness
    uint public slowBlocks = 0;
    
    /// @notice Amount of 0x tokens to give (legacy reference)
    /// @dev May be related to 0xBitcoin compatibility or rewards
    uint public give0x = 0;
    
    /// @notice Timestamp of the last function execution
    /// @dev Used for rate limiting and timing calculations
    uint256 public lastrun = block.timestamp;

    //**MUST REMOVE THIS FUNCTION BEFORE WE LAUNCH setDifficultyOnlyTestnet must be removed before mainnet launches, this is just for extra help testnet stuff */
    //**MUST REMOVE THIS FUNCTION BEFORE WE LAUNCH setDifficultyOnlyTestnet must be removed before mainnet launches, this is just for extra help testnet stuff */
    //**MUST REMOVE THIS FUNCTION BEFORE WE LAUNCH setDifficultyOnlyTestnet must be removed before mainnet launches, this is just for extra help testnet stuff */
    
    /// @notice TESTNET ONLY: Manually sets mining difficulty for testing purposes
    /// @dev ⚠️ CRITICAL: This function MUST be removed before mainnet deployment
    /// @dev Allows owner to override difficulty calculations for easier testnet mining
    /// @dev Uses 0xBTC difficulty scale with 524,288 normalization factor
    /// @param _newDifficulty The difficulty level to set (must be below 10,000)
    /// @return bool True if difficulty was successfully updated
    /// @custom:security-note This function bypasses normal difficulty adjustment mechanisms
    /// @custom:mainnet-warning REMOVE THIS FUNCTION BEFORE PRODUCTION DEPLOYMENT
    function setDifficultyOnlyTestnet(uint _newDifficulty) public onlyOwner returns (bool) {
        require(_newDifficulty < 10000, "New difficulty must be at least below 10000 0xBTC difficulty not higher");
        miningTarget = _MAXIMUM_TARGET.div(_newDifficulty * 524_288);
        return true;
    }


    /// @notice Initializes the B0x mining contract with token and LP reward addresses
    /// @dev Sets up initial mining parameters and marks the first challenge as used
    /// @param token Address of the B0x token contract to be mined
    /// @param lp Address of the LP reward distribution contract
    constructor(address token, address lp) {
        B0x_Mining_TOKEN_ADDRESS = token;
        AddressLPReward = lp;
        latestDifficultyPeriodStarted2 = block.timestamp;
        latestDifficultyPeriodStarted = block.number;	
        challengeNumber = blockhash(block.number - 1); //generate a new one so we can start with a fresh
        usedChallenges[blockhash(block.number - 1)] = true;
    }
    
    
	
    /// @notice Activates mining operations with initial parameters and safety checks
    /// @dev Can only be called once within a 7-day window after startTime, requires proper token funding
    /// @dev Initializes mining with Feb 5th 2025 @ 4PM GMT target launch (epochTime = 1738771200)
    /// @return success True if mining was successfully activated
    /// @custom:timing Must be called between startTime and startTime + 7 days
    /// @custom:funding Requires contract to hold at least 20,328,200 B0x tokens (2*10,164,100)
    function openMining() public returns (bool success) {
        require(tokensMinted <= 10_835_900 * 10**18, "Cant mint tokens before launch");
        require(IERC20(B0x_Mining_TOKEN_ADDRESS).balanceOf(address(this)) >= 2*10_164_100 * 10 ** 18, "Must supply 2*10_164_100 min tokens");
        require(reward_amount == 0, "reward must be zero");
        require(!locked, "Only allowed to run once");
        locked = true;
        require(block.timestamp >= startTime && block.timestamp <= startTime + 60* 60 * 24* 7, "7 Day window to activate StartTime");
        challengeNumber = blockhash(block.number - 1); //generate a new one so we can start fresh
        reward_amount = (50 * 10**18) / (2**(rewardEra));
        maxSupplyForEra = (_maxTotalSupply - _maxTotalSupply.div(2**(rewardEra + 1)));
        miningTarget = (2**234);  //0xBTCs starting difficulty of 1 //change it to 2**234 for launch please
        latestDifficultyPeriodStarted2 = block.timestamp;
        latestDifficultyPeriodStarted = block.number;	
        epochOld = 0;
        epochCount = 0;//number of 'blocks' mined
        require(usedChallenges[challengeNumber] == false);
        usedChallenges[challengeNumber] = true;
        return true;
    }



/// @notice Calculates Token2Per_return given a multiplier
/// @dev Returns Token2Per_return to scale base reward amounts
/// @dev Higher multipliers progressively reduce ETH distribution rewards
/// @param multiplier The multiplier value to determine scaling tier
/// @return Token2Per_return The amount of Token to be distributed
/// @custom:scaling-tiers
function getToken2Per(uint multiplier) internal pure returns (uint Token2Per_return) {
    if (multiplier < 200) {
        Token2Per_return = 0.00000180 ether * multiplier / 200; 
    } else if (multiplier < 400) {
        Token2Per_return = 0.00000300 ether * multiplier / 400; 
    } else if (multiplier < 800) {
        Token2Per_return = 0.00000500 ether * multiplier / 800; 
    } else if (multiplier < 1600) {
        Token2Per_return = 0.00000800 ether * multiplier / 1600; 
    } else if (multiplier < 3000) {
        Token2Per_return = 0.00001200 ether * multiplier / 3000; 
    } else if (multiplier < 5000) {
        Token2Per_return = 0.00001500 ether * multiplier / 5000; 
    } else if (multiplier < 10000) {
        Token2Per_return = 0.00002000 ether * multiplier / 10000; 
    } else if (multiplier < 20000) {
        Token2Per_return = 0.00003000 ether * multiplier / 20000; 
    } else if (multiplier < 40000) {
        Token2Per_return = 0.00005000 ether * multiplier / 40000; 
    } else if (multiplier < 100000) {
        Token2Per_return = 0.00010000 ether * multiplier / 100000; 
    } else if (multiplier < 200000) {
        Token2Per_return = 0.00015000 ether * multiplier / 200000; 
    } else if (multiplier < 500000) {
        Token2Per_return = 0.00025000 ether * multiplier / 500000; 
    } else if (multiplier < 1000000) {
        Token2Per_return = 0.00050000 ether * multiplier / 1000000; 
    } else {
        Token2Per_return = (0.00050000 ether * multiplier) / 1000000;
    }
}
    

    /// @notice Distributes accumulated rewards to liquidity providers when adjustment threshold is met
    /// @dev Executes every BLOCKS_PER_READJUSTMENT / 4 blocks to manage LP reward distribution
    /// @dev Calculates multiplier based on contract balance vs 0.15 ETH adjustment threshold
    /// @dev Determines scaling factor for Token2Per using the calculated multiplier
    /// @dev Transfers accumulated B0x tokens to LP reward address
    /// @dev Conditionally sends ETH to LP reward address if balance is sufficient
    /// @dev Updates tracking variables for next execution cycle
    /// @custom:requirements Contract must have sufficient balance for ETH transfers
    /// @custom:requirements B0x mining token contract must be valid and have sufficient balance
    /// @custom:requirements LP reward address must be set and valid
    /// @custom:state-changes Updates multipler, Token2Per, sentToLP, give0x flag, lastRunB0x, lastRunETH
    function ARewardSender() public {

        //runs every _BLOCKS_PER_READJUSTMENT / 4
        uint256 ADJUSTMENT_THRESHOLD = 0.1499999999999 ether;
        multipler = (address(this).balance*100) / ADJUSTMENT_THRESHOLD;     //Adjust every 0.15 eth or 700$
            

        
        // Use a more compact approach to determine the scaling factor
        Token2Per = getToken2Per(multipler);
        
        
        uint B0x_To_LPERS = tokensMinted - lastRunB0x;
        uint ETH_To_LPERs = totalETH_MintedToMiners - lastRunETH;

        IERC20(B0x_Mining_TOKEN_ADDRESS).transfer(AddressLPReward, B0x_To_LPERS);

        sentToLP = sentToLP.add(B0x_To_LPERS);

        if(address(this).balance > (80 * (Token2Per * _BLOCKS_PER_READJUSTMENT/2))) {  // at least enough blocks to rerun this function for both LPRewards and Users
            address payable to = payable(AddressLPReward);
            (bool success, ) = to.call{value: ETH_To_LPERs}("");
            require(success, "ETH transfer failed");

            give0x = 1;
            IETHConverter(AddressLPReward).convertETHtoWETH();
        } else { 
            give0x = 0;
        }
        
        lastRunB0x = tokensMinted;
        lastRunETH = totalETH_MintedToMiners;
    }


    ///
    // Based Work Token Minting
    ///  
    
    /// @notice Legacy compatibility function for single nonce mining operations
    /// @dev Wrapper that converts single nonce to array format for multi_MintTo function
    /// @dev Maintains backward compatibility with standard mining interfaces
    /// @param nonce The nonce value that solves the current mining challenge
    /// @param challenge_digest The digest parameter (unused but kept for interface compatibility)
    /// @return success True if mining operation resulted in token reward (> 0 tokens minted)
    /// @custom:compatibility Provides standard mining function interface for miners
    /// @custom:delegation Internally delegates to multi_MintTo with single-element nonce array
    function mint(uint256 nonce, bytes32 challenge_digest) public returns (bool success) {
        uint256[] memory nonceArray = new uint256[](1);
        nonceArray[0] = nonce;
        return multi_MintTo(msg.sender, nonceArray, _BLOCKS_PER_READJUSTMENT, 0) > 0;
    }
    
    
    /// @notice Advanced mining function that processes multiple solutions in a single transaction
    /// @dev Allows miners to submit multiple valid nonces at once for improved efficiency and gas optimization
    /// @dev Supports batch mining with configurable limits and timing requirements
    /// @param mintToAddress The address that will receive the mined tokens (can be different from msg.sender)
    /// @param nonce Array of nonce values that solve the current mining challenge
    /// @param maxAnswers Maximum number of solutions to process from the nonce array
    /// @param minPreviousBlockTimeDifference Minimum time difference required from previous block (timing constraint)
    /// @return NumberOfMintsDone The actual number of successful mining operations completed
    /// @custom:efficiency Processes multiple solutions in one transaction to reduce gas costs
    /// @custom:flexibility Supports delegation by allowing different mint recipient address
    /// @custom:batching Can process up to maxAnswers solutions or entire array if maxAnswers is 0
    /// @custom:timing May include timing constraints via minPreviousBlockTimeDifference parameter
    function multi_MintTo(address mintToAddress, uint256[] memory nonce, uint maxAnswers, uint minPreviousBlockTimeDifference) public payable returns (uint NumberOfMintsDone) {
        uint blocktimestampsLocal = block.timestamp;
        uint NextEpochCount = blocksToReadjust();
        uint xLoop = 0;
        uint GoodLoops = 0;
        uint prevBlockTime = previousBlockTime;
        uint targetTimez = targetTime;
        bytes32 localChallengeNumber = challengeNumber;
        uint localMiningTarget = miningTarget;
        uint miningTargetCloseToAdjustment = localMiningTarget;
        
        for (xLoop = 0; xLoop < nonce.length; xLoop++) {
            bytes32 digest = keccak256(abi.encodePacked(localChallengeNumber, msg.sender, nonce[xLoop]));
            uint localDigestINT = uint(digest);
            uint multiplier_local = localMiningTarget / localDigestINT;
            uint compensation = calculateCompensation(multiplier_local);

            if(GoodLoops + compensation > maxAnswers) {
                compensation = maxAnswers - GoodLoops;
            }

            if(GoodLoops + compensation >= NextEpochCount) {
                compensation = NextEpochCount - GoodLoops;
                uint SecPer1Compensation = (blocktimestampsLocal - prevBlockTime) / (NextEpochCount);
                
                if(targetTimez < SecPer1Compensation) {
                    uint timeMultiplier = SecPer1Compensation / (targetTimez / 2);
                    uint targetDivisor = targetTimez / (targetTimez / 2);
                    
                    // First check if result would exceed 2^253
                    uint MAX_SAFE_VALUE = 1 << 253; // 2^253

                    // Check if miningTarget * timeMultiplier would overflow
                    if (timeMultiplier > MAX_SAFE_VALUE / miningTarget) {
                        // Would overflow, use maximum safe value
                        miningTargetCloseToAdjustment = MAX_SAFE_VALUE / targetDivisor;
                    } else {
                        // Safe to calculate
                        uint256 product = miningTarget * timeMultiplier;
                        miningTargetCloseToAdjustment = product / targetDivisor;
                    }

                    if(usedCombinations[localChallengeNumber][digest] || localDigestINT >= miningTargetCloseToAdjustment) {
                        continue;
                    }
                } else if (usedCombinations[localChallengeNumber][digest] || localDigestINT >= localMiningTarget) {
                    continue;
                }
            } else if (usedCombinations[localChallengeNumber][digest] || localDigestINT >= localMiningTarget) {
                continue;
            }
            
            GoodLoops = GoodLoops.add(compensation);
            usedCombinations[localChallengeNumber][digest] = true;
            
            if(GoodLoops >= maxAnswers) {
                GoodLoops = maxAnswers;
                break;
            }
            if (GoodLoops >= NextEpochCount) {
                GoodLoops = NextEpochCount;
                break;
            }
        }

        require(GoodLoops > 0, "Must have valid solve in the answers");
        
        uint dif = (blocktimestampsLocal - prevBlockTime) / GoodLoops;
        require(minPreviousBlockTimeDifference <= dif, "Not enough Difference in prevBlockTime / GoodLoops, compared to minPreviousBlockTimeDifference function variable");

        uint miningDifficultyz = getMiningDifficulty();

        uint256 x = ((blocktimestampsLocal - prevBlockTime) / GoodLoops * 888) / targetTimez;
        uint ratio = x * 100 / 888;
        if(ratio > 100) {
            slowBlocks = slowBlocks.add(GoodLoops);
        }
        
        ( uint B0x_To_Send_User, uint totalETH_To_Send_User, uint totalETH_For_Contract ) = TotalForContract(GoodLoops, NextEpochCount);
        
        
        totalETH_MintedToMiners = totalETH_MintedToMiners + totalETH_To_Send_User;
        
	if (totalETH_To_Send_User >= totalETH_For_Contract) {
	    // Case 1: User is net receiving ETH
	    uint payout = totalETH_To_Send_User - totalETH_For_Contract;
	    // User gets payout, contract keeps nothing extra
	    totalETH_To_Send_User = msg.value + payout; // if msg.value > 0, it's just extra refund

	} else {
	    // Case 2: User must contribute ETH
	    uint required = totalETH_For_Contract - totalETH_To_Send_User;

	    if (msg.value < required) {
		revert(
		    string(
		        abi.encodePacked(
		            "Need to send required ETH. Required: ",
		            toString(required),
		            " wei, Sent: ",
		            toString(msg.value),
		            " wei"
		        )
		    )
		);
	    }

	    // Contract is satisfied, user might still receive excess if msg.value > required
	    totalETH_To_Send_User = msg.value - required; 
	}


		
				
		        
        _startNewMiningEpoch(NextEpochCount, GoodLoops);


        // If max supply for the era will be exceeded next reward round then enter the new era before that happens
        // 59 is the final reward era, almost all tokens minted
        if(tokensMinted.add(B0x_To_Send_User) > maxSupplyForEra && rewardEra < 59) {
            rewardEra = rewardEra + 1;
            maxSupplyForEra = _maxTotalSupply - _maxTotalSupply.div(2**(rewardEra + 1));
            reward_amount = (50 * 10**18) / (2**(rewardEra));
            B0x_To_Send_User = B0x_To_Send_User.div(2);
        }
        
        IERC20(B0x_Mining_TOKEN_ADDRESS).transfer(mintToAddress, B0x_To_Send_User);
        tokensMinted = tokensMinted.add(B0x_To_Send_User);
        previousBlockTime = blocktimestampsLocal;
                    
                    
        address payable to = payable(mintToAddress);
        to.call{value: totalETH_To_Send_User}("");

        emit Mint(msg.sender, B0x_To_Send_User, epochCount, localChallengeNumber);
        return GoodLoops;
    }
    
    

	
	//Remember we are special not like Bitcoin or 0xBitcoin we use 2**253 so it may seem large divide by 2**19 to fix
	//Also this only works on last block of the challenge/2016 blocks.
	function calcReduceDifficulty(uint prevBlockTime, uint NumberOfCompensation)public view returns (uint miningDifficultyReduced){

		uint miningTargetz = calcReduceTarget(prevBlockTime, NumberOfCompensation);
		miningDifficultyReduced = _MAXIMUM_TARGET.div(miningTargetz);
		return miningDifficultyReduced;        

	}



	//Remember we are special not like Bitcoin or 0xBitcoin we use 2**253 so it may seem large divide by 2**19 to fix
	//Also this only works on last block of the challenge/2016 blocks.
	function calcReduceTarget(uint prevBlockTime, uint NumberOfCompensation)public view returns (uint miningTargetReduced){

	    uint targetTimez=targetTime;
	    uint blockTimestampz = block.timestamp;
	    uint SecPer1Compensation = (blockTimestampz - prevBlockTime)/(NumberOfCompensation);
	    if(targetTimez < SecPer1Compensation){
	    	uint timeMultiplier = SecPer1Compensation/(targetTimez/2);
            uint targetDivisor = targetTime/(targetTimez/2);
                        
            uint MAX_SAFE_VALUE = 1 << 253; // 2^255


                // Check if miningTarget * timeMultiplier would overflow
            if (timeMultiplier > MAX_SAFE_VALUE / miningTarget) {
                // Would overflow, use maximum safe value
                return  MAX_SAFE_VALUE;
            } 

                // Safe to calculate
                uint256 product = miningTarget * timeMultiplier;
               return product / targetDivisor;
            

                        
					
	    }
    }


    ///
    ///// NFT Minting ////
    ///
    
    
    /// @notice Mints B0x tokens through standard mining while also transferring NFTs as bonus rewards
    /// @dev Performs normal multi_MintTo mining operation and additionally transfers specific NFTs to the miner
    /// @dev Can only be called during specific network conditions: near difficulty adjustment with slow block performance
    /// @param nftAddresses Array of NFT contract addresses that this contract holds
    /// @param nftNumbers Array of specific token IDs that this contract owns and will transfer
    /// @param nonces Array of nonce values that solve the current mining challenge
    /// @param maxNumberOfAnswersInMint Maximum number of solutions to process in this transaction
    /// @return success True if both mining and NFT transfer operations completed successfully
    /// @custom:timing-requirements Only available when blocksToReadjust() == 1 (near adjustment)
    /// @custom:performance-gate Requires blocksFromReadjust() < 5 and significant slow blocks
    /// @custom:slow-block-threshold Needs slowBlocks > _BLOCKS_PER_READJUSTMENT / 8 (poor network performance)
    /// @custom:dual-rewards Provides both B0x token mining rewards and NFT bonus rewards
    /// @custom:array-validation Requires nftAddresses and nftNumbers arrays to have matching lengths
    /// @custom:mining-validation Must successfully complete multi_MintTo operation before NFT transfer
    function mintNFT(
        address[] memory nftAddresses, 
        uint[] memory nftNumbers, 
        uint256[] memory nonces, 
        uint maxNumberOfAnswersInMint
    ) public payable returns (bool success) {
        require(blocksToReadjust() == 1 && blocksFromReadjust() < 5 && slowBlocks > _BLOCKS_PER_READJUSTMENT / 8, "NFT Adjust Bad");
        require(nftAddresses.length == nftNumbers.length, "Array length mismatch");
        
        require(multi_MintTo(msg.sender, nonces, maxNumberOfAnswersInMint, 0) > 0, "mintfailed nft");
        
        // Try each NFT until one succeeds
        for (uint i = 0; i < nftAddresses.length; i++) {
            address nftaddy = nftAddresses[i];
            uint nftNumber = nftNumbers[i];
            
            try IERC165(nftaddy).supportsInterface(0xd9b67a26) returns (bool isERC1155) {
                if (isERC1155) {
                    // Try ERC-1155 transfer
                    try IERC1155(nftaddy).safeTransferFrom(address(this), msg.sender, nftNumber, 1, "") {
                        slowBlocks = 0;
                        return true; // Success!
                    } catch {
                        // Continue to next NFT
                        continue;
                    }
                }
            } catch {
                // Interface check failed, continue
            }
            
            try IERC165(nftaddy).supportsInterface(0x80ac58cd) returns (bool isERC721) {
                if (isERC721) {
                    // Try ERC-721 transfer
                    try IERC721(nftaddy).safeTransferFrom(address(this), msg.sender, nftNumber, "") {
                        slowBlocks = 0;
                        return true; // Success!
                    } catch {
                        // Continue to next NFT
                        continue;
                    }
                }
            } catch {
                // Interface check failed, continue
            }
        }
        //Allow bad NFT users
        return true;
    }



    
    /// @notice Calculates the base-2 logarithm of a given number
    /// @dev Simple bit-shifting implementation for logarithm calculation
    /// @dev Used in compensation calculations for mining difficulty scaling
    /// @param x The input value to calculate log2 for
    /// @return uint256 The floor of log2(x), returns 0 for x <= 1
    function log2(uint256 x) public pure returns (uint256) {
        uint256 n = 0;
        while (x > 1) {
            x >>= 1;
            n++;
        }
        return n;
    }

    /// @notice Calculates mining compensation based on solution difficulty multiplier
    /// @dev Higher multipliers (better solutions) receive exponentially more compensation
    /// @dev Uses logarithmic scaling to reward significantly better solutions
    /// @param multiplier The difficulty multiplier from the mining solution quality
    /// @return uint256 The compensation amount (number of blocks/solutions this counts as)
    /// @custom:scaling Returns 1 for multiplier < 4, then log2(multiplier/2) + 1 for higher values
    /// @custom:example multiplier=8 gives log2(4)+1=3, multiplier=16 gives log2(8)+1=4
    function calculateCompensation(uint256 multiplier) public pure returns (uint256) {
        if(multiplier < 4) {
            return 1;
        }
        return log2(multiplier/2) + 1;
    }
    
    /// @notice Returns the total amount owed based on current time since last mint
    /// @dev Convenience wrapper that calculates owed amount using current block timestamp
    /// @return totalOwed The total amount owed based on time elapsed since previousBlockTime
    function totalOwedAtCurrentTime() public view returns (uint totalOwed) {
        return totalOwedAtTime(block.timestamp - previousBlockTime);
    }

    /// @notice Calculates total amount owed based on time elapsed since previous mint
    /// @dev Uses piecewise function with different formulas for different time ratios
    /// @dev Optimized for ratio around 3000 where totalOwed/100000000 ≈ 71.6
    /// @param secondsFromPreviousMint Time in seconds since the last successful mint operation
    /// @return totalOwed The calculated total amount owed based on elapsed time
    /// @custom:formula-low For ratio < 3000: quadratic formula (508606*(15*x²)/888² + 9943920*x/888)
    /// @custom:formula-high For ratio >= 3000: linear formula (24*x*5086060/888 + 3456750000)
    /// @custom:scaling Uses 888 as scaling factor related to targetTime normalization
    function totalOwedAtTime(uint secondsFromPreviousMint) public view returns (uint totalOwed) {
        totalOwed = 0;
        uint256 x = ((secondsFromPreviousMint) * 888) / targetTime;
        uint ratio = x * 100 / 888;
    
        //best @ 3000 ratio totalOwed / 100000000 = 71.6
        if(ratio < 3000) {
            totalOwed = (508606*(15*x**2)).div(888 ** 2) + (9943920 * (x)).div(888);
        } else {
            totalOwed = (24*x*5086060).div(888) + 3456750000;
        }
        
        return totalOwed;
    }


    /// @notice Returns the ETH amount to send to user based on current time since last mint
    /// @dev Convenience wrapper that calculates ETH distribution using current block timestamp
    /// @return totalETHToSendToUser The ETH amount to distribute based on elapsed time since previousBlockTime
    function totalETHtoSendUserAtCurrentTime() public view returns (uint totalETHToSendToUser) {
        return totalETHtoSendUserAtTime(block.timestamp - previousBlockTime);
    }


    /// @notice Calculates ETH distribution amount based on time elapsed and system state
    /// @dev Uses piecewise calculation similar to totalOwedAtTime with additional ETH-specific scaling
    /// @dev ETH distribution depends on give0x flag and uses Token2Per as scaling factor
    /// @param secondsFromPreviousMint Time in seconds since the last successful mint operation
    /// @return totalETHToSendToUser The calculated ETH amount to distribute to the user
    /// @custom:gating Only distributes ETH when give0x > 0 (sufficient contract reserves)
    /// @custom:ratio-scaling Different formulas for ratio < 2000 vs >= 2000 (more conservative at high ratios)
    /// @custom:scaling-factors Uses Token2Per and totalOwed/100000000 for amount calculations
    /// @custom:reserve-dependent Distribution amount scales with give0x multiplier for reserve management
    function totalETHtoSendUserAtTime(uint secondsFromPreviousMint) public view returns (uint totalETHToSendToUser) {
        uint totalOwed = 0;
        uint totalETHtoSendUser = 0;
        uint256 x = ((secondsFromPreviousMint) * 888) / targetTime;
        uint ratio = x * 100 / 888;
    
        //best @ 3000 ratio totalOwed / 100000000 = 71.6
        if(ratio < 3000) {
            totalOwed = (508606*(15*x**2)).div(888 ** 2) + (9943920 * (x)).div(888);
        } else {
            totalOwed = (24*x*5086060).div(888) + 3456750000;
        }
        
        if(give0x > 0) {
            if(ratio < 2000) {
                totalETHtoSendUser = ((totalOwed * Token2Per * give0x).div(100000000));
            } else {
                totalETHtoSendUser = ((320 * Token2Per * give0x).div(10));
            }
        }
        
        return totalETHtoSendUser;
    }



    /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
    /// @param a The multiplicand
    /// @param b The multiplier
    /// @param denominator The divisor
    /// @return result The 256-bit result
    /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv
    function mulDiv(uint256 a, uint256 b, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = a * b
            // Compute the product mod 2**256 and mod 2**256 - 1
            // then use the Chinese Remainder Theorem to reconstruct
            // the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2**256 + prod0
            uint256 prod0 = a * b; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly ("memory-safe") {
                let mm := mulmod(a, b, not(0))
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Make sure the result is less than 2**256.
            // Also prevents denominator == 0
            require(denominator > prod1);

            // Handle non-overflow cases, 256 by 256 division
            if (prod1 == 0) {
                assembly ("memory-safe") {
                    result := div(prod0, denominator)
                }
                return result;
            }

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0]
            // Compute remainder using mulmod
            uint256 remainder;
            assembly ("memory-safe") {
                remainder := mulmod(a, b, denominator)
            }
            // Subtract 256 bit number from 512 bit number
            assembly ("memory-safe") {
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator
            // Compute largest power of two divisor of denominator.
            // Always >= 1.
            uint256 twos = (0 - denominator) & denominator;
            // Divide denominator by power of two
            assembly ("memory-safe") {
                denominator := div(denominator, twos)
            }

            // Divide [prod1 prod0] by the factors of two
            assembly ("memory-safe") {
                prod0 := div(prod0, twos)
            }
            // Shift in bits from prod1 into prod0. For this we need
            // to flip `twos` such that it is 2**256 / twos.
            // If twos is zero, then it becomes one
            assembly ("memory-safe") {
                twos := add(div(sub(0, twos), twos), 1)
            }
            prod0 |= prod1 * twos;

            // Invert denominator mod 2**256
            // Now that denominator is an odd number, it has an inverse
            // modulo 2**256 such that denominator * inv = 1 mod 2**256.
            // Compute the inverse by starting with a seed that is correct
            // correct for four bits. That is, denominator * inv = 1 mod 2**4
            uint256 inv = (3 * denominator) ^ 2;
            // Now use Newton-Raphson iteration to improve the precision.
            // Thanks to Hensel's lifting lemma, this also works in modular
            // arithmetic, doubling the correct bits in each step.
            inv *= 2 - denominator * inv; // inverse mod 2**8
            inv *= 2 - denominator * inv; // inverse mod 2**16
            inv *= 2 - denominator * inv; // inverse mod 2**32
            inv *= 2 - denominator * inv; // inverse mod 2**64
            inv *= 2 - denominator * inv; // inverse mod 2**128
            inv *= 2 - denominator * inv; // inverse mod 2**256

            // Because the division is now exact we can divide by multiplying
            // with the modular inverse of denominator. This will give us the
            // correct result modulo 2**256. Since the preconditions guarantee
            // that the outcome is less than 2**256, this is the final result.
            // We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inv;
            return result;
        }
    }



    /// @notice Retrieves the current ETH price with maximum precision using FullMath library
    /// @dev Most precise method for ETH price calculation, recommended for accurate price feeds
    /// @dev Uses Uniswap V3 pool data to calculate current ETH/USDC price with full precision
    /// @return price ETH price multiplied by 10^22 for maximum precision (10^12 for USDC decimals + 10^10 for precision)
    /// @custom:precision Returns price scaled by 10^22 to maintain full decimal precision
    /// @custom:decimals Accounts for USDC's 6 decimal places with additional 10^16 scaling for precision
    /// @custom:library Uses FullMath library for overflow-safe arithmetic operations
    /// @custom:source Queries live Uniswap V3 ETH/USDC pool for real-time pricing data
    function getETHPricePrecise() public view returns (uint256 price) {
        return 4498799707501163;
        //Fix return for now until mainnet then remove!
        IUniswapV3Pool pool = IUniswapV3Pool(POOL_ADDRESS);
        (uint160 sqrtPriceX96, , , , , , ) = pool.slot0();
        
        // Calculate price = (sqrtPriceX96)^2 * 10^22 / 2^192
        // Using mulDiv to handle large numbers safely
        
        if (sqrtPriceX96 <= type(uint128).max) {
            // Safe to square without overflow
            uint256 priceX192 = uint256(sqrtPriceX96) * sqrtPriceX96;
            return (priceX192 * 1e24) >> 192;
        } else {
            // Use FullMath.mulDiv for large numbers
            // You'll need to import @uniswap/v3-core/contracts/libraries/FullMath.sol
            uint256 priceX128 = mulDiv(sqrtPriceX96, sqrtPriceX96, 1 << 64);
            return mulDiv(priceX128, 1e24, 1 << 128);
        }
    }


    /// @notice Calculates comprehensive mining results including B0x tokens, ETH flows, and current ETH price
    /// @dev Simulates mining operation results without executing the actual mining transaction, at current previousblockTime
    /// @dev Handles both regular mining and difficulty adjustment scenarios with different calculations
    /// @param compensation The mining compensation multiplier based on solution quality
    /// @return B0xYouGet Amount of B0x tokens the miner would receive
    /// @return ETHYouGet Amount of ETH the miner would receive (if any)
    /// @return ETHyouSpend Amount of ETH the miner would need to send (if any)
    /// @return ETHPrice Current ETH price with maximum precision (scaled by 10^22)
    /// @return secondsFromPreviousMintreturn Time elapsed since last mint operation
    /// @custom:simulation Provides preview of mining results without state changes
    /// @custom:difficulty-aware Adjusts calculations based on proximity to difficulty adjustment
    /// @custom:price-floor Enforces minimum ETH price per token (minAmountETH)
    /// @custom:overflow-safe Uses safe arithmetic to prevent overflow in difficulty calculations
    function TotalTotalsAndETHpriceAndCurrentMintTime(uint compensation) 
        public 
        view
        returns (
            uint B0xYouGet, 
            uint ETHYouGet, 
            uint ETHyouSpend, 
            uint ETHPrice, 
            uint secondsFromPreviousMintreturn
        ) {
        uint secondsFromPreviousMint = block.timestamp - previousBlockTime; 
        secondsFromPreviousMintreturn = secondsFromPreviousMint;
        ETHPrice = getETHPricePrecise();
        ( B0xYouGet, ETHYouGet, ETHyouSpend) = TotalForContract(compensation, blocksToReadjust());
    }
    
    
    
    /// @notice Calculates comprehensive mining results including B0x tokens, ETH flows, and current ETH price
    /// @dev Simulates mining operation results without executing the actual mining transaction, at current previousblockTime
    /// @dev Handles both regular mining and difficulty adjustment scenarios with different calculations
    /// @param compensation The mining compensation multiplier based on solution quality
    /// @param blocksToReadjustMENT BlocksToReadjustment
    /// @return B0xYouGet Amount of B0x tokens the miner would receive
    /// @return ETHYouGet Amount of ETH the miner would receive (if any)
    /// @return ETHyouSpend Amount of ETH the miner would need to send (if any)
    /// @custom:simulation Provides preview of mining results without state changes
    /// @custom:difficulty-aware Adjusts calculations based on proximity to difficulty adjustment
    /// @custom:price-floor Enforces minimum ETH price per token (minAmountETH)
    /// @custom:overflow-safe Uses safe arithmetic to prevent overflow in difficulty calculations
    function TotalForContract(uint compensation, uint blocksToReadjustMENT) 
        public 
        view
        returns (
            uint B0xYouGet, 
            uint ETHYouGet, 
            uint ETHyouSpend
        ) {
        uint miningDiffz = getMiningDifficulty();
        uint blkzToAdjustment = blocksToReadjustMENT;
        uint secondsFromPreviousMint = block.timestamp - previousBlockTime;


        // Prevent division by zero
        require(compensation > 0, "Compensation must be greater than 0");
        
        uint totalETH_To_Send_User = compensation * totalETHtoSendUserAtTime(secondsFromPreviousMint / compensation);
        uint miningTargetCloseToAdjustment = miningTarget;
        
        if (compensation >= blkzToAdjustment) {
            uint SecPer1Compensation = (block.timestamp - previousBlockTime) / (blkzToAdjustment);
            
            if(targetTime < SecPer1Compensation) {
                uint timeMultiplier = SecPer1Compensation / (targetTime / 2);
                uint targetDivisor = targetTime / (targetTime / 2);
                
                // First check if result would exceed 2^253
                uint MAX_SAFE_VALUE = 1 << 253; // 2^253
                miningTargetCloseToAdjustment = 0;
                
                // Check if miningTarget * timeMultiplier would overflow
                if (timeMultiplier > MAX_SAFE_VALUE / miningTarget) {
                    // Would overflow, use maximum safe value
                    miningTargetCloseToAdjustment = MAX_SAFE_VALUE;
                } else {
                    // Safe to calculate
                    uint256 product = miningTarget * timeMultiplier;
                    miningTargetCloseToAdjustment = product / targetDivisor;
                }
            }

            uint miningDiffForAdjustment = _MAXIMUM_TARGET.div(miningTargetCloseToAdjustment);

            B0xYouGet = totalB0xToSendAtTime(secondsFromPreviousMint / blkzToAdjustment, 1);
            ETHyouSpend = totalETHowedAtTime(secondsFromPreviousMint / blkzToAdjustment, miningDiffForAdjustment, 1);

            B0xYouGet = B0xYouGet + (blkzToAdjustment - 1) * totalB0xToSendAtTime(secondsFromPreviousMint / blkzToAdjustment, blkzToAdjustment);
            ETHyouSpend = ETHyouSpend + (blkzToAdjustment - 1) * totalETHowedAtTime(secondsFromPreviousMint / blkzToAdjustment, miningDiffz, blkzToAdjustment);
            
            if (B0xYouGet != 0) {
                uint local_minAmountETH = (ETHyouSpend * 1e18) / B0xYouGet;
                if (local_minAmountETH < minAmountETH) {
                    ETHyouSpend = (minAmountETH * B0xYouGet) / 1e18;
                }
            }
        
        } else {
            B0xYouGet = compensation * totalB0xToSendAtTime(secondsFromPreviousMint / compensation, compensation);
            ETHYouGet = compensation * totalETHtoSendUserAtTime(secondsFromPreviousMint / compensation);
            ETHyouSpend = compensation * totalETHowedAtTime(secondsFromPreviousMint / compensation, miningDiffz, compensation);

            if (B0xYouGet != 0) {
                uint local_minAmountETH = (ETHyouSpend * 1e18) / B0xYouGet;
                if (local_minAmountETH < minAmountETH) {
                    ETHyouSpend = (minAmountETH * B0xYouGet) / 1e18;
                }
            }
        }
        
    }
    
    
    
    
    /// @notice Calculates the total B0x tokens to reward a miner based on timing and adjustment context
    /// @dev Determines token reward amount using current reward era and timing-based scaling
    /// @dev Provides the core token reward calculation for successful mining operations
    /// @param secondsFromPreviousMint Time elapsed since last mining operation in seconds
    /// @param blocksToAdjust Number of blocks remaining until next difficulty adjustment
    /// @return totalB0xToSendToUser The amount of B0x tokens to reward the miner
    /// @custom:reward-era Uses current rewardEra to determine base reward amount (50 / 2^rewardEra)
    /// @custom:timing-based Reward amount may scale based on time elapsed since previous mint
    /// @custom:adjustment-context Uses blocksToAdjust for reward calculation context
    /// @custom:halving-compatible Works with Bitcoin-style reward halving mechanism
    function totalB0xToSendAtTime(uint secondsFromPreviousMint, uint blocksToAdjust) public view returns (uint totalB0xToSendToUser) {
        totalB0xToSendToUser = reward_amount;
        // Calculate adjustment factor (using 1000 as fixed point multiplier)
        uint256 adjustmentFactor = (secondsFromPreviousMint * 1000) / targetTime;
        
        if  (blocksToAdjust != 1 && adjustmentFactor > 1000) {
            adjustmentFactor = 1000;  // Cap at at 1x normal fees 
        }else if (adjustmentFactor < 250){
            adjustmentFactor = 250;
        }else if ( blocksToAdjust == 1 && adjustmentFactor > 2000){ //max 2x unless targertTimezMulti =>4 then up to 16x
            uint TimeSinceLastDifficultyPeriod2 = block.timestamp - latestDifficultyPeriodStarted2 + 1;
        	uint epochTotal = (epochCount) - epochOld; //calculated after startNewMiningEpoch
        	if(epochTotal == 0){
        		epochTotal = epochTotal + 1;
        	}
        	uint totalTimePerEpoch = TimeSinceLastDifficultyPeriod2 / epochTotal;
        	uint targetTimezMulti = totalTimePerEpoch / targetTime;
        	
        	if(targetTimezMulti < 4){
	      	    adjustmentFactor = 2000;
         	}else if(adjustmentFactor > 4000 && targetTimezMulti >= 4){
	     	    adjustmentFactor = 4000;
		}
        }
        totalB0xToSendToUser = (totalB0xToSendToUser*adjustmentFactor )/ 1000;

    }
	
	
    /// @notice Adjusts ETH payment required from miners based on mining difficulty
    /// @dev Uses 0xBTC difficulty standards with 524,288 normalization factor
    /// @dev Implements anti-FPGA measures by requiring higher ETH payments at higher difficulties
    /// @param reward The base ETH payment amount that needs adjustment
    /// @param difficulty The current mining difficulty (0xBTC standard)
    /// @return uint256 The adjusted ETH amount that miners must send
    /// @custom:scaling Uses bit shifting for gas-efficient multiplication/division operations
    /// @custom:anti-fpga Higher ETH payments required at higher difficulties to discourage FPGA farming
    /// @custom:difficulty-tiers Progressive scaling from reduced payments at low difficulty to high payments at extreme difficulty
    /// @custom:economic-barrier Higher difficulties require more ETH payment, lower difficulties require less
    function adjustETHtoSendByDifficulty(uint256 reward, uint256 difficulty) internal pure returns (uint256) {
        // 524_288 divide by this because we are using 0xBTC difficulty standards
        // 3.2 Million = 31 Gh/s
        // 3 million = 1 FPGA so make it best since we dont want FPGA make this the best era
        
        if (difficulty < 1) return reward >> 8;                    // divide by 256 (much less payment required)
        if (difficulty < 2) return reward >> 7;                    // divide by 128 (less payment required)
        if (difficulty < 10) return reward >> 6;                   // divide by 64 (less payment required)
        if (difficulty < 100) return reward >> 5;                  // divide by 32 (less payment required)
        if (difficulty < 1000) return reward >> 4;                 // divide by 16 (less payment required)
        if (difficulty < 25_000) return reward >> 3;               // divide by 8 (less payment required)
        if (difficulty < 50_000) return reward >> 2;               // divide by 4 (less payment required)
        if (difficulty < 125_000) return reward >> 1;              // divide by 2 (less payment required)
        if (difficulty < 250_000) return reward * 1/2;             // multiply by 1/2 (less payment required)
        if (difficulty < 500_000) return (reward * 2) / 3;         // multiply by 2/3 (less payment required)
        if (difficulty < 1_000_000) return reward;                 // base payment amount
        if (difficulty < 3_000_000) return (reward * 3) / 2;       // multiply by 3/2 (50% more payment required)
        if (difficulty < 10_000_000) return reward << 1;           // multiply by 2 (2x more payment required)
        if (difficulty < 20_000_000) return reward << 2;           // multiply by 4 (4x more payment required)
        if (difficulty < 50_000_000) return reward << 3;           // multiply by 8 (8x more payment required)
        if (difficulty < 100_000_000) return reward << 4;          // multiply by 16 (16x more payment required)
        if (difficulty < 250_000_000) return reward << 5;          // multiply by 32 (32x more payment required)
        if (difficulty < 500_000_000) return reward << 6;          // multiply by 64 (64x more payment required)
        if (difficulty < 1_000_000_000) return reward << 7;        // multiply by 128 (128x more payment required) // 8.65 Th/s or 8650 Gh/s or 330 FPGAs or at 5000$ 6.4$ for rewardAmount minimum or 6.4*4 = 25.6$ for rewardAmount/4
        if (difficulty < 2_000_000_000) return reward << 8;        // multiply by 256 (256x more payment required)
        if (difficulty < 3_000_000_000) return reward << 9;        // multiply by 512 (512x more payment required)
        if (difficulty < 5_000_000_000) return reward << 10;       // multiply by 1024 (1024x more payment required)
        
        return reward * (difficulty / 5_000_000);                  // dynamic multiplier for extreme difficulties
    }


    /// @notice Calculates the total ETH amount a miner must send based on mining parameters
    /// @dev Combines time-based calculation with difficulty-based adjustment to determine ETH payment
    /// @dev Uses both timing penalties and difficulty scaling to calculate required ETH payment
    /// @param secondsFromPreviousMint Time elapsed since last mining operation in seconds
    /// @param miningDiff Current mining difficulty (0xBTC standard, ~difficulty/524,288)
    /// @param blocksToAdjust Number of blocks remaining until next difficulty adjustment
    /// @return totalETHNeeded The total ETH amount the miner must send with their transaction
    /// @custom:time-based Uses secondsFromPreviousMint to calculate base ETH amount owed
    /// @custom:difficulty-scaling Applies adjustETHtoSendByDifficulty() to scale payment by mining difficulty
    /// @custom:economic-balance Higher difficulty = higher payment, longer time = higher payment
    /// @custom:anti-fpga Higher difficulties require exponentially more ETH to discourage industrial mining
    function totalETHowedAtTime(uint secondsFromPreviousMint, uint miningDiff, uint blocksToAdjust) public view returns (uint totalETHNeeded) {
        uint ETHtoSendContract = 0.00001 ether; //0.00001 ETH = 0.045$ the avg expected cost of Layer 2 tx in the future.

        //524_288 difference between uint public  MAXIMUMTARGET = 2**234; and my new maximum target is uint public constant _MAXIMUM_TARGET = 2**253; 2^19 = 524288
        uint ETHuserMUSTsendContract = adjustETHtoSendByDifficulty(ETHtoSendContract, miningDiff / 524_288);

        
        // Calculate adjustment factor (using 1000 as fixed point multiplier)
        uint256   adjustmentFactor = 4000;  
        if(secondsFromPreviousMint != 0){

                adjustmentFactor = (targetTime * 1000) / secondsFromPreviousMint;  
        }
        
        if (adjustmentFactor > 4000 ) {
            adjustmentFactor = 4000;  // Cap at 4x as much ETH
        }

        //zkBTC terms of difficulty must adjust by dividing by 524_288
        if(adjustmentFactor < 1000 && blocksToAdjust != 1) {
            adjustmentFactor = 1000;   // Cap at 4x less eth (1000/4 = 250)
        }else if( blocksToAdjust == 1 && adjustmentFactor < 500){// cap at 2x unless Target Time >= 4x
            uint TimeSinceLastDifficultyPeriod2 = block.timestamp - latestDifficultyPeriodStarted2 + 1;
        	uint epochTotal = epochCount - epochOld;
        	if(epochTotal == 0){
        		epochTotal = 1;
        	}
        
        
        	uint totalTimePerEpoch = TimeSinceLastDifficultyPeriod2 / epochTotal;
        	uint targetTimezMulti = totalTimePerEpoch / targetTime;
                
            if(targetTimezMulti < 4 && adjustmentFactor < 500){
                adjustmentFactor = 500; // 1000/2= 125   so 8x less ETH needed max if not adjustment factored
            }else if(adjustmentFactor < 250 && targetTimezMulti >= 4){
                adjustmentFactor = 250; // 1000/33.30= 30   so 33.3x less ETH needed max
            }
        }
        
        //If Its 4x Faster charge 4x More, if its 4x Slower charge 4x less
        totalETHNeeded = (ETHuserMUSTsendContract * adjustmentFactor) / 1000;
        return totalETHNeeded;

    }


    /// @notice Advanced mining function that distributes multiple token types based on epoch-based unlock system
    /// @dev Performs standard mining while also distributing accumulated tokens from contract's inventory
    /// @dev Uses epoch-based power-of-2 unlocking system (epoch 2=1 token, epoch 4=2 tokens, epoch 8=3 tokens, etc.)
    /// @param nonce Array of valid nonces for mining solutions
    /// @param ExtraFunds Array of token contract addresses to distribute (must not include main B0x token)
    /// @param MintTo Array of recipient addresses (length must be ExtraFunds.length + 1, first is for main rewards)
    /// @param maxNumberOfSolutions Maximum number of mining solutions to process
    /// @param minBlockTimeDifferencePerSolve Minimum time difference required per solution
    /// @return owed The total amount owed based on mining time calculations
    /// @custom:epoch-unlocking Tokens unlock based on epoch count divisibility by powers of 2
    /// @custom:distribution-logic epoch % 2^(n+1) == 0 determines which tokens get distributed
    /// @custom:array-relationship MintTo.length must equal ExtraFunds.length + 1 (first address gets main rewards)
    /// @custom:token-validation Prevents minting of the main B0x token through ExtraFunds array
    /// @custom:batch-transfers Accumulates all transfers and executes them at once for gas efficiency
    function mintTokensArrayTo(
        uint256[] memory nonce, 
        address[] memory ExtraFunds, 
        address[] memory MintTo, 
        uint maxNumberOfSolutions,  
        uint minBlockTimeDifferencePerSolve
    ) public payable returns (uint256 owed) {
        // MintTo is 1+ExtraFunds.length so always 1 more than ExtraFunds is MintTo, because first mintTo is for the main rewards.
        // Nonce is an array of uint256 nonces that are valid, it will try all
        
        uint prevBlockTimez = previousBlockTime;
        uint NumberofMints = multi_MintTo(MintTo[0], nonce, maxNumberOfSolutions, minBlockTimeDifferencePerSolve);
        uint totalOd = totalOwedAtTime(((block.timestamp - prevBlockTimez) / NumberofMints));
        uint local_epochCount = epochCount;
        uint MAXmaxMax = 0;
        
        if(totalOd == 0) {
            return 0;
        }
        
        require(MintTo.length == ExtraFunds.length + 1, "MintTo has to have an extra address compared to ExtraFunds");
        
        address B0x = B0x_Mining_TOKEN_ADDRESS;
        uint xy = 0;
        uint256[] memory balances = new uint256[](ExtraFunds.length);
        
        // Validate that ExtraFunds doesn't contain the main B0x token
        for(uint z = 0; z < ExtraFunds.length; z++) {
            require(ExtraFunds[z] != B0x, "Not allowed to ERC20 mint Main Token");
        }
        
        // Process each mint and calculate token distributions
        for(uint xzzzz = 0; xzzzz < NumberofMints; xzzzz++) {
            // Determine how many tokens are unlocked for this epoch
            for(xy = 0; xy < ExtraFunds.length; xy++) {
                if(local_epochCount % (2**(xy + 1)) != 0) {
                    break;
                }
                // Validate no duplicate tokens in the array
                for(uint y = xy + 1; y < ExtraFunds.length; y++) {
                    require(ExtraFunds[y] != ExtraFunds[xy], "No printing The same tokens");
                }
            }
            
            if(xy == 0) {
                continue;
            }
            
            if(MAXmaxMax < xy) {
                MAXmaxMax = xy;
            }
            
            uint256 totalOwed = 0;
            uint256 TotalOwned = 0;
            
            // Calculate and accumulate token distributions
            for(uint x = 0; x < xy && x < ExtraFunds.length; x++) {
                // Epoch count must be evenly divisible by 2^n in order to get extra mints
                // ex. epoch 2 = 1 extramint, epoch 4 = 2 extra, epoch 8 = 3 extra mints, ..., epoch 32 = 5 extra mints
                if(local_epochCount % (2**(x + 1)) == 0) {
                    address tokenAddress = ExtraFunds[x];
                    
                    // Use low-level call to get token balance
                    (bool success, bytes memory data) = tokenAddress.staticcall(
                        abi.encodeWithSignature("balanceOf(address)", address(this))
                    );
                    
                    if (success && data.length >= 32) {
                        TotalOwned = abi.decode(data, (uint256));
                    } else {
                        TotalOwned = 0;
                    }
                    
                    if(TotalOwned != 0) {
                        // Special rounding for certain conditions
                        if(x % 3 == 0 && x != 0 && totalOd > 17600000) {
                            totalOwed = (TotalOwned * totalOd).divRound(2**x * 100000000 * 20000);
                        } else {
                            totalOwed = (TotalOwned * totalOd).div(2**x * 100000000 * 20000);
                        }
                        balances[x] = balances[x] + totalOwed;
                    }
                }
            }
            
            local_epochCount = local_epochCount - 1;
        }
        
        // Execute all accumulated transfers at once
        for(uint i = 0; i < MAXmaxMax && i < ExtraFunds.length; i++) {
            address tokenAddress = ExtraFunds[i];
            uint256 amount = balances[i];
            
            if(amount > 0) {
                IERC20(tokenAddress).transfer(AddressLPReward, amount);
                IERC20(tokenAddress).transfer(MintTo[i + 1], amount);
            }
        }
        
        emit MegaMint(msg.sender, epochCount, challengeNumber, MAXmaxMax, totalOd);
        return totalOd;
    }
    
    
    /// @notice Convenience wrapper for mintTokensArrayTo that sends all tokens to the same recipient
    /// @dev Creates an array of identical addresses and delegates to mintTokensArrayTo for processing
    /// @dev Simplifies multi-token mining when all rewards should go to a single address
    /// @param nonce Array of valid nonces for mining solutions
    /// @param ExtraFunds Array of token contract addresses to distribute (including main B0x token)
    /// @param MintTo Single recipient address that will receive all token rewards
    /// @param MaxAnswersInOneSubmit Maximum number of mining solutions to process
    /// @param minBlockTimeDifferencePerSolve Minimum time difference required per solution
    /// @return success Always returns true if the operation completes without reverting
    /// @custom:convenience-wrapper Eliminates need to manually create recipient address arrays
    /// @custom:single-recipient All token rewards (main + extra) go to the same address
    /// @custom:array-creation Dynamically creates MintTo array with length ExtraFunds.length + 1
    /// @custom:delegation Forwards all actual processing to mintTokensArrayTo function
    function mintTokensSameAddress(
        uint256[] memory nonce, 
        address[] memory ExtraFunds, 
        address MintTo, 
        uint MaxAnswersInOneSubmit, 
        uint minBlockTimeDifferencePerSolve
    ) public payable returns (bool success) {
        // MintTo is 1+ExtraFunds.length so always 1 more than ExtraFunds is MintTo, because first mintTo is for the main rewards.
        
        address[] memory dd = new address[](ExtraFunds.length + 1); 
        
        for(uint x = 0; x < (ExtraFunds.length + 1); x++) {
            dd[x] = MintTo;
        }
        
        mintTokensArrayTo(nonce, ExtraFunds, dd, MaxAnswersInOneSubmit, minBlockTimeDifferencePerSolve);
        return true;
    }


    /// @notice Returns the time elapsed since the last successful mining operation
    /// @dev Simple utility function for calculating time differences in mining operations
    /// @return time Time in seconds since previousBlockTime
    function timeFromLastSolve() public view returns (uint256 time) {
        time = block.timestamp - previousBlockTime;
        return time;
    }


    function rewardAtTimeERC20(uint256 timeDifference, address[] memory tokens, uint epochCountStart, uint epochCountEnd) public view returns (uint256[] memory) {
        uint numberOfMints = epochCountEnd - epochCountStart;
        uint totalOwed = totalOwedAtTime(((timeDifference) / numberOfMints));
        
        uint256 TotalOwned;
        uint256[] memory balances = new uint256[](tokens.length);
                    // Validate no duplicate tokens

        for(uint xy =0; xy< tokens.length; xy++){
            
            for(uint y = xy + 1; y < tokens.length; y++) {
                require(tokens[y] != tokens[xy], "No same tokens");
            }
        }
        // Process each mint operation
        for(uint f = 0; f < numberOfMints; f++) {
            for(uint z = 0; z < tokens.length; z++) {
                uint totalToSend = 0;
                
                // Epoch count must be evenly divisible by 2^n in order to get extra mints
                // ex. epoch 2 = 1 extramint, epoch 4 = 2 extra, epoch 8 = 3 extra mints, epoch 16 = 4 extra mints
                if((epochCountEnd - f) % (2**(z + 1)) == 0) {
                    TotalOwned = IERC20(tokens[z]).balanceOf(address(this));
                    
                    if(TotalOwned != 0) {
                        // Special rounding for certain conditions (every 3rd token with high totalOwed)
                        if(z % 3 == 0 && z != 0 && totalOwed > 17600000) {
                            totalToSend = ((2** rewardEra) * TotalOwned * totalOwed).divRound(2**z * 100000000 * 20000);
                        } else {
                            totalToSend = ((2** rewardEra) * TotalOwned * totalOwed).div(2**z * 100000000 * 20000);
                        }
                        
                        balances[z] = balances[z] + totalToSend;
                    }
                }
            }
        }
        
        return balances;
    }

    
    /// @notice Returns the number of blocks mined since the last difficulty adjustment
    /// @dev Simple calculation of blocks completed in current difficulty period
    /// @return blocks Number of epochs mined since last difficulty readjustment
    function blocksFromReadjust() public view returns (uint256 blocks) {
        blocks = (epochCount - epochOld);
        return blocks;
    }
    
    /// @notice Calculates how many blocks remain until the next difficulty adjustment
    /// @dev Complex logic that can trigger early adjustments based on timing and block count conditions
    /// @dev Uses multiple factors: time elapsed, blocks mined, and performance thresholds
    /// @return blocks Number of blocks remaining until difficulty adjustment (1 if conditions met for immediate adjustment)
    /// @custom:early-adjustment Can return 1 block when timing/performance conditions are met
    /// @custom:timing-based Uses 4x target time threshold and minimum block count for early adjustment
    /// @custom:performance-gate Requires at least _BLOCKS_PER_READJUSTMENT/8 blocks for early adjustment
    /// @custom:standard-calculation Returns normal remainder calculation when early conditions not met
    function blocksToReadjust() public view returns (uint blocks) {
        uint256 blktimestamp = block.timestamp;
        uint local_BLOCKS_PER_READJUSTMENT = _BLOCKS_PER_READJUSTMENT;
        uint localEpochCount = epochCount;
        uint localEpochOld = epochOld;
        
        uint TimeSinceLastDifficultyPeriod2 = blktimestamp - latestDifficultyPeriodStarted2;
        uint adjusDiffTargetTime = targetTime * (localEpochCount - localEpochOld);
        uint adjusDiffTime = targetTime * local_BLOCKS_PER_READJUSTMENT;
        uint adjustFinal = 4 * adjusDiffTargetTime;
        uint epochCOUNTS = localEpochCount - localEpochOld;
        
        // If we are 256 blocks (2016/(4*2) = 256) AND at least average 1.5x slowtime on blocks adjust 
        // OR if we are past our Difficulty period (aka slow mining)
        if((TimeSinceLastDifficultyPeriod2 > adjustFinal && epochCOUNTS > local_BLOCKS_PER_READJUSTMENT / (8)) || 
           (adjusDiffTime < TimeSinceLastDifficultyPeriod2)) {
            // Complicated math not needed if only moving 1 block
            blocks = 1;
            return (blocks);
        } else {
            blocks = local_BLOCKS_PER_READJUSTMENT - ((localEpochCount - localEpochOld) % local_BLOCKS_PER_READJUSTMENT);
            return (blocks);
        }
    }

    
    /// @notice Calculates the time in seconds until difficulty adjustment conditions will be met
    /// @dev Mirrors the logic from blocksToReadjust() to determine when adjustment switch will occur
    /// @dev Returns 0 if adjustment conditions are already met (blocksToReadjust() would return 1)
    /// @return secs Time in seconds until adjustment conditions trigger, or 0 if already triggered
    /// @custom:condition-matching Exactly mirrors the dual condition logic from blocksbToReadjust()
    /// @custom:timing-prediction Calculates when either slow mining or 4x time conditions will be met
    /// @custom:block-threshold Considers minimum block requirement (252 blocks) for timing-based adjustment
    /// @custom:immediate-check Returns 0 if adjustment conditions are already satisfied
    function seconds_Until_adjustmentSwitch() public view returns (uint secs) {
        uint256 blktimestamp = block.timestamp;
        uint256 local_BLOCKS_PER_READJUSTMENT = _BLOCKS_PER_READJUSTMENT;
        uint256 localEpochCount = epochCount;
        uint256 localEpochOld = epochOld;
        uint256 TimeSinceLastDifficultyPeriod2 = blktimestamp - latestDifficultyPeriodStarted2;
        uint256 epochCOUNTS = localEpochCount - localEpochOld;
        uint256 adjusDiffTime = targetTime * local_BLOCKS_PER_READJUSTMENT;
        
        // Make this calculation match blocksToReadjust() exactly
        uint256 adjusDiffTargetTime = targetTime * epochCOUNTS;
        uint256 adjustFinal = 4 * adjusDiffTargetTime;
        uint256 minBlocksRequired = local_BLOCKS_PER_READJUSTMENT / (8);
        
        // Check if we're already in adjustment mode (blocks = 1)
        if ((TimeSinceLastDifficultyPeriod2 > adjustFinal && epochCOUNTS > minBlocksRequired) ||
            (adjusDiffTime < TimeSinceLastDifficultyPeriod2)) {
            return 0; // Already in adjustment mode
        }
        
        // Calculate time until we hit the adjustment conditions
        // Time until we hit the "slow mining" condition
        int timeUntilSlowCondition = int(latestDifficultyPeriodStarted2) + int(adjusDiffTime) - int(blktimestamp);
        
        // Time until we hit the "1.5x slow time" condition - only relevant if we have enough blocks
        int minTime = timeUntilSlowCondition;
        
        if (epochCOUNTS > minBlocksRequired) {
            int timeUntilSlowTimeCondition = int(latestDifficultyPeriodStarted2) + int(adjustFinal) - int(blktimestamp);
            // Only consider this condition if we have enough blocks
            if (timeUntilSlowTimeCondition > 0 && (timeUntilSlowTimeCondition < minTime || minTime <= 0)) {
                minTime = timeUntilSlowTimeCondition;
            }
        }
        // If epochCOUNTS <= minBlocksRequired, we only care about timeUntilSlowCondition
        
        if (minTime <= 0) {
            return 0;
        }
        
        return uint(minTime);
    }


    /// @notice Initiates a new mining epoch and handles difficulty adjustments when conditions are met
    /// @dev Internal function that manages epoch transitions, reward distribution, and challenge generation
    /// @dev Triggers difficulty adjustment and reward distribution when full epoch completed
    /// @param blocksToAdjust Number of blocks remaining until next difficulty adjustment
    /// @param blocksMined Number of blocks successfully mined in this operation
    /// @custom:epoch-completion Triggers full adjustment cycle when blocksMined >= blocksToAdjust
    /// @custom:quarter-milestones Sends rewards to Liquidity Providers at 25%, 50%, and 75% completion points of difficulty period
    /// @custom:challenge-generation Creates new challenges using previous block hash and current challenge
    /// @custom:usage-limits Prevents challenge reuse with maximum 3 uses per base challenge
    function _startNewMiningEpoch(uint blocksToAdjust, uint blocksMined) internal {
        uint local_BLOCKS_PER_READJUSTMENT = _BLOCKS_PER_READJUSTMENT;
        uint nextEpoch = blocksToAdjust;
        uint epochsz = blocksMined;
        uint localEpochCount = epochCount;
        uint blocksToReadjust_local = nextEpoch;
        
        if(epochsz >= blocksToReadjust_local) {
            epochsz = blocksToReadjust_local;
            epochCount = localEpochCount.add(epochsz);
            
            if(_maxTotalSupply < tokensMinted) {
                reward_amount = 0;
            }
            
            ARewardSender();
            _reAdjustDifficulty();
            
            bytes32 localChallenge2 = blockhash(block.number - 1);
            bytes32 localChallenge_advanced = bytes32(keccak256(abi.encodePacked(localChallenge2, challengeNumber)));
            require(usedChallenges[localChallenge_advanced] == false, "used Chal before");
            usedChallenges[localChallenge_advanced] = true;
            challengeNumber = localChallenge_advanced;

            uint maxAmountOfChallengeUses = usedChallengesNumber[localChallenge2] + 1;
            usedChallengesNumber[localChallenge2] = maxAmountOfChallengeUses;
            require(maxAmountOfChallengeUses <= 3, "Max 3 times");
        } else {
            // Check if we've crossed a quarter milestone
            // Calculate how many blocks we've mined so far in this readjustment period
            uint blocksSoFar = local_BLOCKS_PER_READJUSTMENT - blocksToReadjust_local + epochsz;
            
            // Calculate quarter milestones
            uint quarter1 = local_BLOCKS_PER_READJUSTMENT / 4;
            uint quarter2 = local_BLOCKS_PER_READJUSTMENT / 2;
            uint quarter3 = (local_BLOCKS_PER_READJUSTMENT * 3) / 4;
            
            // Check if we've just crossed a quarter milestone
            uint blocksBeforeThisMining = blocksSoFar - epochsz;
            
            epochCount = localEpochCount.add(epochsz);

            if ((blocksBeforeThisMining < quarter1 && blocksSoFar >= quarter1) ||
                (blocksBeforeThisMining < quarter2 && blocksSoFar >= quarter2) ||
                (blocksBeforeThisMining < quarter3 && blocksSoFar >= quarter3)) {
                ARewardSender();
            }
        }
    }

    /// @notice Adjusts mining difficulty based on time taken to mine recent blocks
    /// @dev Internal function that implements Bitcoin-style difficulty adjustment with 4x caps
    /// @dev Uses actual time elapsed vs target time to calculate adjustment factor
    /// @custom:bitcoin-style Implements 4x maximum adjustment in either direction per period
    /// @custom:time-based Uses elapsed time vs target time to determine if mining is too fast/slow
    /// @custom:overflow-protection Uses mulDiv for safe arithmetic and prevents target overflow
    /// @custom:bounds-enforcement Ensures mining target stays within _MINIMUM_TARGET and _MAXIMUM_TARGET
    function _reAdjustDifficulty() internal {
        uint256 blktimestamp = block.timestamp;
        uint TimeSinceLastDifficultyPeriod2 = blktimestamp - latestDifficultyPeriodStarted2+1;
        uint epochTotal = epochCount - epochOld;
        uint adjusDiffTargetTime = targetTime * epochTotal; 
        epochOld = epochCount;
        
        // Calculate adjustment factor (using 1000 as fixed point multiplier)
        uint256 adjustmentFactor = (TimeSinceLastDifficultyPeriod2 * 1000) / adjusDiffTargetTime;
        
        // Apply Bitcoin's 4x cap in both directions
        if (adjustmentFactor > 4000) {
            adjustmentFactor = 4000;  // Cap at 4x easier
        }
        if (adjustmentFactor < 250) {
            adjustmentFactor = 250;   // Cap at 4x harder (1000/4 = 250)
        }

        // Check if the result would exceed uint256 max
        // Rearrange: (miningTarget * adjustmentFactor) / 1000 <= type(uint256).max
        // To: miningTarget * adjustmentFactor <= type(uint256).max * 1000
        // To: miningTarget <= (type(uint256).max * 1000) / adjustmentFactor
        uint256 maxAllowedMiningTarget = mulDiv(_MAXIMUM_TARGET, 1000, adjustmentFactor);

        if (miningTarget > maxAllowedMiningTarget) {
            miningTarget = _MAXIMUM_TARGET; // Handle overflow by using maximum target
        } else {
            miningTarget = mulDiv(miningTarget, adjustmentFactor, 1000);
        }
        
        // Apply the adjustment to the target
        // If blocks are coming in 4x slower (adjustmentFactor = 4000), make it 4x easier
        // If blocks are coming in 4x faster (adjustmentFactor = 250), make it 4x harder
        
        require(latestDifficultyPeriodStarted2 != blktimestamp, "No same block");
        latestDifficultyPeriodStarted2 = blktimestamp;
        latestDifficultyPeriodStarted = block.number;
        
        if(miningTarget < _MINIMUM_TARGET) { // Very difficult
            miningTarget = _MINIMUM_TARGET;
        }
        if(miningTarget > _MAXIMUM_TARGET) { // Very easy
            miningTarget = _MAXIMUM_TARGET;
        }
    }
    
    /// @notice Calculates what the mining difficulty would be after the next adjustment
    /// @dev Simulates the difficulty adjustment calculation without actually changing state
    /// @dev Uses current time + 1 second and epochCount + 1 to predict next adjustment
    /// @return newDifficulty The predicted difficulty value after next adjustment
    /// @custom:prediction-logic Simulates _reAdjustDifficulty() calculation with incremented values
    /// @custom:bitcoin-caps Applies same 4x maximum adjustment limits as actual adjustment
    /// @custom:time-simulation Adds 1 second to current time and 1 to epoch count for prediction
    /// @custom:bounds-checking Enforces same minimum and maximum target limits
    function readjustsToWhatDifficulty() public view returns (uint newDifficulty) {
        uint256 blktimestamp = block.timestamp;
        uint TimeSinceLastDifficultyPeriod2 = blktimestamp - latestDifficultyPeriodStarted2 + 1;
        uint epochTotal = epochCount - epochOld;
        if(epochTotal == 0){
        	epochTotal = 1;
        }
        uint adjusDiffTargetTime = targetTime * epochTotal; 
        
        // Calculate adjustment factor (using 1000 as fixed point multiplier)
        uint256 adjustmentFactor = (TimeSinceLastDifficultyPeriod2 * 1000) / adjusDiffTargetTime;
        uint miningTarget2 = miningTarget;
        
        // Apply Bitcoin's 4x cap in both directions
        if (adjustmentFactor > 4000) {
            adjustmentFactor = 4000;  // Cap at 4x easier
        }
        if (adjustmentFactor < 250) {
            adjustmentFactor = 250;   // Cap at 4x harder (1000/4 = 250)
        }

         // Check if the result would exceed uint256 max
        // Rearrange: (miningTarget * adjustmentFactor) / 1000 <= type(uint256).max
        // To: miningTarget * adjustmentFactor <= type(uint256).max * 1000
        // To: miningTarget <= (type(uint256).max * 1000) / adjustmentFactor
        uint256 maxAllowedMiningTarget = mulDiv(_MAXIMUM_TARGET, 1000, adjustmentFactor);

        if (miningTarget2 > maxAllowedMiningTarget) {
            miningTarget2 = _MAXIMUM_TARGET; // Handle overflow by using maximum target
        } else {
            miningTarget2 = mulDiv(miningTarget, adjustmentFactor, 1000);
        }
        
        
        if(miningTarget2 < _MINIMUM_TARGET) { // Very difficult
            miningTarget2 = _MINIMUM_TARGET;
        }
        if(miningTarget2 > _MAXIMUM_TARGET) { // Very easy
            miningTarget2 = _MAXIMUM_TARGET;
        }
        
        return _MAXIMUM_TARGET.div(miningTarget2);
    }


    /// @notice Returns comprehensive block and adjustment timing information for easy one call in miner
    /// @dev Convenience function that aggregates key mining statistics in one call
    /// @return slowBlockz Number of blocks that took longer than expected to mine
    /// @return secondsUntilAdjustmentz Time in seconds until next difficulty adjustment
    /// @return blocksFromReadjustz Number of blocks mined since last difficulty adjustment
    /// @return blocksToReadjustz Number of blocks remaining until next difficulty adjustment
    /// @custom:aggregation Combines multiple view functions for efficient data retrieval
    /// @custom:monitoring Provides complete picture of current mining performance and timing
    /// @custom:ui-friendly Single call returns all key metrics for dashboard displays
    function getBlockInfo() public view returns (
        uint slowBlockz,  
        uint secondsUntilAdjustmentz, 
        uint blocksFromReadjustz, 
        uint blocksToReadjustz
    ) {
        return (
            slowBlocks, 
            seconds_Until_adjustmentSwitch(), 
            blocksFromReadjust(), 
            blocksToReadjust()
        );
    }
    
    
    ///
    // Statistical Analysis Functions
    ///
    
    /// @notice Calculates current mining inflation metrics based on recent performance
    /// @dev Analyzes recent mining data to project yearly inflation and mining statistics
    /// @dev Returns zero values if no blocks have been mined since last adjustment
    /// @return YearlyInflation Projected total B0x tokens to be mined per year at current rate
    /// @return EpochsPerYear Projected number of epochs that would be mined in one year
    /// @return RewardsAtTime Current reward amount per epoch at current mining speed
    /// @return TimePerEpoch Average time in seconds per epoch based on recent performance
    /// @custom:performance-based Uses actual mining time data for realistic projections
    /// @custom:zero-division-safe Returns zeros if no progress made since last adjustment
    /// @custom:yearly-projection Extrapolates current performance to annual estimates
    function inflationMined() public view returns (
        uint YearlyInflation, 
        uint EpochsPerYear, 
        uint RewardsAtTime, 
        uint TimePerEpoch
    ) {
        if(epochCount - epochOld == 0) {
            return (0, 0, 0, 0);
        }
        
        uint256 blktimestamp = block.timestamp;
        uint TimeSinceLastDifficultyPeriod2 = blktimestamp - latestDifficultyPeriodStarted2;
        
        TimePerEpoch = (TimeSinceLastDifficultyPeriod2 / blocksFromReadjust()); 
        if(TimePerEpoch ==0){
            TimePerEpoch = TimePerEpoch + 1;

        }
        RewardsAtTime = totalB0xToSendAtTime(TimePerEpoch, 2); 
        
        uint year = 365 * 24 * 60 * 60;
        EpochsPerYear = year / TimePerEpoch;
        YearlyInflation = RewardsAtTime * EpochsPerYear;
        
        return (YearlyInflation, EpochsPerYear, RewardsAtTime, TimePerEpoch);
    }
    
    
    /// @notice Calculates time remaining until next reward era and daily mining metrics
    /// @dev Uses current inflation rate to project when supply cap for current era will be reached
    /// @dev Returns zero values if daily mining amount is zero (no active mining)
    /// @return daysToNextEra Number of days until current reward era ends
    /// @return maxSupplyForEraTotal Maximum token supply allowed for current reward era
    /// @return tokensMintedTotal Total tokens mined so far across all eras
    /// @return amtDaily Projected daily token mining amount at current rate
    /// @custom:era-progression Tracks progress toward reward halving events
    /// @custom:supply-cap-tracking Uses maxSupplyForEra to determine era transition timing
    /// @custom:daily-projection Converts yearly inflation to daily mining estimates
    function toNextEraDays() public view returns (
        uint daysToNextEra, 
        uint maxSupplyForEraTotal, 
        uint tokensMintedTotal, 
        uint amtDaily
    ) {
        (uint totalamt,,,) = inflationMined();
        (amtDaily) = totalamt / 365;
        
        if(amtDaily == 0) {
            return(0, 0, 0, 0);
        }
        maxSupplyForEraTotal = maxSupplyForEra;
        tokensMintedTotal = tokensMinted;
        daysToNextEra = (maxSupplyForEraTotal - tokensMintedTotal) / amtDaily;
        return (daysToNextEra, maxSupplyForEraTotal, tokensMintedTotal, amtDaily);
    }
    
    
    /// @notice Calculates epochs remaining until next reward era based on current mining performance
    /// @dev Converts daily era progression into epoch-based timeline using current epoch duration
    /// @dev Returns zero values if no mining progress has been made
    /// @return epochs Number of epochs remaining until next reward era
    /// @return epochTime Average time per epoch in seconds based on recent performance
    /// @return daysToNextEra Number of days until next reward era (from toNextEraDays)
    /// @custom:epoch-timeline Provides epoch-based perspective on era progression
    /// @custom:time-conversion Converts days to epochs using current mining performance
    /// @custom:performance-dependent Calculations based on actual recent mining speed
    function toNextEraEpochs() public view returns (
        uint epochs, 
        uint epochTime, 
        uint daysToNextEra
    ) {
        if(blocksFromReadjust() == 0) {
            return (0, 0, 0);
        }
        
        uint256 blktimestamp = block.timestamp;
        uint TimeSinceLastDifficultyPeriod2 = blktimestamp - latestDifficultyPeriodStarted2;
        uint timePerEpoch = TimeSinceLastDifficultyPeriod2 / blocksFromReadjust();
        (uint daysz,,,) = toNextEraDays();
        if(timePerEpoch ==0){
            timePerEpoch = timePerEpoch + 1;
        }
        uint amt = daysz * (60 * 60 * 24) / timePerEpoch;
        
        return (amt, timePerEpoch, daysz);
    }
    
    
    /// @notice Validates a mining solution for debugging mining software
    /// @dev Checks if provided nonce and digest are valid for the given challenge and target
    /// @param nonce The nonce value to test
    /// @param challenge_digest The expected digest result
    /// @param challenge_number The challenge to solve
    /// @param testTarget The difficulty target to test against
    /// @return success True if the digest matches and meets the target difficulty
    /// @custom:debugging Helps miners verify their solutions before submitting transactions
    /// @custom:validation Performs same hash calculation as actual mining functions
    function checkMintSolution(uint256 nonce, bytes32 challenge_digest, bytes32 challenge_number, uint testTarget) public view returns (bool success) {
        bytes32 digest = bytes32(keccak256(abi.encodePacked(challenge_number, msg.sender, nonce)));
        if(uint256(digest) > testTarget) revert();
        
        return (digest == challenge_digest);
    }
    

    /// @notice Advanced mining solution validator for debugging with custom sender address
    /// @dev Pure function that validates solutions for any sender address, useful for testing
    /// @param nonce The nonce value to test
    /// @param challenge_digest The expected digest result
    /// @param challenge_number The challenge to solve
    /// @param testTarget The difficulty target to test against
    /// @param senda The sender address to use in hash calculation
    /// @return bytes32 The computed digest for verification
    /// @custom:debugging Advanced debugging tool for mining software development
    /// @custom:pure-function No state dependencies, can test any combination of parameters
    function checkMintSolution2(uint256 nonce, bytes32 challenge_digest, bytes32 challenge_number, uint testTarget, address senda) public pure returns (bytes32) {
        bytes32 digest = bytes32(keccak256(abi.encodePacked(challenge_number, senda, nonce)));
        if(uint256(digest) > testTarget) revert();
        
        return digest;
    }


    /// @notice Returns the current mining challenge that needs to be solved
    /// @dev The challenge changes with each successful mining operation
    /// @return bytes32 Current challenge number based on recent Ethereum block hash
    function getChallengeNumber() public view returns (bytes32) {
        return challengeNumber;
    }


    /// @notice Returns the current mining difficulty (number of leading zeros required)
    /// @dev Automatically adjusts based on mining performance to maintain target block times
    /// @return uint Current difficulty calculated as _MAXIMUM_TARGET / current mining target
    function getMiningDifficulty() public view returns (uint) {
        return _MAXIMUM_TARGET.div(getMiningTarget());
    }


    /// @notice Returns the current mining target, adjusted for timing if near difficulty adjustment
    /// @dev Implements dynamic target adjustment when blocks are taking too long
    /// @return uint Current mining target (lower target = higher difficulty)
    /// @custom:dynamic-adjustment Temporarily reduces difficulty if current block is very slow
    /// @custom:timing-based Activates when blocksToReadjust() == 1 and block time exceeds target
    /// @custom:overflow-protection Uses safe arithmetic to prevent overflow in calculations
    function getMiningTarget() public view returns (uint) {
        if(blocksToReadjust() == 1) {
            uint targetTimez = targetTime;
            uint blockTimestampz = block.timestamp;
            uint previousBlkTimez = previousBlockTime;
            
            if(targetTimez < (blockTimestampz - previousBlkTimez)) {
                uint timeMultiplier = (blockTimestampz - previousBlkTimez) / (targetTimez / 2);
                uint targetDivisor = targetTimez / (targetTimez / 2);
                
                // First check if result would exceed 2^253
                uint MAX_SAFE_VALUE = 1 << 253; // 2^253
                
                // Check if miningTarget * timeMultiplier would overflow
                if (timeMultiplier > MAX_SAFE_VALUE / miningTarget) {
                    // Would overflow, use maximum safe value
                    return MAX_SAFE_VALUE;
                }

                // Safe to calculate
                uint256 product = miningTarget * timeMultiplier;
                return product / targetDivisor;
            }
        }
        
        return miningTarget;
    }


    /// @notice Returns the total number of tokens mined so far
    /// @dev Tracks cumulative token creation across all mining operations
    /// @return uint Total tokens minted since contract deployment
    function getMiningMinted() public view returns (uint) {
        return tokensMinted;
    }


    /// @notice Returns the total circulating supply of tokens
    /// @dev Currently equivalent to total mined tokens (no burns or locks)
    /// @return uint Total tokens in circulation
    function getCirculatingSupply() public view returns (uint) {
        return tokensMinted;
    }


    /// @notice Returns the current mining reward per successful block
    /// @dev Implements Bitcoin-style reward halving based on current reward era
    /// @return uint Current reward amount (50 tokens / 2^rewardEra)
    /// @custom:halving-mechanism Reward halves every era as total supply increases
    /// @custom:bitcoin-inspired Starts at 50 tokens and halves periodically
    function getMiningReward() public view returns (uint) {
        // Once we get half way thru the coins, only get 25 per block
        // Every reward era, the reward amount halves.
        return (50 * 10**18) / (2**(rewardEra));
    }


    /// @notice Returns the current epoch count (total blocks mined)
    /// @dev Increments with each successful mining operation
    /// @return uint Current epoch number
    function getEpoch() public view returns (uint) {
        return epochCount;
    }


    /// @notice Generates the mining digest for debugging purposes
    /// @dev Computes the same hash that would be used in actual mining validation
    /// @param nonce The nonce value to test
    /// @param challenge_digest The expected digest (unused but kept for interface compatibility)
    /// @param challenge_number The challenge (unused, uses current challengeNumber)
    /// @return digesttest The computed digest for the current challenge, sender, and nonce
    /// @custom:debugging Helps miners verify their hash calculations
    /// @custom:current-state Uses actual current challenge and msg.sender
    function getMintDigest(uint256 nonce, bytes32 challenge_digest, bytes32 challenge_number) public view returns (bytes32 digesttest) {
        bytes32 digest = keccak256(abi.encodePacked(challengeNumber, msg.sender, nonce));
        return digest;
    }


    /// @notice Converts a uint256 value to its string representation
    /// @dev Pure function that handles digit-by-digit conversion without external dependencies
    /// @dev Used for creating human-readable error messages with numeric values
    /// @param value The unsigned integer to convert to string format
    /// @return memory String representation of the input value
    /// @custom:efficiency Calculates digit count first, then builds string in reverse order
    /// @custom:usage Primarily used in revert messages to display required vs sent ETH amounts
    function toString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }
    
    
    /// @notice Handles calls to non-existent functions with optional data
    /// @dev Fallback function that accepts ETH payments and arbitrary call data
    fallback() external payable {
    }


    /// @notice Allows the contract to receive ETH payments directly
    /// @dev Called when ETH is sent without function call data
    receive() external payable {
    }
    

}

/*
*
* MIT License
* ===========
*
* Copyright (c) 2025 B0x Token (B0x)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.   
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*/

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

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"lp","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"epochCount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"newChallengeNumber","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"NumberOfTokensMinted","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"TokenMultipler","type":"uint256"}],"name":"MegaMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"epochCount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"newChallengeNumber","type":"bytes32"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"TransferOwnership","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"ARewardSender","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"AddressLPReward","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"B0x_Mining_TOKEN_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"Token2Per","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"compensation","type":"uint256"},{"internalType":"uint256","name":"blocksToReadjustMENT","type":"uint256"}],"name":"TotalForContract","outputs":[{"internalType":"uint256","name":"B0xYouGet","type":"uint256"},{"internalType":"uint256","name":"ETHYouGet","type":"uint256"},{"internalType":"uint256","name":"ETHyouSpend","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"compensation","type":"uint256"}],"name":"TotalTotalsAndETHpriceAndCurrentMintTime","outputs":[{"internalType":"uint256","name":"B0xYouGet","type":"uint256"},{"internalType":"uint256","name":"ETHYouGet","type":"uint256"},{"internalType":"uint256","name":"ETHyouSpend","type":"uint256"},{"internalType":"uint256","name":"ETHPrice","type":"uint256"},{"internalType":"uint256","name":"secondsFromPreviousMintreturn","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_BLOCKS_PER_READJUSTMENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_MAXIMUM_TARGET","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_MINIMUM_TARGET","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_maxTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blocksFromReadjust","outputs":[{"internalType":"uint256","name":"blocks","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blocksToReadjust","outputs":[{"internalType":"uint256","name":"blocks","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"prevBlockTime","type":"uint256"},{"internalType":"uint256","name":"NumberOfCompensation","type":"uint256"}],"name":"calcReduceDifficulty","outputs":[{"internalType":"uint256","name":"miningDifficultyReduced","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"prevBlockTime","type":"uint256"},{"internalType":"uint256","name":"NumberOfCompensation","type":"uint256"}],"name":"calcReduceTarget","outputs":[{"internalType":"uint256","name":"miningTargetReduced","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"multiplier","type":"uint256"}],"name":"calculateCompensation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"challengeNumber","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes32","name":"challenge_digest","type":"bytes32"},{"internalType":"bytes32","name":"challenge_number","type":"bytes32"},{"internalType":"uint256","name":"testTarget","type":"uint256"}],"name":"checkMintSolution","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes32","name":"challenge_digest","type":"bytes32"},{"internalType":"bytes32","name":"challenge_number","type":"bytes32"},{"internalType":"uint256","name":"testTarget","type":"uint256"},{"internalType":"address","name":"senda","type":"address"}],"name":"checkMintSolution2","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"epochCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epochOld","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBlockInfo","outputs":[{"internalType":"uint256","name":"slowBlockz","type":"uint256"},{"internalType":"uint256","name":"secondsUntilAdjustmentz","type":"uint256"},{"internalType":"uint256","name":"blocksFromReadjustz","type":"uint256"},{"internalType":"uint256","name":"blocksToReadjustz","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChallengeNumber","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCirculatingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getETHPricePrecise","outputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMiningDifficulty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMiningMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMiningReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMiningTarget","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes32","name":"challenge_digest","type":"bytes32"},{"internalType":"bytes32","name":"challenge_number","type":"bytes32"}],"name":"getMintDigest","outputs":[{"internalType":"bytes32","name":"digesttest","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"give0x","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"inflationMined","outputs":[{"internalType":"uint256","name":"YearlyInflation","type":"uint256"},{"internalType":"uint256","name":"EpochsPerYear","type":"uint256"},{"internalType":"uint256","name":"RewardsAtTime","type":"uint256"},{"internalType":"uint256","name":"TimePerEpoch","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastrun","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestDifficultyPeriodStarted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestDifficultyPeriodStarted2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"locked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"log2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"maxSupplyForEra","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"miningTarget","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes32","name":"challenge_digest","type":"bytes32"}],"name":"mint","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"nftAddresses","type":"address[]"},{"internalType":"uint256[]","name":"nftNumbers","type":"uint256[]"},{"internalType":"uint256[]","name":"nonces","type":"uint256[]"},{"internalType":"uint256","name":"maxNumberOfAnswersInMint","type":"uint256"}],"name":"mintNFT","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"nonce","type":"uint256[]"},{"internalType":"address[]","name":"ExtraFunds","type":"address[]"},{"internalType":"address[]","name":"MintTo","type":"address[]"},{"internalType":"uint256","name":"maxNumberOfSolutions","type":"uint256"},{"internalType":"uint256","name":"minBlockTimeDifferencePerSolve","type":"uint256"}],"name":"mintTokensArrayTo","outputs":[{"internalType":"uint256","name":"owed","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"nonce","type":"uint256[]"},{"internalType":"address[]","name":"ExtraFunds","type":"address[]"},{"internalType":"address","name":"MintTo","type":"address"},{"internalType":"uint256","name":"MaxAnswersInOneSubmit","type":"uint256"},{"internalType":"uint256","name":"minBlockTimeDifferencePerSolve","type":"uint256"}],"name":"mintTokensSameAddress","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"mintToAddress","type":"address"},{"internalType":"uint256[]","name":"nonce","type":"uint256[]"},{"internalType":"uint256","name":"maxAnswers","type":"uint256"},{"internalType":"uint256","name":"minPreviousBlockTimeDifference","type":"uint256"}],"name":"multi_MintTo","outputs":[{"internalType":"uint256","name":"NumberOfMintsDone","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"multipler","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oldecount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"openMining","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"previousBlockTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"readjustsToWhatDifficulty","outputs":[{"internalType":"uint256","name":"newDifficulty","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timeDifference","type":"uint256"},{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256","name":"epochCountStart","type":"uint256"},{"internalType":"uint256","name":"epochCountEnd","type":"uint256"}],"name":"rewardAtTimeERC20","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardEra","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reward_amount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"seconds_Until_adjustmentSwitch","outputs":[{"internalType":"uint256","name":"secs","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sentToLP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newDifficulty","type":"uint256"}],"name":"setDifficultyOnlyTestnet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"slowBlocks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"targetTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timeFromLastSolve","outputs":[{"internalType":"uint256","name":"time","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toNextEraDays","outputs":[{"internalType":"uint256","name":"daysToNextEra","type":"uint256"},{"internalType":"uint256","name":"maxSupplyForEraTotal","type":"uint256"},{"internalType":"uint256","name":"tokensMintedTotal","type":"uint256"},{"internalType":"uint256","name":"amtDaily","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toNextEraEpochs","outputs":[{"internalType":"uint256","name":"epochs","type":"uint256"},{"internalType":"uint256","name":"epochTime","type":"uint256"},{"internalType":"uint256","name":"daysToNextEra","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokensMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"secondsFromPreviousMint","type":"uint256"},{"internalType":"uint256","name":"blocksToAdjust","type":"uint256"}],"name":"totalB0xToSendAtTime","outputs":[{"internalType":"uint256","name":"totalB0xToSendToUser","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalETH_MintedToMiners","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"secondsFromPreviousMint","type":"uint256"},{"internalType":"uint256","name":"miningDiff","type":"uint256"},{"internalType":"uint256","name":"blocksToAdjust","type":"uint256"}],"name":"totalETHowedAtTime","outputs":[{"internalType":"uint256","name":"totalETHNeeded","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalETHtoSendUserAtCurrentTime","outputs":[{"internalType":"uint256","name":"totalETHToSendToUser","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"secondsFromPreviousMint","type":"uint256"}],"name":"totalETHtoSendUserAtTime","outputs":[{"internalType":"uint256","name":"totalETHToSendToUser","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalOwedAtCurrentTime","outputs":[{"internalType":"uint256","name":"totalOwed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"secondsFromPreviousMint","type":"uint256"}],"name":"totalOwedAtTime","outputs":[{"internalType":"uint256","name":"totalOwed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"usedChallenges","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"usedChallengesNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"usedCombinations","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60a0346101dc5760009061578b3881900390601f8201601f191683016001600160401b038111848210176101c8579180849260409485528339810103126101c457610055602061004e836101e1565b92016101e1565b3360018060a01b03198454161783557f5c486528ec3e3f0ea91181cff8116f02bfa350e03b8b6f12e00765adbb5af85c60408051858152336020820152a16001546102586002556001600160a01b031916426202a2ff1981019081116101b057608052600160ea1b60065560098490554360001981019081116101b05740936001600b55506a0d073135f91b9ea7c00000600c556000600d556a08f69750e81d45e9700000600e556000600f556a08f69750e81d45e9700000601055600060115560006012556013549260006014556000601555600060165542601755600060185560006019556000601a5542601b5560018060a01b031617600155610100600160a81b039060081b169060018060a81b03191617601355426007554360085580600a5560005260046020526040600020600160ff1982541617905560405161559590816101f68239608051818181610bfe01526111370152f35b634e487b7160e01b85526011600452602485fd5b5080fd5b634e487b7160e01b85526041600452602485fd5b600080fd5b51906001600160a01b03821682036101dc5756fe60806040526004361015610010575b005b60003560e01c8062819439146121de578063012d3edf146121c0578063035ccc44146121a257806305411d8814612183578063080ca6e2146121445780630a891b83146121285780630c179832146120f75780630c97e564146103a757806310294317146120d9578063150b7a021461208357806317da485f1461206a5780631801fbe5146116785780632381a60e1461165a578063240c3b701461161c5780632656e97f14611609578063294ce45d146115eb5780632b112e49146108e35780632d38bf7a146115cd5780632f104e0c146115a05780633179fabc1461157e57806332e997081461156357806334d5b131146115485780633730837c146115225780633c953615146115045780633dc8a068146114e657806343346f351461149f57806345d8a23214611481578063490203a7146114495780634cbf68fe1461142b5780634ef3762814610af15780634fa972e11461140d57806351736a13146110a75780635456bf1314611089578063577e9ec11461105d5780635a993ae91461103f578063646222c014610cb45780636d2bfdba14610c995780636de9f32b14610c7b57806373d21f8614610c21578063757991a814610b4d57806378e9792514610be657806381269a5614610b82578063822dec0514610b6b578063829965cc14610b4d57806387a2a9d614610b2d5780638a769d3514610b0f5780638ae0368b14610af15780638da5cb5b14610ac857806397566aa014610a7057806399f584b314610a525780639d30dffb146109cf578063a68eb88e146109b1578063b5ade81b14610994578063b83bd2bd1461090f578063bd92d4d4146108e8578063c0abebe0146108e3578063c212f073146108c5578063c4dd180c14610848578063c76ae54014610826578063c8ce67b914610742578063cb9ae70714610724578063ccadb30a14610628578063cf30901214610605578063d0856d16146105ec578063d0f66e4b146105d0578063d317140b146104aa578063da9816b614610491578063dc6e9cf914610473578063dfe95b0c14610455578063e186ca981461041a578063e38cfe1f146103f1578063e932012b146103d3578063ec11a769146103ac578063f23a6e61146103a7578063f4ec14181461037b5763f95d39190361000e5734610376576000366003190112610376576020601454604051908152f35b600080fd5b3461037657606036600319011261037657602061039f604435602435600435615071565b604051908152f35b612292565b3461037657600036600319011261037657602061039f6103ce60175442612431565b614abc565b34610376576000366003190112610376576020600754604051908152f35b34610376576000366003190112610376576001546040516001600160a01b039091168152602090f35b346103765761045161043461042e36612302565b90614bf9565b604080519384526020840192909252908201529081906060820190565b0390f35b3461037657602036600319011261037657602061039f600435614abc565b34610376576000366003190112610376576020604051620100008152f35b3461037657602061039f6104a436612302565b9061498e565b3461037657602036600319011261037657600054600435906001600160a01b0316330361059e57612710811015610523578060131b9080820462080000149015171561050d578015610376576104ff90612454565b600655602060405160018152f35b634e487b7160e01b600052601160045260246000fd5b60405162461bcd60e51b815260206004820152604760248201527f4e657720646966666963756c7479206d757374206265206174206c656173742060448201527f62656c6f7720313030303020307842544320646966666963756c7479206e6f74606482015266103434b3b432b960c91b608482015260a490fd5b60405162461bcd60e51b815260206004820152600a60248201526927b7363c9027bbb732b960b11b6044820152606490fd5b346103765760003660031901126103765761045161043461490d565b346103765760003660031901126103765761000e6144c9565b3461037657600036600319011261037657602060ff601354166040519015158152f35b346103765760003660031901126103765761064560075442612431565b6001810180911161050d5761065f60095460125490612431565b801561071c575b6106729060025461247a565b6103e88202918083046103e8149015171561050d5761069091612463565b60065490610fa08111610713575b60fa811061070b575b6106b08161519d565b8211156106fd5750600160fd1b90505b6201000081106106f3575b600160fd1b81116106e8575b80156103765761039f602091612454565b50600160fd1b6106d7565b50620100006106cb565b61070691615205565b6106c0565b5060fa6106a7565b50610fa061069e565b506001610666565b34610376576000366003190112610376576020600854604051908152f35b60a0366003190112610376576004356001600160401b0381116103765761076d903690600401612366565b6024356001600160401b0381116103765761078c9036906004016123c3565b906044356001600160a01b03811690819003610376578251926001840180941161050d576107b98461234f565b936107c76040519586612318565b8085526107d6601f199161234f565b0136602086013760005b81516001810180911161050d57811015610809578083610802600193886125df565b52016107e0565b61081a608435606435878588613ebc565b50602060405160018152f35b3461037657600036600319011261037657602061039f60095460125490612431565b60a0366003190112610376576004356001600160401b03811161037657610873903690600401612366565b6024356001600160401b038111610376576108929036906004016123c3565b604435906001600160401b038211610376576020926108b861039f9336906004016123c3565b6084359260643592613ebc565b34610376576000366003190112610376576020601b54604051908152f35b610c7b565b3461037657600036600319011261037657602061039f61090a60175442612431565b612732565b6080366003190112610376576004356001600160401b0381116103765761093a9036906004016123c3565b6024356001600160401b03811161037657610959903690600401612366565b90604435906001600160401b0382116103765760209261098061098a933690600401612366565b90606435926134c7565b6040519015158152f35b346103765760003660031901126103765760206040516107e08152f35b34610376576000366003190112610376576020601854604051908152f35b346103765760a0366003190112610376576084356001600160a01b038116810361037657604051610a3b81610a2d60208201946004359060443587916054939183526001600160601b03199060601b16602083015260348201520190565b03601f198101835282612318565b519020606435811161037657602090604051908152f35b34610376576000366003190112610376576020601554604051908152f35b3461037657606036600319011261037657600a546040805160208181019384523360601b6001600160601b031916928201929092526004356054820152909190610abd8160748101610a2d565b519020604051908152f35b34610376576000366003190112610376576000546040516001600160a01b039091168152602090f35b34610376576000366003190112610376576020600a54604051908152f35b34610376576000366003190112610376576020600654604051908152f35b3461037657600036600319011261037657604051600160fd1b8152602090f35b34610376576000366003190112610376576020600954604051908152f35b34610376576106d7610b7c36612302565b9061262b565b346103765760803660031901126103765760408051604435602082019081523360601b6001600160601b031916928201929092526004356054820152610bcb8160748101610a2d565b51902060643581116103765760209060405190602435148152f35b346103765760003660031901126103765760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b346103765760203660031901126103765760a0610c4060175442612431565b610c53610c4b612858565b600435614bf9565b9060409392935193845260208401526040830152660ffba26e7b326b60608301526080820152f35b34610376576000366003190112610376576020600e54604051908152f35b3461037657600036600319011261037657602061039f6133d2565b34610376576080366003190112610376576024356001600160401b03811161037657610ce49036906004016123c3565b606435610cf360443582612431565b90610d0361090a83600435612463565b90610d0e845161258a565b6000935b8551851015610da7576001850180861161050d575b8651811015610d9b576001600160a01b03610d4282896125df565b51166001600160a01b03610d56888a6125df565b511614610d6557600101610d27565b60405162461bcd60e51b815260206004820152600e60248201526d4e6f2073616d6520746f6b656e7360901b6044820152606490fd5b50600190940193610d12565b9350936000935b808510610dfb578560405180916020820160208352815180915260206040840192019060005b818110610de2575050500390f35b8251845285945060209384019390920191600101610dd4565b60005b8251811015611034576000610e138786612431565b600183018084116110205790610e2b610e319261292b565b9061284e565b15610e40575b50600101610dfe565b60249060206001600160a01b03610e5785886125df565b5116604051938480926370a0823160e01b82523060048301525afa918215611013578792829190610fda575b5081610e91575b5050610e37565b600384061580610fd1575b80610fc4575b15610f2f575090610ebb610ec092610ebb600b5461292b565b61247a565b90610eca8161292b565b6305f5e1008102908082046305f5e100148115171561050d576501d1a94a20000290808204614e20149015171561050d57610f0a610f1a91600194615337565b610f14838b6125df565b5161246d565b610f24828a6125df565b529050848880610e8a565b91610ebb610f4292610ebb600b5461292b565b610f4b8361292b565b916305f5e1008302928084046305f5e1001481151715610fb0576501d1a94a20000292808404614e201490151715610f9c578215610f995750610f9460019392610f1a92612463565b610f0a565b80fd5b634e487b7160e01b81526011600452602490fd5b634e487b7160e01b82526011600452602482fd5b5063010c8e008311610ea2565b50831515610e9c565b915091506020813d821161100b575b81610ff660209383612318565b81010312611007575186918a610e83565b5080fd5b3d9150610fe9565b50604051903d90823e3d90fd5b634e487b7160e01b83526011600452602483fd5b509360010193610dae565b3461037657602036600319011261037657602061039f600435613375565b346103765760203660031901126103765760043560005260056020526020604060002054604051908152f35b3461037657602036600319011261037657602061039f600435613352565b34610376576000366003190112610376576a08f69750e81d45e9700000600e54116113c8576001546040516370a0823160e01b815230600482015290602090829060249082906001600160a01b03165afa80156113bc5760009061137f575b6a10d0a9ee1d64709720000091501061132e57600d546112f35760135460ff81166112ae5760ff19166001176013557f0000000000000000000000000000000000000000000000000000000000000000428111159081611296575b501561124657600019430143811161050d574080600a55600b546111848161292b565b8015611230576802b5e3af16b188000004600d556001810180911161050d576111ac9061292b565b8015610376576111bb9061243e565b6a115eec47f6cf7e35000000036a115eec47f6cf7e35000000811161050d57600c55600160ea1b60065542600755436008556000601255600060095580600052600460205260ff604060002054166103765760005260046020526040600020600160ff19825416179055602060405160018152f35b634e487b7160e01b600052601260045260246000fd5b60405162461bcd60e51b815260206004820152602260248201527f37204461792077696e646f7720746f20616374697661746520537461727454696044820152616d6560f01b6064820152608490fd5b905062093a80810180911161050d5742111581611161565b60405162461bcd60e51b815260206004820152601860248201527f4f6e6c7920616c6c6f77656420746f2072756e206f6e636500000000000000006044820152606490fd5b60405162461bcd60e51b8152602060048201526013602482015272726577617264206d757374206265207a65726f60681b6044820152606490fd5b60405162461bcd60e51b815260206004820152602360248201527f4d75737420737570706c7920322a31305f3136345f313030206d696e20746f6b604482015262656e7360e81b6064820152608490fd5b506020813d6020116113b4575b8161139960209383612318565b81010312610376576a10d0a9ee1d6470972000009051611106565b3d915061138c565b6040513d6000823e3d90fd5b60405162461bcd60e51b815260206004820152601e60248201527f43616e74206d696e7420746f6b656e73206265666f7265206c61756e636800006044820152606490fd5b34610376576000366003190112610376576020600c54604051908152f35b34610376576000366003190112610376576020601954604051908152f35b3461037657600036600319011261037657611465600b5461292b565b801561123057602090604051906802b5e3af16b1880000048152f35b34610376576000366003190112610376576020600254604051908152f35b6080366003190112610376576114b3612239565b6024356001600160401b038111610376576020916114d861039f923690600401612366565b90606435916044359161299d565b34610376576000366003190112610376576020601654604051908152f35b34610376576000366003190112610376576020601a54604051908152f35b346103765760003660031901126103765760206040516a115eec47f6cf7e350000008152f35b3461037657600036600319011261037657602061039f612858565b3461037657600036600319011261037657602061039f612800565b34610376576000366003190112610376576020604051660ffba26e7b326b8152f35b346103765760003660031901126103765760135460405160089190911c6001600160a01b03168152602090f35b34610376576000366003190112610376576020600b54604051908152f35b3461037657602036600319011261037657602061039f600435612732565b3461037657602061039f610b7c36612302565b34610376576000366003190112610376576104516116386125f3565b6040805194855260208501939093529183015260608201529081906080820190565b34610376576000366003190112610376576020600d54604051908152f35b3461037657604036600319011261037657604080516116978282612318565b60018152601f1982013660208301376004356116b2826125bc565b526000916116be612858565b90836017549260025491600a549060065490885b885181101561205d576116e5818a6125df565b518751602081018681523360601b6001600160601b031916604083015260548201929092526117178160748101610a2d565b5190209161172d6117288486612463565b613375565b6107e061173a828461246d565b11612039575b8661174b828461246d565b1061200e575061175b8187612431565b61176e876117698c42612431565b612463565b80891015611fd75761178e6117878a60011c8093612463565b918a612463565b906006548015611fc3578e918c91600160fd1b819004821115611fac57505050508015611f9857600160fd1b0460ff8a8e5b8981526003602052818120888252602052205416908115611f8d575b50611f82576117ec905b8261246d565b908110611dca57806107e09193868d526003602052898d20908d52602052888c20600160ff198254161790551015611f705784821015611830576001905b016116d2565b50505090809293949550925b83159586611f2057846117698261185a8361176961186a9642612431565b50611863612570565b5042612431565b6103788102908082046103781490151715611f0c579061188991612463565b606481029080820460641490151715611ef8576103786064910411611ed8575b6118b38284614bf9565b9391908194816118c581600f5461246d565b600f55818110611dce57506118d991612431565b8801808911611c0057915b60095490808710611d19576118f9908261246d565b908110611c1457600955600e546a115eec47f6cf7e3500000010611d10575b6119206144c9565b61192c60075442612431565b60018101809111611c00576009549061195261194a60125484612431565b60025461247a565b916012556103e88102908082046103e81490151715611c56579061197591612463565b610fa08111611d07575b60fa8110611cff575b6119918161519d565b6006549190821115611cee575050600160fd1b6006555b4260075414611cba5742600755436008556201000060065410611cae575b600654600160fd1b10611ca1575b6000194301438111611c005740600a548751602081019183835289820152888152611a00606082612318565b519020808a52600460205260ff888b205416611c6a57808a526004602052878a20600160ff19825416179055600a558089526005602052868920549060018201809211611c5657906003918a52600560205280888b205511611c24575b600e54611a6a828261246d565b908110611c1457600c541080611c18575b611b6a575b50600154855163a9059cbb60e01b81523360048201526024810185905290602090829060449082908c906001600160a01b03165af18015611b6057611b33575b50600e54611ace848261246d565b908110611b2f57968080809360209a600e5542601755335af150611af061296d565b50600954845192835286830152838201527fcf6fbb9dcea7d07263ab4f5c3a92f53af33dffc421d9d121e1c74b307e68189d60603392a2505190158152f35b8780fd5b611b549060203d602011611b59575b611b4c8183612318565b81019061293a565b611ac0565b503d611b42565b86513d8a823e3d90fd5b909250600b546001810190818111611c005760029082600b5501808211611c0057611b949061292b565b8015611c1457611ba39061243e565b6a115eec47f6cf7e35000000036a115eec47f6cf7e350000008111611c0057600c55611bce9061292b565b8015611bec576802b5e3af16b188000004600d5560011c9187611a80565b634e487b7160e01b88526012600452602488fd5b634e487b7160e01b89526011600452602489fd5b8880fd5b50603b600b5410611a7b565b855162461bcd60e51b815260206004820152600b60248201526a4d617820332074696d657360a81b6044820152606490fd5b634e487b7160e01b8a52601160045260248afd5b875162461bcd60e51b815260206004820152601060248201526f75736564204368616c206265666f726560801b6044820152606490fd5b600160fd1b6006556119d4565b620100006006556119c6565b855162461bcd60e51b815260206004820152600d60248201526c4e6f2073616d6520626c6f636b60981b6044820152606490fd5b611cf791615205565b6006556119a8565b5060fa611988565b50610fa061197f565b87600d55611918565b6107e0036107e08111611c565786611d309161246d565b611d3a8782612431565b91611d45888261246d565b908110611dca576009556101f882109182611dbd575b8215611d9e575b8215611d7d575b505015611a5d57611d786144c9565b611a5d565b6105e811915081611d91575b508980611d69565b6105e89150101589611d89565b91506103f0821080611db1575b91611d62565b506103f0811015611dab565b6101f88210159250611d5b565b8a80fd5b90611dd99250612431565b80611ded578803888111611c0057916118e4565b604460458a89611ea46004600c611e0f611e09611eca9961526f565b9561526f565b845196879160208301977f4e65656420746f2073656e64207265717569726564204554482e20526571756989526403932b21d160dd1b88850152611e5c8151809260208688019101612908565b83016b0103bb2b4961029b2b73a1d160a51b83820152611e86825180936020605185019101612908565b0101632077656960e01b838201520301601b19810186520184612318565b5193849262461bcd60e51b84526020600485015251809281602486015285850190612908565b601f01601f19168101030190fd5b601954611ee5848261246d565b908110611ef4576019556118a9565b8680fd5b634e487b7160e01b87526011600452602487fd5b634e487b7160e01b88526011600452602488fd5b855162461bcd60e51b8152602060048201526024808201527f4d75737420686176652076616c696420736f6c766520696e2074686520616e736044820152637765727360e01b6064820152608490fd5b5050509091929394506107e09261183c565b50915060019061182a565b90508410158d6117dc565b634e487b7160e01b8d52601260045260248dfd5b93611769611fbd9260ff959661247a565b926117c0565b634e487b7160e01b8f52601260045260248ffd5b50858c526003602052888c20848d5260205260ff898d2054168015612004575b611f82576117ec906117e6565b5084841015611ff7565b858c526003602052888c20848d5260205260ff898d205416801561200457611f82576117ec906117e6565b50806107e0036107e081111561174057634e487b7160e01b8c52601160045260248cfd5b509495965050909161183c565b34610376576000366003190112610376576106d7612800565b346103765760803660031901126103765761209c612239565b506120a561224f565b506064356001600160401b038111610376576120c5903690600401612265565b5050604051630a85bd0160e11b8152602090f35b34610376576000366003190112610376576020601754604051908152f35b34610376576020366003190112610376576004356000526004602052602060ff604060002054166040519015158152f35b346103765760003660031901126103765761045161163861248d565b346103765760403660031901126103765760043560005260036020526040600020602435600052602052602060ff604060002054166040519015158152f35b3461037657600036600319011261037657602061039f60175442612431565b34610376576000366003190112610376576020600f54604051908152f35b34610376576000366003190112610376576020601254604051908152f35b34610376576000366003190112610376576019546121fa6133d2565b9061045161220d60095460125490612431565b612215612858565b90604051948594859094939260609260808301968352602083015260408201520152565b600435906001600160a01b038216820361037657565b602435906001600160a01b038216820361037657565b9181601f84011215610376578235916001600160401b038311610376576020838186019501011161037657565b3461037657600060a0366003190112610f9957600435906001600160a01b0382168203610f995750506024356001600160a01b038116810361037657506084356001600160401b038111610376576122ee903690600401612265565b505060405163f23a6e6160e01b8152602090f35b6040906003190112610376576004359060243590565b90601f801991011681019081106001600160401b0382111761233957604052565b634e487b7160e01b600052604160045260246000fd5b6001600160401b0381116123395760051b60200190565b9080601f8301121561037657813561237d8161234f565b9261238b6040519485612318565b81845260208085019260051b82010192831161037657602001905b8282106123b35750505090565b81358152602091820191016123a6565b9080601f83011215610376578135906123db8261234f565b926123e96040519485612318565b82845260208085019360051b82010191821161037657602001915b8183106124115750505090565b82356001600160a01b038116810361037657815260209283019201612404565b9190820391821161050d57565b8015611230576a115eec47f6cf7e350000000490565b801561123057600160fd1b0490565b8115611230570490565b9190820180921161050d57565b8181029291811591840414171561050d57565b6009546012549061249e8282612431565b15612560576124bc6124c2926124b660075442612431565b92612431565b90612463565b801561253e575b600d54906103e88102918115928281046103e81484171561050d576103e8916124f86125089260025490612463565b838111156125265750829061247a565b049161123057806301e133800492612520848461247a565b93929190565b60fa811015612538575060fa9061247a565b9061247a565b60018101809111156124c957634e487b7160e01b600052601160045260246000fd5b5050600090600090600090600090565b612578612800565b80156103765761258790612454565b90565b906125948261234f565b6125a16040519182612318565b82815280926125b2601f199161234f565b0190602036910137565b8051156125c95760200190565b634e487b7160e01b600052603260045260246000fd5b80518210156125c95760209160051b010190565b61016d6125fe61248d565b5050500490811561261f57600c5491600e5491612520826117698587612431565b60009150819081908190565b9190916126416000936117696002549342612431565b80821061264c575050565b819293506126616126679260011c8092612463565b92612463565b600654801561123057600160fd1b819004831161268b57612587926117699161247a565b50600160fd1b92915050565b600090801561272b5780806001146127235760021461271b5760016101338210166001600b8310161761270d579060019060025b600181116126e4575082600019048211610f9c57500290565b9280600019048111610fb05760018416612704575b80029260011c6126cb565b809202916126f9565b6002900a919080610f9c5750565b506004919050565b505050600190565b5050600090565b610378810290808204610378149015171561050d5760025461275391612463565b606481028181046064148215171561050d57610378610bb89104106000146127c45761277e81612697565b80600f0290600f8204810361050d576274692202906207c2be82040361050d57620c08409004816297bb7002916297bb7083040361050d5761037861258792049061246d565b806018029060188204810361050d5763074692200290808204624d9b6c149015171561050d57610378900463ce09d1b0810180911161050d5790565b600161280a612858565b14612816575b60065490565b6002546017546128268142612431565b8210612833575050612810565b6128406126679142612431565b6126618360011c8092612463565b8115611230570690565b6009546012549061286b60075442612431565b6002549061288261287c8585612431565b8361247a565b916107e08102908082046107e0149015171561050d576001600160fe1b038316830361050d576128b28585612431565b9260021b821192836128fd575b5082156128f3575b5050156128d5575050600190565b6107e0916128e291612431565b066107e0036107e0811161050d5790565b10905038806128c7565b60fc109250386128bf565b60005b83811061291b5750506000910152565b818101518382015260200161290b565b60ff811161050d576001901b90565b90816020910312610376575180151581036103765790565b6001600160401b03811161233957601f01601f191660200190565b3d15612998573d9061297e82612952565b9161298c6040519384612318565b82523d6000602084013e565b606090565b9092916129a8612858565b91600091826017549060025492600a5495600654925b8a51811015613334576129d1818c6125df565b51604051612a0881610a2d60208201948d339087916054939183526001600160601b03199060601b16602083015260348201520190565b51902091612a196117288487612463565b84612a24828461246d565b11613324575b8a612a35828461246d565b106132f35750612a45818b612431565b612a538b6117698942612431565b808910156132b657612a6c6117878a60011c8093612463565b90600654801561123057600160fd1b8190048211156132a3575050801561123057600160fd1b045b8a600052600360205260406000208560005260205260ff60406000205416908115613298575b5061328d57612ac9908261246d565b90811061037657808491938a60005260036020526040600020906000526020526040600020600160ff19825416179055101561327c5788821015612b11576001905b016129be565b505050509091929380959650955b861561322b57612b33876117698442612431565b106131815785611769612b4892611863612570565b90610378820291808304610378149015171561050d57612b6791612463565b60648102908082046064149015171561050d576103786064910411613165575b612b918385614bf9565b829195929580612ba381600f5461246d565b600f558281106130645750612bc191612bbb91612431565b3461246d565b915b60095490808810612fb357612bd8908261246d565b90811061037657600955600e546a115eec47f6cf7e3500000010612fa9575b612bff6144c9565b612c0b60075442612431565b6001810180911161050d57600954612c2861194a60125483612431565b906012556103e88202918083046103e8149015171561050d57612c4a91612463565b610fa08111612fa0575b60fa8110612f98575b612c668161519d565b6006549190821115612f87575050600160fd1b6006555b4260075414612f525742600755436008556201000060065410612f46575b600654600160fd1b10612f39575b600019430143811161050d5740600a546040516020810191838352604082015260408152612cd8606082612318565b51902080600052600460205260ff60406000205416612f01578060005260046020526040600020600160ff19825416179055600a558060005260056020526040600020546001810180911161050d5760039160005260056020528060406000205511612ece575b600e54612d4c828261246d565b90811061037657600c541080612ec2575b612e3f575b5060015460405163a9059cbb60e01b81526001600160a01b03848116600483015260248201879052909160209183916044918391600091165af180156113bc57612e22575b50600e5491612db6858461246d565b92831061037657600e9290925542601755600091829182918291906001600160a01b03165af150612de561296d565b50600954604051928352602083015260408201527fcf6fbb9dcea7d07263ab4f5c3a92f53af33dffc421d9d121e1c74b307e68189d60603392a290565b612e3a9060203d602011611b5957611b4c8183612318565b612da7565b909350600b54600181019081811161050d5760029082600b550180821161050d57612e699061292b565b801561037657612e789061243e565b6a115eec47f6cf7e3500000003906a115eec47f6cf7e35000000821161050d57612ea491600c5561292b565b8015611230576802b5e3af16b188000004600d5560011c9238612d62565b50603b600b5410612d5d565b60405162461bcd60e51b815260206004820152600b60248201526a4d617820332074696d657360a81b6044820152606490fd5b60405162461bcd60e51b815260206004820152601060248201526f75736564204368616c206265666f726560801b6044820152606490fd5b600160fd1b600655612ca9565b62010000600655612c9b565b60405162461bcd60e51b815260206004820152600d60248201526c4e6f2073616d6520626c6f636b60981b6044820152606490fd5b612f9091615205565b600655612c7d565b5060fa612c5d565b50610fa0612c54565b6000600d55612bf7565b6107e0036107e0811161050d5787612fca9161246d565b612fd48882612431565b91612fdf898261246d565b908110610376576009556101f882109182613057575b8215613038575b8215613017575b505015612d3f576130126144c9565b612d3f565b6105e81191508161302b575b503880613003565b6105e89150101538613023565b91506103f082108061304b575b91612ffc565b506103f0811015613045565b6101f88210159250612ff5565b905061306f91612431565b803410613086576130809034612431565b91612bc3565b60446045613096611eca9361526f565b61313d6004600c6130a63461526f565b60405195869160208301967f4e65656420746f2073656e64207265717569726564204554482e20526571756988526403932b21d160dd1b60408501526130f58151809260208688019101612908565b83016b0103bb2b4961029b2b73a1d160a51b8382015261311f825180936020605185019101612908565b0101632077656960e01b838201520301601b19810185520183612318565b60405193849262461bcd60e51b84526020600485015251809281602486015285850190612908565b601954613172858261246d565b90811061037657601955612b87565b60405162461bcd60e51b815260206004820152607060248201527f4e6f7420656e6f75676820446966666572656e636520696e2070726576426c6f60448201527f636b54696d65202f20476f6f644c6f6f70732c20636f6d706172656420746f2060648201527f6d696e50726576696f7573426c6f636b54696d65446966666572656e6365206660848201526f756e6374696f6e207661726961626c6560801b60a482015260c490fd5b60405162461bcd60e51b8152602060048201526024808201527f4d75737420686176652076616c696420736f6c766520696e2074686520616e736044820152637765727360e01b6064820152608490fd5b505091929394959697505095612b1f565b509150600190612b0b565b905084101538612aba565b6132b192916117699161247a565b612a94565b5089600052600360205260406000208460005260205260ff6040600020541680156132e9575b61328d57612ac9906117e6565b50858410156132dc565b89600052600360205260406000208460005260205260ff6040600020541680156132e95761328d57612ac9906117e6565b5061332f8185612431565b612a2a565b50985050509091929394612b1f565b600019811461050d5760010190565b6000905b60018111613362575090565b61336f9060011c91613343565b90613356565b60048110613397576133899060011c613352565b6001810180911161050d5790565b50600190565b9190916000838201938412911290801582169115161761050d57565b8181039291600013801582851316918412161761050d57565b600954601254906133ea600754926124b68442612431565b916002546107e08102908082046107e0148115171561050d578461340d9161247a565b600281901b93906001600160fe1b0381160361050d5783811190816134bc575b81156134b2575b506134a95761344f60fc9161344a42918561339d565b6133b9565b931161346a575b505060008113156134645790565b50600090565b61344a61347892429261339d565b6000811380613495575b61348d575b80613456565b905038613487565b508181128061348257506000821315613482565b50505050600090565b9050811038613434565b60fc8611915061342d565b919260016134d3612858565b1480613ea4575b80613e98575b15613e62578251825103613e25576000906134f9612858565b90826017549360025490600a549360065491845b8b51811015613e1557613520818d6125df565b5160405161355681610a2d6020820194338d87916054939183526001600160601b03199060601b16602083015260348201520190565b519020916135676117288487612463565b84613572828461246d565b11613e05575b89613583828461246d565b10613dd85750613593818a612431565b6135a18a6117698d42612431565b80881015613d9f576135c16135ba8960011c8093612463565b9189612463565b906006548015613d8b57600160fd1b819004821115613d785750508015613d6457600160fd1b045b898952600360205260408920858a5260205260ff60408a205416908115613d59575b50613d4e5761361a908261246d565b908110611ef4578084919389895260036020526040892090895260205260408820600160ff198254161790551015613d3c578782101561365e576001905b0161350d565b50505050909192809495969750945b851561322b57856117698261185a836117696136899642612431565b610378810290808204610378149015171561102057906136a891612463565b606481029080820460641490151715610fb0576103786064910411613d20575b6136d28385614bf9565b8291959295806136e481600f5461246d565b600f55828110613cfe57506136fc91612bbb91612431565b915b60095490808810613c4957613713908261246d565b908110613be157600955600e546a115eec47f6cf7e3500000010613c40575b61373a6144c9565b61374660075442612431565b60018101809111613bcd576009549061376461194a60125484612431565b916012556103e88102908082046103e81490151715613bf1579061378791612463565b610fa08111613c37575b60fa8110613c2f575b6137a38161519d565b6006549190821115613c1e575050600160fd1b6006555b4260075414612f525742600755436008556201000060065410613c12575b600654600160fd1b10613c05575b6000194301438111613bcd5740600a546040516020810191838352604082015260408152613815606082612318565b519020808552600460205260ff604086205416612f0157808552600460205260408520600160ff19825416179055600a55808452600560205260408420549060018201809211613bf157906003918552600560205280604086205511612ece575b600e54613883828261246d565b908110613be157600c541080613be5575b613b37575b5060015460405163a9059cbb60e01b815233600482015260248101869052906020908290604490829087906001600160a01b03165af18015613b2c57613b0f575b50600e546138e8858261246d565b908110613b0b578280928192600e5542601755335af15061390761296d565b50600954604051928352602083015260408201527fcf6fbb9dcea7d07263ab4f5c3a92f53af33dffc421d9d121e1c74b307e68189d60603392a250600090815b8351811015613b02576001600160a01b0361396282866125df565b511661396e82846125df565b516040516301ffc9a760e01b8152636cdb3d1360e11b6004820152602081602481865afa869181613ae2575b50613a7d575b506040516301ffc9a760e01b81526380ac58cd60e01b6004820152602081602481865afa869181613a5d575b506139df575b5050506001905b01613947565b6139e957806139d2565b813b15613a595784809260a482936040519485938492635c46a7ef60e11b84523060048501523360248501526044840152608060648401528160848401525af19182613a49575b5050613a3e576001906139d9565b505060195550600190565b613a5291612318565b3884613a30565b8480fd5b613a7691925060203d8111611b5957611b4c8183612318565b90386139cc565b613a8757386139a0565b813b15613a595784809260c482936040519485938492637921219560e11b845230600485015233602485015260448401526001606484015260a060848401528160a48401525af19182613a49575050613a3e576001906139d9565b613afb91925060203d8111611b5957611b4c8183612318565b903861399a565b50505050600190565b8280fd5b613b279060203d602011611b5957611b4c8183612318565b6138da565b6040513d85823e3d90fd5b909350600b546001810190818111613bcd5760029082600b5501808211613bcd57613b619061292b565b8015613be157613b709061243e565b6a115eec47f6cf7e35000000036a115eec47f6cf7e350000008111613bcd57600c55613b9b9061292b565b8015613bb9576802b5e3af16b188000004600d5560011c9238613899565b634e487b7160e01b83526012600452602483fd5b634e487b7160e01b84526011600452602484fd5b8380fd5b50603b600b5410613894565b634e487b7160e01b85526011600452602485fd5b600160fd1b6006556137e6565b620100006006556137d8565b613c2791615205565b6006556137ba565b5060fa61379a565b50610fa0613791565b82600d55613732565b6107e0036107e08111613bf15787613c609161246d565b613c6a8882612431565b91613c75898261246d565b908110613cfa576009556101f882109182613ced575b8215613cce575b8215613cad575b50501561387657613ca86144c9565b613876565b6105e811915081613cc1575b503880613c99565b6105e89150101538613cb9565b91506103f0821080613ce1575b91613c92565b506103f0811015613cdb565b6101f88210159250613c8b565b8580fd5b9050613d0991612431565b80341061308657613d1a9034612431565b916136fe565b601954613d2d858261246d565b908110611007576019556136c8565b5050919293949596979850509461366d565b509150600190613658565b90508410153861360b565b634e487b7160e01b89526012600452602489fd5b613d8692916117699161247a565b6135e9565b634e487b7160e01b8b52601260045260248bfd5b5088885260036020526040882084895260205260ff6040892054168015613dce575b613d4e5761361a906117e6565b5085841015613dc1565b88885260036020526040882084895260205260ff6040892054168015613dce57613d4e5761361a906117e6565b50613e108185612431565b613578565b509798995050509091929361366d565b60405162461bcd60e51b8152602060048201526015602482015274082e4e4c2f240d8cadccee8d040dad2e6dac2e8c6d605b1b6044820152606490fd5b60405162461bcd60e51b815260206004820152600e60248201526d1391950810591a9d5cdd0810985960921b6044820152606490fd5b5060fc601954116134e0565b506005613eb660095460125490612431565b106134da565b60175461176996959294613ef49361090a93613eeb92906001600160a01b03613ee4896125bc565b511661299d565b96879142612431565b926009549460009185156144bf57835185519060018201809211613bf157036144545760018060a01b036001541695613f2d865161258a565b92845b8751811015613fac57886001600160a01b03613f4c838b6125df565b511614613f5b57600101613f30565b60405162461bcd60e51b8152602060048201526024808201527f4e6f7420616c6c6f77656420746f204552433230206d696e74204d61696e205460448201526337b5b2b760e11b6064820152608490fd5b5090929594979193965086905b80821061414c5750505060005b85811080614142575b156140f5576001600160a01b03613fe682866125df565b511690613ff381876125df565b518061400a575b506140059150613343565b613fc6565b60135460405163a9059cbb60e01b815260089190911c6001600160a01b03166004820152602481018290526020816044816000885af180156113bc576140d9575b50600182019081831161050d576140a7936020926001600160a01b0390614072908d6125df565b5116600060405180978195829463a9059cbb60e01b84526004840160209093929193604081019460018060a01b031681520152565b03925af19182156113bc576140059215613ffa576140d29060203d8111611b5957611b4c8183612318565b5038613ffa565b6140f09060203d8111611b5957611b4c8183612318565b61404b565b5093925093505060095490600a54604051928352602083015260408201528160608201527f87e5a7775b8ac2ead741e32752431bffeff76ec5f347cc202a6bad454653930b60803392a290565b5083518110613fcf565b909497600097949796939296975b89518910156144455760018901808a1161050d5761418061417a8261292b565b8a61284e565b614214575b8a51811015614208576001600160a01b036141a0828d6125df565b51166001600160a01b036141b48c8e6125df565b5116146141c357600101614185565b60405162461bcd60e51b815260206004820152601b60248201527f4e6f207072696e74696e67205468652073616d6520746f6b656e7300000000006044820152606490fd5b5060019098019761415a565b50989593989694909192965b88156144365788821061442e575b60005b89811080614424575b15614401576001810180821161050d5761425661425c9161292b565b8861284e565b15614270575b61426b90613343565b614231565b6000806001600160a01b03614285848c6125df565b511660405160208101906370a0823160e01b8252306024820152602481526142ae604482612318565b51915afa6142ba61296d565b90806143f5575b156143ed57805160208083019260009281010312610f995750515b806142e8575b50614262565b896003830615806143e4575b806143d7575b15614371576143089161247a565b906143128161292b565b916305f5e1008302928084046305f5e100148115171561050d576501d1a94a20000292808404614e20149015171561050d5761436a826143648f9361426b9661435a91615337565b610f1483866125df565b926125df565b52906142e2565b61437a9161247a565b906143848161292b565b916305f5e1008302928084046305f5e100148115171561050d576501d1a94a20000292808404614e20149015171561050d5782156103765761436a826143648f9361426b966143d291612463565b61435a565b5063010c8e0081116142fa565b508215156142f4565b5060006142dc565b506020815110156142c1565b50949097509795929097600019810190811161050d57600190915b019091613fb9565b508751811061423a565b88915061422e565b9491989693600191985061441c565b98959398969490919296614220565b60405162461bcd60e51b815260206004820152603a60248201527f4d696e74546f2068617320746f206861766520616e206578747261206164647260448201527f65737320636f6d706172656420746f20457874726146756e64730000000000006064820152608490fd5b9550509250505090565b6000606447818102918115918304141715610fb057670214e8348c4d796090048060155560c881106000146146ce57806501a3185c500002906501a3185c5000820403610fb05760c890045b601855614527600e5460105490612431565b614536600f5460115490612431565b60015460135460405163a9059cbb60e01b81526001600160a01b0360089290921c8216600482015260248101859052929392916020918391168187816044810103925af180156146c3576146a6575b50614593601454918261246d565b908110613b0b57601455476018546107e08102908082046107e01490151715613bcd5760011c9081605002916050830403613bcd57839291101561469c576013548291829182919060081c6001600160a01b03165af16145f161296d565b5015614661576001601a5560135460081c6001600160a01b0316803b1561100757818091600460405180948193636645e41360e01b83525af1801561465657614646575b50505b600e54601055600f54601155565b8161465091612318565b38614635565b6040513d84823e3d90fd5b60405162461bcd60e51b8152602060048201526013602482015272115512081d1c985b9cd9995c8819985a5b1959606a1b6044820152606490fd5b5050601a55614638565b6146be9060203d602011611b5957611b4c8183612318565b614585565b6040513d86823e3d90fd5b6101908110156146fa57806502ba7def300002906502ba7def3000820403610fb0576101909004614515565b610320811015614726578065048c27395000029065048c27395000820403610fb0576103209004614515565b6106408110156147525780650746a52880000290650746a5288000820403610fb0576106409004614515565b610bb881101561477e5780650ae9f7bcc0000290650ae9f7bcc000820403610fb057610bb89004614515565b6113888110156147aa5780650da475abf0000290650da475abf000820403610fb0576113889004614515565b6127108110156147d657806512309ce5400002906512309ce54000820403610fb0576127109004614515565b614e208110156148025780651b48eb57e0000290651b48eb57e000820403610fb057614e209004614515565b619c4081101561482e5780652d79883d20000290652d79883d2000820403610fb057619c409004614515565b620186a081101561485c5780655af3107a40000290655af3107a4000820403610fb057620186a09004614515565b62030d4081101561488a578065886c98b76000029065886c98b76000820403610fb05762030d409004614515565b6207a1208110156148b8578065e35fa931a000029065e35fa931a000820403610fb0576207a1209004614515565b620f42408110156148e857806601c6bf5263400002906601c6bf52634000820403610fb057620f42409004614515565b806601c6bf5263400002906601c6bf52634000820403610fb057620f42409004614515565b6009546012549061491e8282612431565b15614981576124bc614936926124b660075442612431565b9061493f6125f3565b50505090821561496f575b62015180820282810462015180148315171561050d578361496a91612463565b929190565b916001810180911161050d579161494a565b5050600090600090600090565b90600d54916103e88102908082046103e8149015171561050d5760016149b76002548093612463565b9214801580614ab1575b156149db575050506149d76103e891829061247a565b0490565b60fa8310156149f6575050506149d76103e89160fa9061247a565b80614aa6575b614a0f575b506149d7906103e89261247a565b614a1b60075442612431565b6001810180911161050d57614a3560095460125490612431565b908115614a8c575b614a556103e895936117696149d79694600494612463565b1015614a6957506107d0905b925090614a01565b90610fa0821180614a84575b15614a6157610fa09150614a61565b506001614a75565b939192906001810180911161050d57919390929190614a3d565b506107d082116149fc565b506103e883116149c1565b600080916103788102908082046103781490151715610fb057600254614ae191612463565b606481028181046064148215171561102057610378900491610bb8831015614bb85750614b0d81612697565b80600f0290600f8204810361050d576274692202906207c2be82040361050d57620c08409004816297bb7002916297bb7083040361050d57610378614b5392049061246d565b601a549182614b63575b50505090565b6107d09192935010600014614b92576305f5e10091610ebb614b88926018549061247a565b045b388080614b5d565b5060185480610140029061014082040361050d57600a91614bb29161247a565b04614b8a565b9080601802906018820481036110205763074692200290808204624d9b6c1490151715610fb05761037890049063ce09d1b08201809211610f9c5750614b53565b91909160009182614c08612800565b801561100757614c1790612454565b9460175493614c268542612431565b94811561502057614c3d61287c6103ce8489612463565b5060065491838110614fdf575082611769614c589242612431565b9060025491808310614f7a575b5080915015613b0b57614c7790612454565b91614c828286612463565b90600d54916103e88102908082046103e81490151715610fb057614ca96002548092612463565b915060fa821015614ecb575050614cc56103e89160fa9061247a565b0491614cd18286612463565b90614ce060009160131c615359565b90610fa09280614e9f575b50610fa08311614e95575b6103e8831080614e8e575b15614dd057506103e89150614d1790829061247a565b0490600019810181811161050d5761253882614d55614d6796614d4f614d4984614d44614d4f998e612463565b61498e565b8661247a565b9061246d565b99614d628260009a612463565b615071565b9184614d71575b50565b670de0b6b3a76400008302838104670de0b6b3a76400001484151715610fb057614da18664746a52880092612463565b1015614d6e579091508364746a528800029064746a52880082048503610f9c5750670de0b6b3a7640000900490565b6101f483109081614deb575b50506103e891614d179161247a565b614df760075442612431565b9060018201809211610f9c5750916103e893916004614e3a614e31614d1796614e2560095460125490612431565b908115614e8557612463565b60025490612463565b1080918192614e7d575b5015614e5a57506101f491505b91819350614ddc565b60fa83109081614e74575b5015614e515760fa9150614e51565b90501538614e65565b905038614e44565b60019150612463565b5080614d01565b610fa09250614cf6565b9092506002546103e88102908082046103e81490151715613bcd5790614ec491612463565b9138614ceb565b6107d08211614ee3575b50614cc5906103e89261247a565b614eef60075442612431565b6001810180911161050d57614f0960095460125490612431565b908115614f60575b614f296103e89593611769614cc59694600494612463565b1015614f3d57506107d0905b925090614ed5565b90610fa0821180614f58575b15614f3557610fa09150614f35565b506001614f49565b939192906001810180911161050d57919390929190614f11565b614f9290614f8c8460011c8092612463565b93612463565b908015614fcb57600160fd1b819004831115614fb95750600160fd1b9150505b8038614c65565b614fc6926117699161247a565b614fb2565b634e487b7160e01b85526012600452602485fd5b9250505083945061253881615005614fff82614d4481614d67989a612463565b8261247a565b97614d628261501a614fff6103ce838d612463565b99612463565b60405162461bcd60e51b815260206004820152602360248201527f436f6d70656e736174696f6e206d75737420626520677265617465722074686160448201526206e20360ec1b6064820152608490fd5b9061507e9060131c615359565b91610fa09180615171575b50610fa08211615167575b6103e882108061515c575b156150b45750506149d76103e891829061247a565b60011480615151575b6150cf575b6149d7906103e89261247a565b6150db60075442612431565b906001820180921161050d576103e8926004615106614e316149d795614e2560095460125490612431565b108080615146575b1561512357506101f491505b925090506150c2565b60fa8310908161513d575b501561511a5760fa915061511a565b9050153861512e565b506101f4831061510e565b506101f481106150bd565b50600181141561509f565b610fa09150615094565b909150600254906103e88202918083046103e8149015171561050d5761519691612463565b9038615089565b607d81111561037657806103e8600160fd1b098180600003168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030291600181806000030401821515607d03029160000304170290565b80820290600019838209908280831092039180830392836103e811156103765714615264577fac083126e978d4fdf3b645a1cac083126e978d4fdf3b645a1cac083126e978d5936103e8910990828211900360fd1b910360031c170290565b50506103e891500490565b801561531757600081805b615303575061528881612952565b906152966040519283612318565b808252601f196152a582612952565b013660208401375b809280156152fc57600019820191821161050d578193600a8206603001928360301161050d57845111156125c957600a9260f81b6001600160f81b03191660001a908401601f015304916152ad565b5050905090565b9061530f600a91613343565b91048061527a565b50604051615326604082612318565b60018152600360fc1b602082015290565b908015610376578061534c6153529284612463565b9261284e565b6133895790565b600060018210615554576002821061554957600a821061553e5760648210615533576103e88210615528576161a8821061551c5761c3508210615510576201e8488210615504576203d09082106154f7576207a12082106154e557620f424082106154d957622dc6c082106154c757506298968081106154bc576301312d0081106154b1576302faf08081106154a6576305f5e100811061549b57630ee6b280811061548f57631dcd6500811061548357633b9aca008110615477576377359400811061546b5763b2d05e00811061545f5764012a05f2008110615453576509184e72a000624c4b409091048181029182040361050d5790565b5066246139ca80000090565b506612309ce540000090565b506609184e72a0000090565b5066048c273950000090565b50660246139ca8000090565b5066012309ce54000090565b50659184e72a000090565b506548c27395000090565b5065246139ca800090565b506512309ce5400090565b809150610f9c5750650da475abf00090565b50506509184e72a00090565b809150610f9c5750650610344c6aaa90565b90505065048c2739500090565b505065048c2739500090565b5050650246139ca80090565b505065012309ce540090565b5050649184e72a0090565b50506448c273950090565b505064246139ca8090565b50506412309ce54090565b50506409184e72a09056fea26469706673582212208b6a2f4e48277282ae24d5483fd67055ae947a614a18019515154e41704c856b64736f6c634300081c0033000000000000000000000000b379a851ac41bcdf0c2564b88916b10e5a08daae0000000000000000000000003ea249809f032b1f5ae7b1dd4986490d05ee2dc2

Deployed Bytecode

0x60806040526004361015610010575b005b60003560e01c8062819439146121de578063012d3edf146121c0578063035ccc44146121a257806305411d8814612183578063080ca6e2146121445780630a891b83146121285780630c179832146120f75780630c97e564146103a757806310294317146120d9578063150b7a021461208357806317da485f1461206a5780631801fbe5146116785780632381a60e1461165a578063240c3b701461161c5780632656e97f14611609578063294ce45d146115eb5780632b112e49146108e35780632d38bf7a146115cd5780632f104e0c146115a05780633179fabc1461157e57806332e997081461156357806334d5b131146115485780633730837c146115225780633c953615146115045780633dc8a068146114e657806343346f351461149f57806345d8a23214611481578063490203a7146114495780634cbf68fe1461142b5780634ef3762814610af15780634fa972e11461140d57806351736a13146110a75780635456bf1314611089578063577e9ec11461105d5780635a993ae91461103f578063646222c014610cb45780636d2bfdba14610c995780636de9f32b14610c7b57806373d21f8614610c21578063757991a814610b4d57806378e9792514610be657806381269a5614610b82578063822dec0514610b6b578063829965cc14610b4d57806387a2a9d614610b2d5780638a769d3514610b0f5780638ae0368b14610af15780638da5cb5b14610ac857806397566aa014610a7057806399f584b314610a525780639d30dffb146109cf578063a68eb88e146109b1578063b5ade81b14610994578063b83bd2bd1461090f578063bd92d4d4146108e8578063c0abebe0146108e3578063c212f073146108c5578063c4dd180c14610848578063c76ae54014610826578063c8ce67b914610742578063cb9ae70714610724578063ccadb30a14610628578063cf30901214610605578063d0856d16146105ec578063d0f66e4b146105d0578063d317140b146104aa578063da9816b614610491578063dc6e9cf914610473578063dfe95b0c14610455578063e186ca981461041a578063e38cfe1f146103f1578063e932012b146103d3578063ec11a769146103ac578063f23a6e61146103a7578063f4ec14181461037b5763f95d39190361000e5734610376576000366003190112610376576020601454604051908152f35b600080fd5b3461037657606036600319011261037657602061039f604435602435600435615071565b604051908152f35b612292565b3461037657600036600319011261037657602061039f6103ce60175442612431565b614abc565b34610376576000366003190112610376576020600754604051908152f35b34610376576000366003190112610376576001546040516001600160a01b039091168152602090f35b346103765761045161043461042e36612302565b90614bf9565b604080519384526020840192909252908201529081906060820190565b0390f35b3461037657602036600319011261037657602061039f600435614abc565b34610376576000366003190112610376576020604051620100008152f35b3461037657602061039f6104a436612302565b9061498e565b3461037657602036600319011261037657600054600435906001600160a01b0316330361059e57612710811015610523578060131b9080820462080000149015171561050d578015610376576104ff90612454565b600655602060405160018152f35b634e487b7160e01b600052601160045260246000fd5b60405162461bcd60e51b815260206004820152604760248201527f4e657720646966666963756c7479206d757374206265206174206c656173742060448201527f62656c6f7720313030303020307842544320646966666963756c7479206e6f74606482015266103434b3b432b960c91b608482015260a490fd5b60405162461bcd60e51b815260206004820152600a60248201526927b7363c9027bbb732b960b11b6044820152606490fd5b346103765760003660031901126103765761045161043461490d565b346103765760003660031901126103765761000e6144c9565b3461037657600036600319011261037657602060ff601354166040519015158152f35b346103765760003660031901126103765761064560075442612431565b6001810180911161050d5761065f60095460125490612431565b801561071c575b6106729060025461247a565b6103e88202918083046103e8149015171561050d5761069091612463565b60065490610fa08111610713575b60fa811061070b575b6106b08161519d565b8211156106fd5750600160fd1b90505b6201000081106106f3575b600160fd1b81116106e8575b80156103765761039f602091612454565b50600160fd1b6106d7565b50620100006106cb565b61070691615205565b6106c0565b5060fa6106a7565b50610fa061069e565b506001610666565b34610376576000366003190112610376576020600854604051908152f35b60a0366003190112610376576004356001600160401b0381116103765761076d903690600401612366565b6024356001600160401b0381116103765761078c9036906004016123c3565b906044356001600160a01b03811690819003610376578251926001840180941161050d576107b98461234f565b936107c76040519586612318565b8085526107d6601f199161234f565b0136602086013760005b81516001810180911161050d57811015610809578083610802600193886125df565b52016107e0565b61081a608435606435878588613ebc565b50602060405160018152f35b3461037657600036600319011261037657602061039f60095460125490612431565b60a0366003190112610376576004356001600160401b03811161037657610873903690600401612366565b6024356001600160401b038111610376576108929036906004016123c3565b604435906001600160401b038211610376576020926108b861039f9336906004016123c3565b6084359260643592613ebc565b34610376576000366003190112610376576020601b54604051908152f35b610c7b565b3461037657600036600319011261037657602061039f61090a60175442612431565b612732565b6080366003190112610376576004356001600160401b0381116103765761093a9036906004016123c3565b6024356001600160401b03811161037657610959903690600401612366565b90604435906001600160401b0382116103765760209261098061098a933690600401612366565b90606435926134c7565b6040519015158152f35b346103765760003660031901126103765760206040516107e08152f35b34610376576000366003190112610376576020601854604051908152f35b346103765760a0366003190112610376576084356001600160a01b038116810361037657604051610a3b81610a2d60208201946004359060443587916054939183526001600160601b03199060601b16602083015260348201520190565b03601f198101835282612318565b519020606435811161037657602090604051908152f35b34610376576000366003190112610376576020601554604051908152f35b3461037657606036600319011261037657600a546040805160208181019384523360601b6001600160601b031916928201929092526004356054820152909190610abd8160748101610a2d565b519020604051908152f35b34610376576000366003190112610376576000546040516001600160a01b039091168152602090f35b34610376576000366003190112610376576020600a54604051908152f35b34610376576000366003190112610376576020600654604051908152f35b3461037657600036600319011261037657604051600160fd1b8152602090f35b34610376576000366003190112610376576020600954604051908152f35b34610376576106d7610b7c36612302565b9061262b565b346103765760803660031901126103765760408051604435602082019081523360601b6001600160601b031916928201929092526004356054820152610bcb8160748101610a2d565b51902060643581116103765760209060405190602435148152f35b346103765760003660031901126103765760206040517f0000000000000000000000000000000000000000000000000000000068b32fa68152f35b346103765760203660031901126103765760a0610c4060175442612431565b610c53610c4b612858565b600435614bf9565b9060409392935193845260208401526040830152660ffba26e7b326b60608301526080820152f35b34610376576000366003190112610376576020600e54604051908152f35b3461037657600036600319011261037657602061039f6133d2565b34610376576080366003190112610376576024356001600160401b03811161037657610ce49036906004016123c3565b606435610cf360443582612431565b90610d0361090a83600435612463565b90610d0e845161258a565b6000935b8551851015610da7576001850180861161050d575b8651811015610d9b576001600160a01b03610d4282896125df565b51166001600160a01b03610d56888a6125df565b511614610d6557600101610d27565b60405162461bcd60e51b815260206004820152600e60248201526d4e6f2073616d6520746f6b656e7360901b6044820152606490fd5b50600190940193610d12565b9350936000935b808510610dfb578560405180916020820160208352815180915260206040840192019060005b818110610de2575050500390f35b8251845285945060209384019390920191600101610dd4565b60005b8251811015611034576000610e138786612431565b600183018084116110205790610e2b610e319261292b565b9061284e565b15610e40575b50600101610dfe565b60249060206001600160a01b03610e5785886125df565b5116604051938480926370a0823160e01b82523060048301525afa918215611013578792829190610fda575b5081610e91575b5050610e37565b600384061580610fd1575b80610fc4575b15610f2f575090610ebb610ec092610ebb600b5461292b565b61247a565b90610eca8161292b565b6305f5e1008102908082046305f5e100148115171561050d576501d1a94a20000290808204614e20149015171561050d57610f0a610f1a91600194615337565b610f14838b6125df565b5161246d565b610f24828a6125df565b529050848880610e8a565b91610ebb610f4292610ebb600b5461292b565b610f4b8361292b565b916305f5e1008302928084046305f5e1001481151715610fb0576501d1a94a20000292808404614e201490151715610f9c578215610f995750610f9460019392610f1a92612463565b610f0a565b80fd5b634e487b7160e01b81526011600452602490fd5b634e487b7160e01b82526011600452602482fd5b5063010c8e008311610ea2565b50831515610e9c565b915091506020813d821161100b575b81610ff660209383612318565b81010312611007575186918a610e83565b5080fd5b3d9150610fe9565b50604051903d90823e3d90fd5b634e487b7160e01b83526011600452602483fd5b509360010193610dae565b3461037657602036600319011261037657602061039f600435613375565b346103765760203660031901126103765760043560005260056020526020604060002054604051908152f35b3461037657602036600319011261037657602061039f600435613352565b34610376576000366003190112610376576a08f69750e81d45e9700000600e54116113c8576001546040516370a0823160e01b815230600482015290602090829060249082906001600160a01b03165afa80156113bc5760009061137f575b6a10d0a9ee1d64709720000091501061132e57600d546112f35760135460ff81166112ae5760ff19166001176013557f0000000000000000000000000000000000000000000000000000000068b32fa6428111159081611296575b501561124657600019430143811161050d574080600a55600b546111848161292b565b8015611230576802b5e3af16b188000004600d556001810180911161050d576111ac9061292b565b8015610376576111bb9061243e565b6a115eec47f6cf7e35000000036a115eec47f6cf7e35000000811161050d57600c55600160ea1b60065542600755436008556000601255600060095580600052600460205260ff604060002054166103765760005260046020526040600020600160ff19825416179055602060405160018152f35b634e487b7160e01b600052601260045260246000fd5b60405162461bcd60e51b815260206004820152602260248201527f37204461792077696e646f7720746f20616374697661746520537461727454696044820152616d6560f01b6064820152608490fd5b905062093a80810180911161050d5742111581611161565b60405162461bcd60e51b815260206004820152601860248201527f4f6e6c7920616c6c6f77656420746f2072756e206f6e636500000000000000006044820152606490fd5b60405162461bcd60e51b8152602060048201526013602482015272726577617264206d757374206265207a65726f60681b6044820152606490fd5b60405162461bcd60e51b815260206004820152602360248201527f4d75737420737570706c7920322a31305f3136345f313030206d696e20746f6b604482015262656e7360e81b6064820152608490fd5b506020813d6020116113b4575b8161139960209383612318565b81010312610376576a10d0a9ee1d6470972000009051611106565b3d915061138c565b6040513d6000823e3d90fd5b60405162461bcd60e51b815260206004820152601e60248201527f43616e74206d696e7420746f6b656e73206265666f7265206c61756e636800006044820152606490fd5b34610376576000366003190112610376576020600c54604051908152f35b34610376576000366003190112610376576020601954604051908152f35b3461037657600036600319011261037657611465600b5461292b565b801561123057602090604051906802b5e3af16b1880000048152f35b34610376576000366003190112610376576020600254604051908152f35b6080366003190112610376576114b3612239565b6024356001600160401b038111610376576020916114d861039f923690600401612366565b90606435916044359161299d565b34610376576000366003190112610376576020601654604051908152f35b34610376576000366003190112610376576020601a54604051908152f35b346103765760003660031901126103765760206040516a115eec47f6cf7e350000008152f35b3461037657600036600319011261037657602061039f612858565b3461037657600036600319011261037657602061039f612800565b34610376576000366003190112610376576020604051660ffba26e7b326b8152f35b346103765760003660031901126103765760135460405160089190911c6001600160a01b03168152602090f35b34610376576000366003190112610376576020600b54604051908152f35b3461037657602036600319011261037657602061039f600435612732565b3461037657602061039f610b7c36612302565b34610376576000366003190112610376576104516116386125f3565b6040805194855260208501939093529183015260608201529081906080820190565b34610376576000366003190112610376576020600d54604051908152f35b3461037657604036600319011261037657604080516116978282612318565b60018152601f1982013660208301376004356116b2826125bc565b526000916116be612858565b90836017549260025491600a549060065490885b885181101561205d576116e5818a6125df565b518751602081018681523360601b6001600160601b031916604083015260548201929092526117178160748101610a2d565b5190209161172d6117288486612463565b613375565b6107e061173a828461246d565b11612039575b8661174b828461246d565b1061200e575061175b8187612431565b61176e876117698c42612431565b612463565b80891015611fd75761178e6117878a60011c8093612463565b918a612463565b906006548015611fc3578e918c91600160fd1b819004821115611fac57505050508015611f9857600160fd1b0460ff8a8e5b8981526003602052818120888252602052205416908115611f8d575b50611f82576117ec905b8261246d565b908110611dca57806107e09193868d526003602052898d20908d52602052888c20600160ff198254161790551015611f705784821015611830576001905b016116d2565b50505090809293949550925b83159586611f2057846117698261185a8361176961186a9642612431565b50611863612570565b5042612431565b6103788102908082046103781490151715611f0c579061188991612463565b606481029080820460641490151715611ef8576103786064910411611ed8575b6118b38284614bf9565b9391908194816118c581600f5461246d565b600f55818110611dce57506118d991612431565b8801808911611c0057915b60095490808710611d19576118f9908261246d565b908110611c1457600955600e546a115eec47f6cf7e3500000010611d10575b6119206144c9565b61192c60075442612431565b60018101809111611c00576009549061195261194a60125484612431565b60025461247a565b916012556103e88102908082046103e81490151715611c56579061197591612463565b610fa08111611d07575b60fa8110611cff575b6119918161519d565b6006549190821115611cee575050600160fd1b6006555b4260075414611cba5742600755436008556201000060065410611cae575b600654600160fd1b10611ca1575b6000194301438111611c005740600a548751602081019183835289820152888152611a00606082612318565b519020808a52600460205260ff888b205416611c6a57808a526004602052878a20600160ff19825416179055600a558089526005602052868920549060018201809211611c5657906003918a52600560205280888b205511611c24575b600e54611a6a828261246d565b908110611c1457600c541080611c18575b611b6a575b50600154855163a9059cbb60e01b81523360048201526024810185905290602090829060449082908c906001600160a01b03165af18015611b6057611b33575b50600e54611ace848261246d565b908110611b2f57968080809360209a600e5542601755335af150611af061296d565b50600954845192835286830152838201527fcf6fbb9dcea7d07263ab4f5c3a92f53af33dffc421d9d121e1c74b307e68189d60603392a2505190158152f35b8780fd5b611b549060203d602011611b59575b611b4c8183612318565b81019061293a565b611ac0565b503d611b42565b86513d8a823e3d90fd5b909250600b546001810190818111611c005760029082600b5501808211611c0057611b949061292b565b8015611c1457611ba39061243e565b6a115eec47f6cf7e35000000036a115eec47f6cf7e350000008111611c0057600c55611bce9061292b565b8015611bec576802b5e3af16b188000004600d5560011c9187611a80565b634e487b7160e01b88526012600452602488fd5b634e487b7160e01b89526011600452602489fd5b8880fd5b50603b600b5410611a7b565b855162461bcd60e51b815260206004820152600b60248201526a4d617820332074696d657360a81b6044820152606490fd5b634e487b7160e01b8a52601160045260248afd5b875162461bcd60e51b815260206004820152601060248201526f75736564204368616c206265666f726560801b6044820152606490fd5b600160fd1b6006556119d4565b620100006006556119c6565b855162461bcd60e51b815260206004820152600d60248201526c4e6f2073616d6520626c6f636b60981b6044820152606490fd5b611cf791615205565b6006556119a8565b5060fa611988565b50610fa061197f565b87600d55611918565b6107e0036107e08111611c565786611d309161246d565b611d3a8782612431565b91611d45888261246d565b908110611dca576009556101f882109182611dbd575b8215611d9e575b8215611d7d575b505015611a5d57611d786144c9565b611a5d565b6105e811915081611d91575b508980611d69565b6105e89150101589611d89565b91506103f0821080611db1575b91611d62565b506103f0811015611dab565b6101f88210159250611d5b565b8a80fd5b90611dd99250612431565b80611ded578803888111611c0057916118e4565b604460458a89611ea46004600c611e0f611e09611eca9961526f565b9561526f565b845196879160208301977f4e65656420746f2073656e64207265717569726564204554482e20526571756989526403932b21d160dd1b88850152611e5c8151809260208688019101612908565b83016b0103bb2b4961029b2b73a1d160a51b83820152611e86825180936020605185019101612908565b0101632077656960e01b838201520301601b19810186520184612318565b5193849262461bcd60e51b84526020600485015251809281602486015285850190612908565b601f01601f19168101030190fd5b601954611ee5848261246d565b908110611ef4576019556118a9565b8680fd5b634e487b7160e01b87526011600452602487fd5b634e487b7160e01b88526011600452602488fd5b855162461bcd60e51b8152602060048201526024808201527f4d75737420686176652076616c696420736f6c766520696e2074686520616e736044820152637765727360e01b6064820152608490fd5b5050509091929394506107e09261183c565b50915060019061182a565b90508410158d6117dc565b634e487b7160e01b8d52601260045260248dfd5b93611769611fbd9260ff959661247a565b926117c0565b634e487b7160e01b8f52601260045260248ffd5b50858c526003602052888c20848d5260205260ff898d2054168015612004575b611f82576117ec906117e6565b5084841015611ff7565b858c526003602052888c20848d5260205260ff898d205416801561200457611f82576117ec906117e6565b50806107e0036107e081111561174057634e487b7160e01b8c52601160045260248cfd5b509495965050909161183c565b34610376576000366003190112610376576106d7612800565b346103765760803660031901126103765761209c612239565b506120a561224f565b506064356001600160401b038111610376576120c5903690600401612265565b5050604051630a85bd0160e11b8152602090f35b34610376576000366003190112610376576020601754604051908152f35b34610376576020366003190112610376576004356000526004602052602060ff604060002054166040519015158152f35b346103765760003660031901126103765761045161163861248d565b346103765760403660031901126103765760043560005260036020526040600020602435600052602052602060ff604060002054166040519015158152f35b3461037657600036600319011261037657602061039f60175442612431565b34610376576000366003190112610376576020600f54604051908152f35b34610376576000366003190112610376576020601254604051908152f35b34610376576000366003190112610376576019546121fa6133d2565b9061045161220d60095460125490612431565b612215612858565b90604051948594859094939260609260808301968352602083015260408201520152565b600435906001600160a01b038216820361037657565b602435906001600160a01b038216820361037657565b9181601f84011215610376578235916001600160401b038311610376576020838186019501011161037657565b3461037657600060a0366003190112610f9957600435906001600160a01b0382168203610f995750506024356001600160a01b038116810361037657506084356001600160401b038111610376576122ee903690600401612265565b505060405163f23a6e6160e01b8152602090f35b6040906003190112610376576004359060243590565b90601f801991011681019081106001600160401b0382111761233957604052565b634e487b7160e01b600052604160045260246000fd5b6001600160401b0381116123395760051b60200190565b9080601f8301121561037657813561237d8161234f565b9261238b6040519485612318565b81845260208085019260051b82010192831161037657602001905b8282106123b35750505090565b81358152602091820191016123a6565b9080601f83011215610376578135906123db8261234f565b926123e96040519485612318565b82845260208085019360051b82010191821161037657602001915b8183106124115750505090565b82356001600160a01b038116810361037657815260209283019201612404565b9190820391821161050d57565b8015611230576a115eec47f6cf7e350000000490565b801561123057600160fd1b0490565b8115611230570490565b9190820180921161050d57565b8181029291811591840414171561050d57565b6009546012549061249e8282612431565b15612560576124bc6124c2926124b660075442612431565b92612431565b90612463565b801561253e575b600d54906103e88102918115928281046103e81484171561050d576103e8916124f86125089260025490612463565b838111156125265750829061247a565b049161123057806301e133800492612520848461247a565b93929190565b60fa811015612538575060fa9061247a565b9061247a565b60018101809111156124c957634e487b7160e01b600052601160045260246000fd5b5050600090600090600090600090565b612578612800565b80156103765761258790612454565b90565b906125948261234f565b6125a16040519182612318565b82815280926125b2601f199161234f565b0190602036910137565b8051156125c95760200190565b634e487b7160e01b600052603260045260246000fd5b80518210156125c95760209160051b010190565b61016d6125fe61248d565b5050500490811561261f57600c5491600e5491612520826117698587612431565b60009150819081908190565b9190916126416000936117696002549342612431565b80821061264c575050565b819293506126616126679260011c8092612463565b92612463565b600654801561123057600160fd1b819004831161268b57612587926117699161247a565b50600160fd1b92915050565b600090801561272b5780806001146127235760021461271b5760016101338210166001600b8310161761270d579060019060025b600181116126e4575082600019048211610f9c57500290565b9280600019048111610fb05760018416612704575b80029260011c6126cb565b809202916126f9565b6002900a919080610f9c5750565b506004919050565b505050600190565b5050600090565b610378810290808204610378149015171561050d5760025461275391612463565b606481028181046064148215171561050d57610378610bb89104106000146127c45761277e81612697565b80600f0290600f8204810361050d576274692202906207c2be82040361050d57620c08409004816297bb7002916297bb7083040361050d5761037861258792049061246d565b806018029060188204810361050d5763074692200290808204624d9b6c149015171561050d57610378900463ce09d1b0810180911161050d5790565b600161280a612858565b14612816575b60065490565b6002546017546128268142612431565b8210612833575050612810565b6128406126679142612431565b6126618360011c8092612463565b8115611230570690565b6009546012549061286b60075442612431565b6002549061288261287c8585612431565b8361247a565b916107e08102908082046107e0149015171561050d576001600160fe1b038316830361050d576128b28585612431565b9260021b821192836128fd575b5082156128f3575b5050156128d5575050600190565b6107e0916128e291612431565b066107e0036107e0811161050d5790565b10905038806128c7565b60fc109250386128bf565b60005b83811061291b5750506000910152565b818101518382015260200161290b565b60ff811161050d576001901b90565b90816020910312610376575180151581036103765790565b6001600160401b03811161233957601f01601f191660200190565b3d15612998573d9061297e82612952565b9161298c6040519384612318565b82523d6000602084013e565b606090565b9092916129a8612858565b91600091826017549060025492600a5495600654925b8a51811015613334576129d1818c6125df565b51604051612a0881610a2d60208201948d339087916054939183526001600160601b03199060601b16602083015260348201520190565b51902091612a196117288487612463565b84612a24828461246d565b11613324575b8a612a35828461246d565b106132f35750612a45818b612431565b612a538b6117698942612431565b808910156132b657612a6c6117878a60011c8093612463565b90600654801561123057600160fd1b8190048211156132a3575050801561123057600160fd1b045b8a600052600360205260406000208560005260205260ff60406000205416908115613298575b5061328d57612ac9908261246d565b90811061037657808491938a60005260036020526040600020906000526020526040600020600160ff19825416179055101561327c5788821015612b11576001905b016129be565b505050509091929380959650955b861561322b57612b33876117698442612431565b106131815785611769612b4892611863612570565b90610378820291808304610378149015171561050d57612b6791612463565b60648102908082046064149015171561050d576103786064910411613165575b612b918385614bf9565b829195929580612ba381600f5461246d565b600f558281106130645750612bc191612bbb91612431565b3461246d565b915b60095490808810612fb357612bd8908261246d565b90811061037657600955600e546a115eec47f6cf7e3500000010612fa9575b612bff6144c9565b612c0b60075442612431565b6001810180911161050d57600954612c2861194a60125483612431565b906012556103e88202918083046103e8149015171561050d57612c4a91612463565b610fa08111612fa0575b60fa8110612f98575b612c668161519d565b6006549190821115612f87575050600160fd1b6006555b4260075414612f525742600755436008556201000060065410612f46575b600654600160fd1b10612f39575b600019430143811161050d5740600a546040516020810191838352604082015260408152612cd8606082612318565b51902080600052600460205260ff60406000205416612f01578060005260046020526040600020600160ff19825416179055600a558060005260056020526040600020546001810180911161050d5760039160005260056020528060406000205511612ece575b600e54612d4c828261246d565b90811061037657600c541080612ec2575b612e3f575b5060015460405163a9059cbb60e01b81526001600160a01b03848116600483015260248201879052909160209183916044918391600091165af180156113bc57612e22575b50600e5491612db6858461246d565b92831061037657600e9290925542601755600091829182918291906001600160a01b03165af150612de561296d565b50600954604051928352602083015260408201527fcf6fbb9dcea7d07263ab4f5c3a92f53af33dffc421d9d121e1c74b307e68189d60603392a290565b612e3a9060203d602011611b5957611b4c8183612318565b612da7565b909350600b54600181019081811161050d5760029082600b550180821161050d57612e699061292b565b801561037657612e789061243e565b6a115eec47f6cf7e3500000003906a115eec47f6cf7e35000000821161050d57612ea491600c5561292b565b8015611230576802b5e3af16b188000004600d5560011c9238612d62565b50603b600b5410612d5d565b60405162461bcd60e51b815260206004820152600b60248201526a4d617820332074696d657360a81b6044820152606490fd5b60405162461bcd60e51b815260206004820152601060248201526f75736564204368616c206265666f726560801b6044820152606490fd5b600160fd1b600655612ca9565b62010000600655612c9b565b60405162461bcd60e51b815260206004820152600d60248201526c4e6f2073616d6520626c6f636b60981b6044820152606490fd5b612f9091615205565b600655612c7d565b5060fa612c5d565b50610fa0612c54565b6000600d55612bf7565b6107e0036107e0811161050d5787612fca9161246d565b612fd48882612431565b91612fdf898261246d565b908110610376576009556101f882109182613057575b8215613038575b8215613017575b505015612d3f576130126144c9565b612d3f565b6105e81191508161302b575b503880613003565b6105e89150101538613023565b91506103f082108061304b575b91612ffc565b506103f0811015613045565b6101f88210159250612ff5565b905061306f91612431565b803410613086576130809034612431565b91612bc3565b60446045613096611eca9361526f565b61313d6004600c6130a63461526f565b60405195869160208301967f4e65656420746f2073656e64207265717569726564204554482e20526571756988526403932b21d160dd1b60408501526130f58151809260208688019101612908565b83016b0103bb2b4961029b2b73a1d160a51b8382015261311f825180936020605185019101612908565b0101632077656960e01b838201520301601b19810185520183612318565b60405193849262461bcd60e51b84526020600485015251809281602486015285850190612908565b601954613172858261246d565b90811061037657601955612b87565b60405162461bcd60e51b815260206004820152607060248201527f4e6f7420656e6f75676820446966666572656e636520696e2070726576426c6f60448201527f636b54696d65202f20476f6f644c6f6f70732c20636f6d706172656420746f2060648201527f6d696e50726576696f7573426c6f636b54696d65446966666572656e6365206660848201526f756e6374696f6e207661726961626c6560801b60a482015260c490fd5b60405162461bcd60e51b8152602060048201526024808201527f4d75737420686176652076616c696420736f6c766520696e2074686520616e736044820152637765727360e01b6064820152608490fd5b505091929394959697505095612b1f565b509150600190612b0b565b905084101538612aba565b6132b192916117699161247a565b612a94565b5089600052600360205260406000208460005260205260ff6040600020541680156132e9575b61328d57612ac9906117e6565b50858410156132dc565b89600052600360205260406000208460005260205260ff6040600020541680156132e95761328d57612ac9906117e6565b5061332f8185612431565b612a2a565b50985050509091929394612b1f565b600019811461050d5760010190565b6000905b60018111613362575090565b61336f9060011c91613343565b90613356565b60048110613397576133899060011c613352565b6001810180911161050d5790565b50600190565b9190916000838201938412911290801582169115161761050d57565b8181039291600013801582851316918412161761050d57565b600954601254906133ea600754926124b68442612431565b916002546107e08102908082046107e0148115171561050d578461340d9161247a565b600281901b93906001600160fe1b0381160361050d5783811190816134bc575b81156134b2575b506134a95761344f60fc9161344a42918561339d565b6133b9565b931161346a575b505060008113156134645790565b50600090565b61344a61347892429261339d565b6000811380613495575b61348d575b80613456565b905038613487565b508181128061348257506000821315613482565b50505050600090565b9050811038613434565b60fc8611915061342d565b919260016134d3612858565b1480613ea4575b80613e98575b15613e62578251825103613e25576000906134f9612858565b90826017549360025490600a549360065491845b8b51811015613e1557613520818d6125df565b5160405161355681610a2d6020820194338d87916054939183526001600160601b03199060601b16602083015260348201520190565b519020916135676117288487612463565b84613572828461246d565b11613e05575b89613583828461246d565b10613dd85750613593818a612431565b6135a18a6117698d42612431565b80881015613d9f576135c16135ba8960011c8093612463565b9189612463565b906006548015613d8b57600160fd1b819004821115613d785750508015613d6457600160fd1b045b898952600360205260408920858a5260205260ff60408a205416908115613d59575b50613d4e5761361a908261246d565b908110611ef4578084919389895260036020526040892090895260205260408820600160ff198254161790551015613d3c578782101561365e576001905b0161350d565b50505050909192809495969750945b851561322b57856117698261185a836117696136899642612431565b610378810290808204610378149015171561102057906136a891612463565b606481029080820460641490151715610fb0576103786064910411613d20575b6136d28385614bf9565b8291959295806136e481600f5461246d565b600f55828110613cfe57506136fc91612bbb91612431565b915b60095490808810613c4957613713908261246d565b908110613be157600955600e546a115eec47f6cf7e3500000010613c40575b61373a6144c9565b61374660075442612431565b60018101809111613bcd576009549061376461194a60125484612431565b916012556103e88102908082046103e81490151715613bf1579061378791612463565b610fa08111613c37575b60fa8110613c2f575b6137a38161519d565b6006549190821115613c1e575050600160fd1b6006555b4260075414612f525742600755436008556201000060065410613c12575b600654600160fd1b10613c05575b6000194301438111613bcd5740600a546040516020810191838352604082015260408152613815606082612318565b519020808552600460205260ff604086205416612f0157808552600460205260408520600160ff19825416179055600a55808452600560205260408420549060018201809211613bf157906003918552600560205280604086205511612ece575b600e54613883828261246d565b908110613be157600c541080613be5575b613b37575b5060015460405163a9059cbb60e01b815233600482015260248101869052906020908290604490829087906001600160a01b03165af18015613b2c57613b0f575b50600e546138e8858261246d565b908110613b0b578280928192600e5542601755335af15061390761296d565b50600954604051928352602083015260408201527fcf6fbb9dcea7d07263ab4f5c3a92f53af33dffc421d9d121e1c74b307e68189d60603392a250600090815b8351811015613b02576001600160a01b0361396282866125df565b511661396e82846125df565b516040516301ffc9a760e01b8152636cdb3d1360e11b6004820152602081602481865afa869181613ae2575b50613a7d575b506040516301ffc9a760e01b81526380ac58cd60e01b6004820152602081602481865afa869181613a5d575b506139df575b5050506001905b01613947565b6139e957806139d2565b813b15613a595784809260a482936040519485938492635c46a7ef60e11b84523060048501523360248501526044840152608060648401528160848401525af19182613a49575b5050613a3e576001906139d9565b505060195550600190565b613a5291612318565b3884613a30565b8480fd5b613a7691925060203d8111611b5957611b4c8183612318565b90386139cc565b613a8757386139a0565b813b15613a595784809260c482936040519485938492637921219560e11b845230600485015233602485015260448401526001606484015260a060848401528160a48401525af19182613a49575050613a3e576001906139d9565b613afb91925060203d8111611b5957611b4c8183612318565b903861399a565b50505050600190565b8280fd5b613b279060203d602011611b5957611b4c8183612318565b6138da565b6040513d85823e3d90fd5b909350600b546001810190818111613bcd5760029082600b5501808211613bcd57613b619061292b565b8015613be157613b709061243e565b6a115eec47f6cf7e35000000036a115eec47f6cf7e350000008111613bcd57600c55613b9b9061292b565b8015613bb9576802b5e3af16b188000004600d5560011c9238613899565b634e487b7160e01b83526012600452602483fd5b634e487b7160e01b84526011600452602484fd5b8380fd5b50603b600b5410613894565b634e487b7160e01b85526011600452602485fd5b600160fd1b6006556137e6565b620100006006556137d8565b613c2791615205565b6006556137ba565b5060fa61379a565b50610fa0613791565b82600d55613732565b6107e0036107e08111613bf15787613c609161246d565b613c6a8882612431565b91613c75898261246d565b908110613cfa576009556101f882109182613ced575b8215613cce575b8215613cad575b50501561387657613ca86144c9565b613876565b6105e811915081613cc1575b503880613c99565b6105e89150101538613cb9565b91506103f0821080613ce1575b91613c92565b506103f0811015613cdb565b6101f88210159250613c8b565b8580fd5b9050613d0991612431565b80341061308657613d1a9034612431565b916136fe565b601954613d2d858261246d565b908110611007576019556136c8565b5050919293949596979850509461366d565b509150600190613658565b90508410153861360b565b634e487b7160e01b89526012600452602489fd5b613d8692916117699161247a565b6135e9565b634e487b7160e01b8b52601260045260248bfd5b5088885260036020526040882084895260205260ff6040892054168015613dce575b613d4e5761361a906117e6565b5085841015613dc1565b88885260036020526040882084895260205260ff6040892054168015613dce57613d4e5761361a906117e6565b50613e108185612431565b613578565b509798995050509091929361366d565b60405162461bcd60e51b8152602060048201526015602482015274082e4e4c2f240d8cadccee8d040dad2e6dac2e8c6d605b1b6044820152606490fd5b60405162461bcd60e51b815260206004820152600e60248201526d1391950810591a9d5cdd0810985960921b6044820152606490fd5b5060fc601954116134e0565b506005613eb660095460125490612431565b106134da565b60175461176996959294613ef49361090a93613eeb92906001600160a01b03613ee4896125bc565b511661299d565b96879142612431565b926009549460009185156144bf57835185519060018201809211613bf157036144545760018060a01b036001541695613f2d865161258a565b92845b8751811015613fac57886001600160a01b03613f4c838b6125df565b511614613f5b57600101613f30565b60405162461bcd60e51b8152602060048201526024808201527f4e6f7420616c6c6f77656420746f204552433230206d696e74204d61696e205460448201526337b5b2b760e11b6064820152608490fd5b5090929594979193965086905b80821061414c5750505060005b85811080614142575b156140f5576001600160a01b03613fe682866125df565b511690613ff381876125df565b518061400a575b506140059150613343565b613fc6565b60135460405163a9059cbb60e01b815260089190911c6001600160a01b03166004820152602481018290526020816044816000885af180156113bc576140d9575b50600182019081831161050d576140a7936020926001600160a01b0390614072908d6125df565b5116600060405180978195829463a9059cbb60e01b84526004840160209093929193604081019460018060a01b031681520152565b03925af19182156113bc576140059215613ffa576140d29060203d8111611b5957611b4c8183612318565b5038613ffa565b6140f09060203d8111611b5957611b4c8183612318565b61404b565b5093925093505060095490600a54604051928352602083015260408201528160608201527f87e5a7775b8ac2ead741e32752431bffeff76ec5f347cc202a6bad454653930b60803392a290565b5083518110613fcf565b909497600097949796939296975b89518910156144455760018901808a1161050d5761418061417a8261292b565b8a61284e565b614214575b8a51811015614208576001600160a01b036141a0828d6125df565b51166001600160a01b036141b48c8e6125df565b5116146141c357600101614185565b60405162461bcd60e51b815260206004820152601b60248201527f4e6f207072696e74696e67205468652073616d6520746f6b656e7300000000006044820152606490fd5b5060019098019761415a565b50989593989694909192965b88156144365788821061442e575b60005b89811080614424575b15614401576001810180821161050d5761425661425c9161292b565b8861284e565b15614270575b61426b90613343565b614231565b6000806001600160a01b03614285848c6125df565b511660405160208101906370a0823160e01b8252306024820152602481526142ae604482612318565b51915afa6142ba61296d565b90806143f5575b156143ed57805160208083019260009281010312610f995750515b806142e8575b50614262565b896003830615806143e4575b806143d7575b15614371576143089161247a565b906143128161292b565b916305f5e1008302928084046305f5e100148115171561050d576501d1a94a20000292808404614e20149015171561050d5761436a826143648f9361426b9661435a91615337565b610f1483866125df565b926125df565b52906142e2565b61437a9161247a565b906143848161292b565b916305f5e1008302928084046305f5e100148115171561050d576501d1a94a20000292808404614e20149015171561050d5782156103765761436a826143648f9361426b966143d291612463565b61435a565b5063010c8e0081116142fa565b508215156142f4565b5060006142dc565b506020815110156142c1565b50949097509795929097600019810190811161050d57600190915b019091613fb9565b508751811061423a565b88915061422e565b9491989693600191985061441c565b98959398969490919296614220565b60405162461bcd60e51b815260206004820152603a60248201527f4d696e74546f2068617320746f206861766520616e206578747261206164647260448201527f65737320636f6d706172656420746f20457874726146756e64730000000000006064820152608490fd5b9550509250505090565b6000606447818102918115918304141715610fb057670214e8348c4d796090048060155560c881106000146146ce57806501a3185c500002906501a3185c5000820403610fb05760c890045b601855614527600e5460105490612431565b614536600f5460115490612431565b60015460135460405163a9059cbb60e01b81526001600160a01b0360089290921c8216600482015260248101859052929392916020918391168187816044810103925af180156146c3576146a6575b50614593601454918261246d565b908110613b0b57601455476018546107e08102908082046107e01490151715613bcd5760011c9081605002916050830403613bcd57839291101561469c576013548291829182919060081c6001600160a01b03165af16145f161296d565b5015614661576001601a5560135460081c6001600160a01b0316803b1561100757818091600460405180948193636645e41360e01b83525af1801561465657614646575b50505b600e54601055600f54601155565b8161465091612318565b38614635565b6040513d84823e3d90fd5b60405162461bcd60e51b8152602060048201526013602482015272115512081d1c985b9cd9995c8819985a5b1959606a1b6044820152606490fd5b5050601a55614638565b6146be9060203d602011611b5957611b4c8183612318565b614585565b6040513d86823e3d90fd5b6101908110156146fa57806502ba7def300002906502ba7def3000820403610fb0576101909004614515565b610320811015614726578065048c27395000029065048c27395000820403610fb0576103209004614515565b6106408110156147525780650746a52880000290650746a5288000820403610fb0576106409004614515565b610bb881101561477e5780650ae9f7bcc0000290650ae9f7bcc000820403610fb057610bb89004614515565b6113888110156147aa5780650da475abf0000290650da475abf000820403610fb0576113889004614515565b6127108110156147d657806512309ce5400002906512309ce54000820403610fb0576127109004614515565b614e208110156148025780651b48eb57e0000290651b48eb57e000820403610fb057614e209004614515565b619c4081101561482e5780652d79883d20000290652d79883d2000820403610fb057619c409004614515565b620186a081101561485c5780655af3107a40000290655af3107a4000820403610fb057620186a09004614515565b62030d4081101561488a578065886c98b76000029065886c98b76000820403610fb05762030d409004614515565b6207a1208110156148b8578065e35fa931a000029065e35fa931a000820403610fb0576207a1209004614515565b620f42408110156148e857806601c6bf5263400002906601c6bf52634000820403610fb057620f42409004614515565b806601c6bf5263400002906601c6bf52634000820403610fb057620f42409004614515565b6009546012549061491e8282612431565b15614981576124bc614936926124b660075442612431565b9061493f6125f3565b50505090821561496f575b62015180820282810462015180148315171561050d578361496a91612463565b929190565b916001810180911161050d579161494a565b5050600090600090600090565b90600d54916103e88102908082046103e8149015171561050d5760016149b76002548093612463565b9214801580614ab1575b156149db575050506149d76103e891829061247a565b0490565b60fa8310156149f6575050506149d76103e89160fa9061247a565b80614aa6575b614a0f575b506149d7906103e89261247a565b614a1b60075442612431565b6001810180911161050d57614a3560095460125490612431565b908115614a8c575b614a556103e895936117696149d79694600494612463565b1015614a6957506107d0905b925090614a01565b90610fa0821180614a84575b15614a6157610fa09150614a61565b506001614a75565b939192906001810180911161050d57919390929190614a3d565b506107d082116149fc565b506103e883116149c1565b600080916103788102908082046103781490151715610fb057600254614ae191612463565b606481028181046064148215171561102057610378900491610bb8831015614bb85750614b0d81612697565b80600f0290600f8204810361050d576274692202906207c2be82040361050d57620c08409004816297bb7002916297bb7083040361050d57610378614b5392049061246d565b601a549182614b63575b50505090565b6107d09192935010600014614b92576305f5e10091610ebb614b88926018549061247a565b045b388080614b5d565b5060185480610140029061014082040361050d57600a91614bb29161247a565b04614b8a565b9080601802906018820481036110205763074692200290808204624d9b6c1490151715610fb05761037890049063ce09d1b08201809211610f9c5750614b53565b91909160009182614c08612800565b801561100757614c1790612454565b9460175493614c268542612431565b94811561502057614c3d61287c6103ce8489612463565b5060065491838110614fdf575082611769614c589242612431565b9060025491808310614f7a575b5080915015613b0b57614c7790612454565b91614c828286612463565b90600d54916103e88102908082046103e81490151715610fb057614ca96002548092612463565b915060fa821015614ecb575050614cc56103e89160fa9061247a565b0491614cd18286612463565b90614ce060009160131c615359565b90610fa09280614e9f575b50610fa08311614e95575b6103e8831080614e8e575b15614dd057506103e89150614d1790829061247a565b0490600019810181811161050d5761253882614d55614d6796614d4f614d4984614d44614d4f998e612463565b61498e565b8661247a565b9061246d565b99614d628260009a612463565b615071565b9184614d71575b50565b670de0b6b3a76400008302838104670de0b6b3a76400001484151715610fb057614da18664746a52880092612463565b1015614d6e579091508364746a528800029064746a52880082048503610f9c5750670de0b6b3a7640000900490565b6101f483109081614deb575b50506103e891614d179161247a565b614df760075442612431565b9060018201809211610f9c5750916103e893916004614e3a614e31614d1796614e2560095460125490612431565b908115614e8557612463565b60025490612463565b1080918192614e7d575b5015614e5a57506101f491505b91819350614ddc565b60fa83109081614e74575b5015614e515760fa9150614e51565b90501538614e65565b905038614e44565b60019150612463565b5080614d01565b610fa09250614cf6565b9092506002546103e88102908082046103e81490151715613bcd5790614ec491612463565b9138614ceb565b6107d08211614ee3575b50614cc5906103e89261247a565b614eef60075442612431565b6001810180911161050d57614f0960095460125490612431565b908115614f60575b614f296103e89593611769614cc59694600494612463565b1015614f3d57506107d0905b925090614ed5565b90610fa0821180614f58575b15614f3557610fa09150614f35565b506001614f49565b939192906001810180911161050d57919390929190614f11565b614f9290614f8c8460011c8092612463565b93612463565b908015614fcb57600160fd1b819004831115614fb95750600160fd1b9150505b8038614c65565b614fc6926117699161247a565b614fb2565b634e487b7160e01b85526012600452602485fd5b9250505083945061253881615005614fff82614d4481614d67989a612463565b8261247a565b97614d628261501a614fff6103ce838d612463565b99612463565b60405162461bcd60e51b815260206004820152602360248201527f436f6d70656e736174696f6e206d75737420626520677265617465722074686160448201526206e20360ec1b6064820152608490fd5b9061507e9060131c615359565b91610fa09180615171575b50610fa08211615167575b6103e882108061515c575b156150b45750506149d76103e891829061247a565b60011480615151575b6150cf575b6149d7906103e89261247a565b6150db60075442612431565b906001820180921161050d576103e8926004615106614e316149d795614e2560095460125490612431565b108080615146575b1561512357506101f491505b925090506150c2565b60fa8310908161513d575b501561511a5760fa915061511a565b9050153861512e565b506101f4831061510e565b506101f481106150bd565b50600181141561509f565b610fa09150615094565b909150600254906103e88202918083046103e8149015171561050d5761519691612463565b9038615089565b607d81111561037657806103e8600160fd1b098180600003168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030291600181806000030401821515607d03029160000304170290565b80820290600019838209908280831092039180830392836103e811156103765714615264577fac083126e978d4fdf3b645a1cac083126e978d4fdf3b645a1cac083126e978d5936103e8910990828211900360fd1b910360031c170290565b50506103e891500490565b801561531757600081805b615303575061528881612952565b906152966040519283612318565b808252601f196152a582612952565b013660208401375b809280156152fc57600019820191821161050d578193600a8206603001928360301161050d57845111156125c957600a9260f81b6001600160f81b03191660001a908401601f015304916152ad565b5050905090565b9061530f600a91613343565b91048061527a565b50604051615326604082612318565b60018152600360fc1b602082015290565b908015610376578061534c6153529284612463565b9261284e565b6133895790565b600060018210615554576002821061554957600a821061553e5760648210615533576103e88210615528576161a8821061551c5761c3508210615510576201e8488210615504576203d09082106154f7576207a12082106154e557620f424082106154d957622dc6c082106154c757506298968081106154bc576301312d0081106154b1576302faf08081106154a6576305f5e100811061549b57630ee6b280811061548f57631dcd6500811061548357633b9aca008110615477576377359400811061546b5763b2d05e00811061545f5764012a05f2008110615453576509184e72a000624c4b409091048181029182040361050d5790565b5066246139ca80000090565b506612309ce540000090565b506609184e72a0000090565b5066048c273950000090565b50660246139ca8000090565b5066012309ce54000090565b50659184e72a000090565b506548c27395000090565b5065246139ca800090565b506512309ce5400090565b809150610f9c5750650da475abf00090565b50506509184e72a00090565b809150610f9c5750650610344c6aaa90565b90505065048c2739500090565b505065048c2739500090565b5050650246139ca80090565b505065012309ce540090565b5050649184e72a0090565b50506448c273950090565b505064246139ca8090565b50506412309ce54090565b50506409184e72a09056fea26469706673582212208b6a2f4e48277282ae24d5483fd67055ae947a614a18019515154e41704c856b64736f6c634300081c0033

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

000000000000000000000000b379a851ac41bcdf0c2564b88916b10e5a08daae0000000000000000000000003ea249809f032b1f5ae7b1dd4986490d05ee2dc2

-----Decoded View---------------
Arg [0] : token (address): 0xb379A851AC41bcDF0c2564b88916B10E5A08daAe
Arg [1] : lp (address): 0x3eA249809f032b1F5AE7B1Dd4986490d05eE2dC2

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000b379a851ac41bcdf0c2564b88916b10e5a08daae
Arg [1] : 0000000000000000000000003ea249809f032b1f5ae7b1dd4986490d05ee2dc2


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
0x925C42A57328FD8a7b07ecA444A34963e07C8999
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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