Contract 0x6d5Ba663dDCa573557c8420256Dc85F31D9762B0

Contract Overview

Balance:
0 Ether

Token:
Txn Hash
Method
Block
From
To
Value
0xff5d1464e6cf52e21182a90a3a14fcfafc943b963af114342e64b8b6dea8207bFulfill Randomne...105803312022-04-28 1:24:0867 days 22 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000146541.06837162
0x26cd713b384eb0c8c2c016b3aaae21a102985eee5458a10cdf7449eb6e38629dFulfill Randomne...105417272022-04-21 7:32:3574 days 16 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000116721.16223081
0x54ed7b04ee0c55bea50af843f8fe204ac69a10bec38b2e309b9b4b7048e0d61dFulfill Randomne...105319432022-04-19 14:31:1976 days 9 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.00019371.50000007
0x869f744ccfb261dac0d0ec74787189b2983e5917a84ebe574f7d5f32b504290eFulfill Randomne...105090212022-04-15 14:41:2680 days 9 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000126411.00000002
0x06f3026df298379e5828e610f23d5cc25158f54ab1f2ee1fb8030026d3be56a2Fulfill Randomne...105089712022-04-15 14:28:5580 days 9 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000142591.00000002
0xbf4a77c3660621bbf61167fbf0226f875e951dedc7147df236b26cff09a5a51bFulfill Randomne...105089702022-04-15 14:28:4080 days 9 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000126321.00000002
0x55c9ca3120dfcd11468879671e8ead853868e29b8307a5792f69dd8b7f4b930fFulfill Randomne...105079482022-04-15 10:12:3580 days 13 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000089661.00000004
0xf8b378609119060679b4730d280a827bd21c96b6dd1162bac9148c948dbca104Fulfill Randomne...105078952022-04-15 9:59:1780 days 13 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.00010911.00000004
0x290285c116d89eea30cec58b10711a79523e39134a97376c075c32569bcdd66aFulfill Randomne...105078432022-04-15 9:46:1580 days 14 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000131791.00000004
0x95b3184421ed96cea3b1429e69272e0f7b9a1b1ae589112aa63e377e249f07f3Fulfill Randomne...105078072022-04-15 9:37:1180 days 14 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000131781.00000004
0x3256e9716aad263c8dcb2c730a1c72a6ef979e91af88c91b11275efdc8bac53dFulfill Randomne...105077092022-04-15 9:12:3580 days 14 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000131781.00000004
0x0d1f0d2a2867e37b8766c8ee5e6ab3924348fc3028570851d3c2b65181ae5530Fulfill Randomne...105030292022-04-14 13:32:3481 days 10 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000098281.00000051
0x1c730bf3f6ef4d662bb6872c1a46689b950b2648452390383bf284038893ae86Fulfill Randomne...105029342022-04-14 13:08:4681 days 10 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000131841.00000011
0x8b6c15b4c6074e480a7809761d4e3fd5bf987ce05b975d0c2c622981c555c7a0Fulfill Randomne...104993142022-04-13 21:41:0882 days 2 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000126311.00000009
0x9cc20be0a1b45a79c87ec131974db3c914c275318407feb62d2ece69e840225aFulfill Randomne...104967412022-04-13 10:51:3882 days 13 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000091821.00000003
0x653943d95fcb5f3bc7102d6d5955e07475af22bcf82f44ff43cad5268fb5dab6Fulfill Randomne...104967172022-04-13 10:45:3882 days 13 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.00010371.00000005
0x5371d378f38cf1d106bfd1337bc1562edc0567b206e9154415d95a87b9dd4831Fulfill Randomne...104966932022-04-13 10:39:3782 days 13 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.00013181.00000008
0xb29515bd0a0e03b406baa4936837e0ee91e3b85daa5f331fca4908a12ba96d4dFulfill Randomne...104952972022-04-13 4:38:2582 days 19 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000099231.08100001
0x119282170793b6bd7fbd64f62909c8ed4121f26cc86507a4c3db4ae438665265Fulfill Randomne...104952732022-04-13 4:32:2582 days 19 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000109211.08100001
0x858e273abb9f664c47c5d48e3c7248720a541c101df0939574da02939c283627Fulfill Randomne...104952722022-04-13 4:32:1082 days 19 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000142481.08100001
0x63dc8eee8ae82cd793673b5df10b71531f7f04075c27026953f318ae2ed42e0dFulfill Randomne...104952492022-04-13 4:26:2582 days 19 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000149581.09000001
0xcb931489b5a9bef8c2268e4f0a3fdd7d6653c76a538df1ed438def271dcf7d4cFulfill Randomne...104679672022-04-08 10:00:4487 days 13 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000126451.00000001
0x6e09d5ef71fdaa0a4389cbaa8ae41be493b47700d38ba8cc4e9634e2c01346cfFulfill Randomne...104671172022-04-08 6:26:0987 days 17 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000139911.00000004
0xb2e5214e0ccc2d08ce6064140a445f883edd32837bc8649dcf08dd4194b58e8cFulfill Randomne...104669632022-04-08 5:47:2587 days 18 hrs ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000129091.00000004
0xf5a58a5d6f32b02d7c5c05a7c83346e64443b5ea8d2c1cca4497320ff84866a5Fulfill Randomne...104654702022-04-07 23:29:3288 days 29 mins ago0x06b5959c3d8212a5718c4b5d6827aa7b2f29e2d5 IN  0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether0.000137211.00000003
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xff5d1464e6cf52e21182a90a3a14fcfafc943b963af114342e64b8b6dea8207b105803312022-04-28 1:24:0867 days 22 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b0 0xc8e3273c1d352dc2b2933bf44bccdd9894002d1b0 Ether
0xff5d1464e6cf52e21182a90a3a14fcfafc943b963af114342e64b8b6dea8207b105803312022-04-28 1:24:0867 days 22 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b00x00000000000000000000000000000000000000010 Ether
0xff5d1464e6cf52e21182a90a3a14fcfafc943b963af114342e64b8b6dea8207b105803312022-04-28 1:24:0867 days 22 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b00x00000000000000000000000000000000000000010 Ether
0xff5d1464e6cf52e21182a90a3a14fcfafc943b963af114342e64b8b6dea8207b105803312022-04-28 1:24:0867 days 22 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b00x00000000000000000000000000000000000000050 Ether
0xff5d1464e6cf52e21182a90a3a14fcfafc943b963af114342e64b8b6dea8207b105803312022-04-28 1:24:0867 days 22 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b00x00000000000000000000000000000000000000050 Ether
0xff5d1464e6cf52e21182a90a3a14fcfafc943b963af114342e64b8b6dea8207b105803312022-04-28 1:24:0867 days 22 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b00x00000000000000000000000000000000000000050 Ether
0xff5d1464e6cf52e21182a90a3a14fcfafc943b963af114342e64b8b6dea8207b105803312022-04-28 1:24:0867 days 22 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b00x00000000000000000000000000000000000000050 Ether
0xff5d1464e6cf52e21182a90a3a14fcfafc943b963af114342e64b8b6dea8207b105803312022-04-28 1:24:0867 days 22 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b00x00000000000000000000000000000000000000050 Ether
0xff5d1464e6cf52e21182a90a3a14fcfafc943b963af114342e64b8b6dea8207b105803312022-04-28 1:24:0867 days 22 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b00x00000000000000000000000000000000000000010 Ether
0xd91ffa3871591e3ef2acae7360255fb45bc4fc7b9545f4359d87936ccf5e209b105803202022-04-28 1:21:2267 days 22 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b0 0x245330351344f9301690d5d8de2a07f5f32e11490 Ether
0xd91ffa3871591e3ef2acae7360255fb45bc4fc7b9545f4359d87936ccf5e209b105803202022-04-28 1:21:2267 days 22 hrs ago 0xc8e3273c1d352dc2b2933bf44bccdd9894002d1b 0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether
0x26cd713b384eb0c8c2c016b3aaae21a102985eee5458a10cdf7449eb6e38629d105417272022-04-21 7:32:3574 days 16 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b0 0x761703a56c22acb7512b18f5bba4b3d2389357a40 Ether
0x26cd713b384eb0c8c2c016b3aaae21a102985eee5458a10cdf7449eb6e38629d105417272022-04-21 7:32:3574 days 16 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b00x00000000000000000000000000000000000000010 Ether
0x26cd713b384eb0c8c2c016b3aaae21a102985eee5458a10cdf7449eb6e38629d105417272022-04-21 7:32:3574 days 16 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b00x00000000000000000000000000000000000000010 Ether
0x26cd713b384eb0c8c2c016b3aaae21a102985eee5458a10cdf7449eb6e38629d105417272022-04-21 7:32:3574 days 16 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b00x00000000000000000000000000000000000000050 Ether
0x26cd713b384eb0c8c2c016b3aaae21a102985eee5458a10cdf7449eb6e38629d105417272022-04-21 7:32:3574 days 16 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b00x00000000000000000000000000000000000000050 Ether
0x26cd713b384eb0c8c2c016b3aaae21a102985eee5458a10cdf7449eb6e38629d105417272022-04-21 7:32:3574 days 16 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b00x00000000000000000000000000000000000000050 Ether
0x26cd713b384eb0c8c2c016b3aaae21a102985eee5458a10cdf7449eb6e38629d105417272022-04-21 7:32:3574 days 16 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b00x00000000000000000000000000000000000000050 Ether
0x26cd713b384eb0c8c2c016b3aaae21a102985eee5458a10cdf7449eb6e38629d105417272022-04-21 7:32:3574 days 16 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b00x00000000000000000000000000000000000000050 Ether
0x26cd713b384eb0c8c2c016b3aaae21a102985eee5458a10cdf7449eb6e38629d105417272022-04-21 7:32:3574 days 16 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b00x00000000000000000000000000000000000000010 Ether
0x8262e20e1adfcc781a57b4b71bea463f3b9f0f76fc87cbd8d9bb4a9533338c8e105417162022-04-21 7:29:5074 days 16 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b0 0x245330351344f9301690d5d8de2a07f5f32e11490 Ether
0x8262e20e1adfcc781a57b4b71bea463f3b9f0f76fc87cbd8d9bb4a9533338c8e105417162022-04-21 7:29:5074 days 16 hrs ago 0x761703a56c22acb7512b18f5bba4b3d2389357a4 0x6d5ba663ddca573557c8420256dc85f31d9762b00 Ether
0x54ed7b04ee0c55bea50af843f8fe204ac69a10bec38b2e309b9b4b7048e0d61d105319432022-04-19 14:31:1976 days 9 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b0 0xc8e3273c1d352dc2b2933bf44bccdd9894002d1b0 Ether
0x54ed7b04ee0c55bea50af843f8fe204ac69a10bec38b2e309b9b4b7048e0d61d105319432022-04-19 14:31:1976 days 9 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b00x00000000000000000000000000000000000000010 Ether
0x54ed7b04ee0c55bea50af843f8fe204ac69a10bec38b2e309b9b4b7048e0d61d105319432022-04-19 14:31:1976 days 9 hrs ago 0x6d5ba663ddca573557c8420256dc85f31d9762b00x00000000000000000000000000000000000000010 Ether
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
VORCoordinator

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-04-09
*/

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

interface IVORConsumerBase {
    function rawFulfillRandomness(bytes32 requestId, uint256 randomness) external;
}



interface BlockHashStoreInterface {
    function getBlockhash(uint256 number) external view returns (bytes32);
}

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20_Ex {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) external returns (bool);

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}


/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) return (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a % b;
    }
}


/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain`call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}


/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor () internal {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

        _;

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

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

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}


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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () internal {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

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

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




contract VOR {
    // See https://www.secg.org/sec2-v2.pdf, section 2.4.1, for these constants.
    uint256 private constant GROUP_ORDER = // Number of points in Secp256k1
        // solium-disable-next-line indentation
        0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141;
    // Prime characteristic of the galois field over which Secp256k1 is defined
    uint256 private constant FIELD_SIZE =
        // solium-disable-next-line indentation
        0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F;
    uint256 private constant WORD_LENGTH_BYTES = 0x20;

    // (base^exponent) % FIELD_SIZE
    // Cribbed from https://medium.com/@rbkhmrcr/precompiles-solidity-e5d29bd428c4
    function bigModExp(uint256 base, uint256 exponent) internal view returns (uint256 exponentiation) {
        uint256 callResult;
        uint256[6] memory bigModExpContractInputs;
        bigModExpContractInputs[0] = WORD_LENGTH_BYTES; // Length of base
        bigModExpContractInputs[1] = WORD_LENGTH_BYTES; // Length of exponent
        bigModExpContractInputs[2] = WORD_LENGTH_BYTES; // Length of modulus
        bigModExpContractInputs[3] = base;
        bigModExpContractInputs[4] = exponent;
        bigModExpContractInputs[5] = FIELD_SIZE;
        uint256[1] memory output;
        assembly {
            // solhint-disable-line no-inline-assembly
            callResult := staticcall(
                not(0), // Gas cost: no limit
                0x05, // Bigmodexp contract address
                bigModExpContractInputs,
                0xc0, // Length of input segment: 6*0x20-bytes
                output,
                0x20 // Length of output segment
            )
        }
        if (callResult == 0) {
            revert("bigModExp failure!");
        }
        return output[0];
    }

    // Let q=FIELD_SIZE. q % 4 = 3, ∴ x≡r^2 mod q ⇒ x^SQRT_POWER≡±r mod q.  See
    // https://en.wikipedia.org/wiki/Modular_square_root#Prime_or_prime_power_modulus
    uint256 private constant SQRT_POWER = (FIELD_SIZE + 1) >> 2;

    // Computes a s.t. a^2 = x in the field. Assumes a exists
    function squareRoot(uint256 x) internal view returns (uint256) {
        return bigModExp(x, SQRT_POWER);
    }

    // The value of y^2 given that (x,y) is on secp256k1.
    function ySquared(uint256 x) internal pure returns (uint256) {
        // Curve is y^2=x^3+7. See section 2.4.1 of https://www.secg.org/sec2-v2.pdf
        uint256 xCubed = mulmod(x, mulmod(x, x, FIELD_SIZE), FIELD_SIZE);
        return addmod(xCubed, 7, FIELD_SIZE);
    }

    // True iff p is on secp256k1
    function isOnCurve(uint256[2] memory p) internal pure returns (bool) {
        return ySquared(p[0]) == mulmod(p[1], p[1], FIELD_SIZE);
    }

    // Hash x uniformly into {0, ..., FIELD_SIZE-1}.
    function fieldHash(bytes memory b) internal pure returns (uint256 x_) {
        x_ = uint256(keccak256(b));
        // Rejecting if x >= FIELD_SIZE corresponds to step 2.1 in section 2.3.4 of
        // http://www.secg.org/sec1-v2.pdf , which is part of the definition of
        // string_to_point in the IETF draft
        while (x_ >= FIELD_SIZE) {
            x_ = uint256(keccak256(abi.encodePacked(x_)));
        }
    }

    // Hash b to a random point which hopefully lies on secp256k1.
    function newCandidateSecp256k1Point(bytes memory b) internal view returns (uint256[2] memory p) {
        p[0] = fieldHash(b);
        p[1] = squareRoot(ySquared(p[0]));
        if (p[1] % 2 == 1) {
            p[1] = FIELD_SIZE - p[1];
        }
    }

    // Domain-separation tag for initial hash in hashToCurve.
    uint256 constant HASH_TO_CURVE_HASH_PREFIX = 1;

    // Cryptographic hash function onto the curve.
    //
    // Corresponds to algorithm in section 5.4.1.1 of the draft standard. (But see
    // DESIGN NOTES above for slight differences.)
    //
    // TODO(alx): Implement a bounded-computation hash-to-curve, as described in
    // "Construction of Rational Points on Elliptic Curves over Finite Fields"
    // http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.831.5299&rep=rep1&type=pdf
    // and suggested by
    // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-01#section-5.2.2
    // (Though we can't used exactly that because secp256k1's j-invariant is 0.)
    //
    // This would greatly simplify the analysis in "OTHER SECURITY CONSIDERATIONS"
    // https://www.pivotaltracker.com/story/show/171120900
    function hashToCurve(uint256[2] memory pk, uint256 input) internal view returns (uint256[2] memory rv) {
        rv = newCandidateSecp256k1Point(abi.encodePacked(HASH_TO_CURVE_HASH_PREFIX, pk, input));
        while (!isOnCurve(rv)) {
            rv = newCandidateSecp256k1Point(abi.encodePacked(rv[0]));
        }
    }

    /** *********************************************************************
     * @notice Check that product==scalar*multiplicand
     *
     * @dev Based on Vitalik Buterin's idea in ethresear.ch post cited below.
     *
     * @param multiplicand: secp256k1 point
     * @param scalar: non-zero GF(GROUP_ORDER) scalar
     * @param product: secp256k1 expected to be multiplier * multiplicand
     * @return verifies true iff product==scalar*multiplicand, with cryptographically high probability
     */
    function ecmulVerify(
        uint256[2] memory multiplicand,
        uint256 scalar,
        uint256[2] memory product
    ) internal pure returns (bool verifies) {
        require(scalar != 0, "scalar must not be 0"); // Rules out an ecrecover failure case
        uint256 x = multiplicand[0]; // x ordinate of multiplicand
        uint8 v = multiplicand[1] % 2 == 0 ? 27 : 28; // parity of y ordinate
        // https://ethresear.ch/t/you-can-kinda-abuse-ecrecover-to-do-ecmul-in-secp256k1-today/2384/9
        // Point corresponding to address ecrecover(0, v, x, s=scalar*x) is
        // (x⁻¹ mod GROUP_ORDER) * (scalar * x * multiplicand - 0 * g), i.e.
        // scalar*multiplicand. See https://crypto.stackexchange.com/a/18106
        bytes32 scalarTimesX = bytes32(mulmod(scalar, x, GROUP_ORDER));
        address actual = ecrecover(bytes32(0), v, bytes32(x), scalarTimesX);
        // Explicit conversion to address takes bottom 160 bits
        address expected = address(uint256(keccak256(abi.encodePacked(product))));
        return (actual == expected);
    }

    // Returns x1/z1-x2/z2=(x1z2-x2z1)/(z1z2) in projective coordinates on P¹(𝔽ₙ)
    function projectiveSub(
        uint256 x1,
        uint256 z1,
        uint256 x2,
        uint256 z2
    ) internal pure returns (uint256 x3, uint256 z3) {
        uint256 num1 = mulmod(z2, x1, FIELD_SIZE);
        uint256 num2 = mulmod(FIELD_SIZE - x2, z1, FIELD_SIZE);
        (x3, z3) = (addmod(num1, num2, FIELD_SIZE), mulmod(z1, z2, FIELD_SIZE));
    }

    // Returns x1/z1*x2/z2=(x1x2)/(z1z2), in projective coordinates on P¹(𝔽ₙ)
    function projectiveMul(
        uint256 x1,
        uint256 z1,
        uint256 x2,
        uint256 z2
    ) internal pure returns (uint256 x3, uint256 z3) {
        (x3, z3) = (mulmod(x1, x2, FIELD_SIZE), mulmod(z1, z2, FIELD_SIZE));
    }

    /** **************************************************************************
      @notice Computes elliptic-curve sum, in projective co-ordinates

      @dev Using projective coordinates avoids costly divisions

      @dev To use this with p and q in affine coordinates, call
      @dev projectiveECAdd(px, py, qx, qy). This will return
      @dev the addition of (px, py, 1) and (qx, qy, 1), in the
      @dev secp256k1 group.

      @dev This can be used to calculate the z which is the inverse to zInv
      @dev in isValidVOROutput. But consider using a faster

      @dev This function assumes [px,py,1],[qx,qy,1] are valid projective
           coordinates of secp256k1 points. That is safe in this contract,
           because this method is only used by linearCombination, which checks
           points are on the curve via ecrecover.
      **************************************************************************
      @param px The first affine coordinate of the first summand
      @param py The second affine coordinate of the first summand
      @param qx The first affine coordinate of the second summand
      @param qy The second affine coordinate of the second summand

      (px,py) and (qx,qy) must be distinct, valid secp256k1 points.
      **************************************************************************
      Return values are projective coordinates of [px,py,1]+[qx,qy,1] as points
      on secp256k1, in P²(𝔽ₙ)
      @return sx 
      @return sy
      @return sz
  */
    function projectiveECAdd(
        uint256 px,
        uint256 py,
        uint256 qx,
        uint256 qy
    )
        internal
        pure
        returns (uint256 sx, uint256 sy, uint256 sz)
    {
        // See "Group law for E/K : y^2 = x^3 + ax + b", in section 3.1.2, p. 80,
        // "Guide to Elliptic Curve Cryptography" by Hankerson, Menezes and Vanstone
        // We take the equations there for (sx,sy), and homogenize them to
        // projective coordinates. That way, no inverses are required, here, and we
        // only need the one inverse in affineECAdd.

        // We only need the "point addition" equations from Hankerson et al. Can
        // skip the "point doubling" equations because p1 == p2 is cryptographically
        // impossible, and require'd not to be the case in linearCombination.

        // Add extra "projective coordinate" to the two points
        (uint256 z1, uint256 z2) = (1, 1);

        // (lx, lz) = (qy-py)/(qx-px), i.e., gradient of secant line.
        uint256 lx = addmod(qy, FIELD_SIZE - py, FIELD_SIZE);
        uint256 lz = addmod(qx, FIELD_SIZE - px, FIELD_SIZE);

        uint256 dx; // Accumulates denominator from sx calculation
        // sx=((qy-py)/(qx-px))^2-px-qx
        (sx, dx) = projectiveMul(lx, lz, lx, lz); // ((qy-py)/(qx-px))^2
        (sx, dx) = projectiveSub(sx, dx, px, z1); // ((qy-py)/(qx-px))^2-px
        (sx, dx) = projectiveSub(sx, dx, qx, z2); // ((qy-py)/(qx-px))^2-px-qx

        uint256 dy; // Accumulates denominator from sy calculation
        // sy=((qy-py)/(qx-px))(px-sx)-py
        (sy, dy) = projectiveSub(px, z1, sx, dx); // px-sx
        (sy, dy) = projectiveMul(sy, dy, lx, lz); // ((qy-py)/(qx-px))(px-sx)
        (sy, dy) = projectiveSub(sy, dy, py, z1); // ((qy-py)/(qx-px))(px-sx)-py

        if (dx != dy) {
            // Cross-multiply to put everything over a common denominator
            sx = mulmod(sx, dy, FIELD_SIZE);
            sy = mulmod(sy, dx, FIELD_SIZE);
            sz = mulmod(dx, dy, FIELD_SIZE);
        } else {
            // Already over a common denominator, use that for z ordinate
            sz = dx;
        }
    }

    // p1+p2, as affine points on secp256k1.
    //
    // invZ must be the inverse of the z returned by projectiveECAdd(p1, p2).
    // It is computed off-chain to save gas.
    //
    // p1 and p2 must be distinct, because projectiveECAdd doesn't handle
    // point doubling.
    function affineECAdd(
        uint256[2] memory p1,
        uint256[2] memory p2,
        uint256 invZ
    ) internal pure returns (uint256[2] memory) {
        uint256 x;
        uint256 y;
        uint256 z;
        (x, y, z) = projectiveECAdd(p1[0], p1[1], p2[0], p2[1]);
        require(mulmod(z, invZ, FIELD_SIZE) == 1, "invZ must be inverse of z");
        // Clear the z ordinate of the projective representation by dividing through
        // by it, to obtain the affine representation
        return [mulmod(x, invZ, FIELD_SIZE), mulmod(y, invZ, FIELD_SIZE)];
    }

    // True iff address(c*p+s*g) == lcWitness, where g is generator. (With
    // cryptographically high probability.)
    function verifyLinearCombinationWithGenerator(
        uint256 c,
        uint256[2] memory p,
        uint256 s,
        address lcWitness
    ) internal pure returns (bool) {
        // Rule out ecrecover failure modes which return address 0.
        require(lcWitness != address(0), "bad witness");
        uint8 v = (p[1] % 2 == 0) ? 27 : 28; // parity of y-ordinate of p
        bytes32 pseudoHash = bytes32(GROUP_ORDER - mulmod(p[0], s, GROUP_ORDER)); // -s*p[0]
        bytes32 pseudoSignature = bytes32(mulmod(c, p[0], GROUP_ORDER)); // c*p[0]
        // https://ethresear.ch/t/you-can-kinda-abuse-ecrecover-to-do-ecmul-in-secp256k1-today/2384/9
        // The point corresponding to the address returned by
        // ecrecover(-s*p[0],v,p[0],c*p[0]) is
        // (p[0]⁻¹ mod GROUP_ORDER)*(c*p[0]-(-s)*p[0]*g)=c*p+s*g.
        // See https://crypto.stackexchange.com/a/18106
        // https://bitcoin.stackexchange.com/questions/38351/ecdsa-v-r-s-what-is-v
        address computed = ecrecover(pseudoHash, v, bytes32(p[0]), pseudoSignature);
        return computed == lcWitness;
    }

    // c*p1 + s*p2. Requires cp1Witness=c*p1 and sp2Witness=s*p2. Also
    // requires cp1Witness != sp2Witness (which is fine for this application,
    // since it is cryptographically impossible for them to be equal. In the
    // (cryptographically impossible) case that a prover accidentally derives
    // a proof with equal c*p1 and s*p2, they should retry with a different
    // proof nonce.) Assumes that all points are on secp256k1
    // (which is checked in verifyVORProof below.)
    function linearCombination(
        uint256 c,
        uint256[2] memory p1,
        uint256[2] memory cp1Witness,
        uint256 s,
        uint256[2] memory p2,
        uint256[2] memory sp2Witness,
        uint256 zInv
    ) internal pure returns (uint256[2] memory) {
        require((cp1Witness[0] - sp2Witness[0]) % FIELD_SIZE != 0, "points in sum must be distinct");
        require(ecmulVerify(p1, c, cp1Witness), "First multiplication check failed");
        require(ecmulVerify(p2, s, sp2Witness), "Second multiplication check failed");
        return affineECAdd(cp1Witness, sp2Witness, zInv);
    }

    // Domain-separation tag for the hash taken in scalarFromCurvePoints.
    uint256 constant SCALAR_FROM_CURVE_POINTS_HASH_PREFIX = 2;

    // Pseudo-random number from inputs.
    // TODO(alx): We could save a bit of gas by following the standard here and
    // using the compressed representation of the points, if we collated the y
    // parities into a single bytes32.
    // https://www.pivotaltracker.com/story/show/171120588
    function scalarFromCurvePoints(
        uint256[2] memory hash,
        uint256[2] memory pk,
        uint256[2] memory gamma,
        address uWitness,
        uint256[2] memory v
    ) internal pure returns (uint256 s) {
        return
            uint256(
                keccak256(
                    abi.encodePacked(
                        SCALAR_FROM_CURVE_POINTS_HASH_PREFIX,
                        hash,
                        pk,
                        gamma,
                        v,
                        uWitness
                    )
                )
            );
    }

    // True if (gamma, c, s) is a correctly constructed randomness proof from pk
    // and seed. zInv must be the inverse of the third ordinate from
    // projectiveECAdd applied to cGammaWitness and sHashWitness. Corresponds to
    // section 5.3 of the IETF draft.
    //
    // TODO(alx): Since I'm only using pk in the ecrecover call, I could only pass
    // the x ordinate, and the parity of the y ordinate in the top bit of uWitness
    // (which I could make a uint256 without using any extra space.) Would save
    // about 2000 gas. https://www.pivotaltracker.com/story/show/170828567
    function verifyVORProof(
        uint256[2] memory pk,
        uint256[2] memory gamma,
        uint256 c,
        uint256 s,
        uint256 seed,
        address uWitness,
        uint256[2] memory cGammaWitness,
        uint256[2] memory sHashWitness,
        uint256 zInv
    ) internal view {
        require(isOnCurve(pk), "public key is not on curve");
        require(isOnCurve(gamma), "gamma is not on curve");
        require(isOnCurve(cGammaWitness), "cGammaWitness is not on curve");
        require(isOnCurve(sHashWitness), "sHashWitness is not on curve");
        require(verifyLinearCombinationWithGenerator(c, pk, s, uWitness), "addr(c*pk+s*g)≠_uWitness");
        // Step 4. of IETF draft section 5.3 (pk corresponds to Y, seed to alpha_string)
        uint256[2] memory hash = hashToCurve(pk, seed);
        // Step 6. of IETF draft section 5.3, but see note for step 5 about +/- terms
        uint256[2] memory v =
            linearCombination(
                c,
                gamma,
                cGammaWitness,
                s,
                hash,
                sHashWitness,
                zInv
            );
        // Steps 7. and 8. of IETF draft section 5.3
        uint256 derivedC = scalarFromCurvePoints(hash, pk, gamma, uWitness, v);
        require(c == derivedC, "invalid proof");
    }

    // Domain-separation tag for the hash used as the final VOR output.
    uint256 constant VOR_RANDOM_OUTPUT_HASH_PREFIX = 3;

    // Length of proof marshaled to bytes array. Shows layout of proof
    uint256 public constant PROOF_LENGTH =
        64 + // PublicKey (uncompressed format.)
        64 + // Gamma
        32 + // C
        32 + // S
        32 + // Seed
        0 +  // Dummy entry: The following elements are included for gas efficiency:
        32 + // uWitness (gets padded to 256 bits, even though it's only 160)
        64 + // cGammaWitness
        64 + // sHashWitness
        32;  // zInv  (Leave Output out, because that can be efficiently calculated)

    /* ***************************************************************************
   * @notice Returns proof's output, if proof is valid. Otherwise reverts

   * @param proof A binary-encoded proof
   *
   * Throws if proof is invalid, otherwise:
   * @return output i.e., the random output implied by the proof
   * ***************************************************************************
   * @dev See the calculation of PROOF_LENGTH for the binary layout of proof.
   */
    function randomValueFromVORProof(bytes memory proof) internal view returns (uint256 output) {
        require(proof.length == PROOF_LENGTH, "wrong proof length");

        uint256[2] memory pk; // parse proof contents into these variables
        uint256[2] memory gamma;
        // c, s and seed combined (prevents "stack too deep" compilation error)
        uint256[3] memory cSSeed;
        address uWitness;
        uint256[2] memory cGammaWitness;
        uint256[2] memory sHashWitness;
        uint256 zInv;

        (pk, gamma, cSSeed, uWitness, cGammaWitness, sHashWitness, zInv) =
            abi.decode(proof,
                (
                    uint256[2],
                    uint256[2],
                    uint256[3],
                    address,
                    uint256[2],
                    uint256[2],
                    uint256
                )
            );

        verifyVORProof(
            pk,
            gamma,
            cSSeed[0], // c
            cSSeed[1], // s
            cSSeed[2], // seed
            uWitness,
            cGammaWitness,
            sHashWitness,
            zInv
        );

        output = uint256(keccak256(abi.encode(VOR_RANDOM_OUTPUT_HASH_PREFIX, gamma)));
    }
}



contract VORRequestIDBase {
    /**
     * @notice returns the seed which is actually input to the VOR coordinator
     *
     * @dev To prevent repetition of VOR output due to repetition of the
     * @dev user-supplied seed, that seed is combined in a hash with the
     * @dev user-specific nonce, and the address of the consuming contract. The
     * @dev risk of repetition is mostly mitigated by inclusion of a blockhash in
     * @dev the final seed, but the nonce does protect against repetition in
     * @dev requests which are included in a single block.
     *
     * @param _userSeed VOR seed input provided by user
     * @param _requester Address of the requesting contract
     * @param _nonce User-specific nonce at the time of the request
     */
    function makeVORInputSeed(
        bytes32 _keyHash,
        uint256 _userSeed,
        address _requester,
        uint256 _nonce
    ) internal pure returns (uint256) {
        return uint256(keccak256(abi.encode(_keyHash, _userSeed, _requester, _nonce)));
    }

    /**
     * @notice Returns the id for this request
     * @param _keyHash The serviceAgreement ID to be used for this request
     * @param _vORInputSeed The seed to be passed directly to the VOR
     * @return The id for this request
     *
     * @dev Note that _vORInputSeed is not the seed passed by the consuming
     * @dev contract, but the one generated by makeVORInputSeed
     */
    function makeRequestId(bytes32 _keyHash, uint256 _vORInputSeed) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked(_keyHash, _vORInputSeed));
    }
}

/**
 * @title VORCoordinator coordinates on-chain verifiable-randomness requests
 * @title with off-chain responses
 */
contract VORCoordinator is Ownable, ReentrancyGuard, VOR, VORRequestIDBase {
    using SafeMath for uint256;
    using Address for address;

    IERC20_Ex internal xFUND;
    BlockHashStoreInterface internal blockHashStore;

    constructor(address _xfund, address _blockHashStore) public {
        xFUND = IERC20_Ex(_xfund);
        blockHashStore = BlockHashStoreInterface(_blockHashStore);
    }

    struct Callback {
        // Tracks an ongoing request
        address callbackContract; // Requesting contract, which will receive response
        // Amount of xFUND paid at request time. Total xFUND = 1e9 * 1e18 < 2^96, so
        // this representation is adequate, and saves a word of storage when this
        // field follows the 160-bit callbackContract address.
        uint96 randomnessFee;
        // Commitment to seed passed to oracle by this contract, and the number of
        // the block in which the request appeared. This is the keccak256 of the
        // concatenation of those values. Storing this commitment saves a word of
        // storage.
        bytes32 seedAndBlockNum;
    }

    struct ServiceAgreement {
        // Tracks oracle commitments to VOR service
        address payable vOROracle; // Oracle committing to respond with VOR service
        uint96 fee; // Minimum payment for oracle response. Total xFUND=1e9*1e18<2^96
        mapping(address => uint96) granularFees; // Per consumer fees if required
    }

    struct Consumer {
        uint256 amount;
        mapping(address => uint256) providers;
    }

    /* (provingKey, seed) */
    mapping(bytes32 => Callback) public callbacks;
    /* provingKey */
    mapping(bytes32 => ServiceAgreement) public serviceAgreements;
    /* oracle */
    /* xFUND balance */
    mapping(address => uint256) public withdrawableTokens;
    /* provingKey */
    /* consumer */
    mapping(bytes32 => mapping(address => uint256)) private nonces;

    event RandomnessRequest(
        bytes32 keyHash,
        uint256 seed,
        address sender,
        uint256 fee,
        bytes32 requestID
    );

    event NewServiceAgreement(bytes32 keyHash, uint256 fee);

    event ChangeFee(bytes32 keyHash, uint256 fee);
    event ChangeGranularFee(bytes32 keyHash, address consumer, uint256 fee);

    event RandomnessRequestFulfilled(bytes32 requestId, uint256 output);

    /**
     * @dev getProviderAddress - get provider address
     * @return address
     */
    function getProviderAddress(bytes32 _keyHash) external view returns (address) {
        return serviceAgreements[_keyHash].vOROracle;
    }

    /**
     * @dev getProviderFee - get provider's base fee
     * @return address
     */
    function getProviderFee(bytes32 _keyHash) external view returns (uint96) {
        return serviceAgreements[_keyHash].fee;
    }

    /**
     * @dev getProviderGranularFee - get provider's base fee
     * @return address
     */
    function getProviderGranularFee(bytes32 _keyHash, address _consumer) external view returns (uint96) {
        if(serviceAgreements[_keyHash].granularFees[_consumer] > 0) {
            return serviceAgreements[_keyHash].granularFees[_consumer];
        } else {
            return serviceAgreements[_keyHash].fee;
        }
    }

    /**
     * @notice Commits calling address to serve randomness
     * @param _fee minimum xFUND payment required to serve randomness
     * @param _oracle the address of the node with the proving key
     * @param _publicProvingKey public key used to prove randomness
     */
    function registerProvingKey(
        uint256 _fee,
        address payable _oracle,
        uint256[2] calldata _publicProvingKey
    ) external {
        bytes32 keyHash = hashOfKey(_publicProvingKey);
        address oldVOROracle = serviceAgreements[keyHash].vOROracle;
        require(oldVOROracle == address(0), "please register a new key");
        require(_oracle != address(0), "_oracle must not be 0x0");
        serviceAgreements[keyHash].vOROracle = _oracle;
        // Yes, this revert message doesn't fit in a word
        require(_fee <= 1e9 ether, "fee too high");
        serviceAgreements[keyHash].fee = uint96(_fee);
        emit NewServiceAgreement(keyHash, _fee);
    }

    /**
     * @notice Changes the provider's base fee
     * @param _publicProvingKey public key used to prove randomness
     * @param _fee minimum xFUND payment required to serve randomness
     */
    function changeFee(uint256[2] calldata _publicProvingKey, uint256 _fee) external {
        bytes32 keyHash = hashOfKey(_publicProvingKey);
        require(serviceAgreements[keyHash].vOROracle == _msgSender(), "only oracle can change the fee");
        require(_fee <= 1e9 ether, "fee too high");
        serviceAgreements[keyHash].fee = uint96(_fee);
        emit ChangeFee(keyHash, _fee);
    }

    /**
     * @notice Changes the provider's fee for a consumer contract
     * @param _publicProvingKey public key used to prove randomness
     * @param _fee minimum xFUND payment required to serve randomness
     */
    function changeGranularFee(uint256[2] calldata _publicProvingKey, uint256 _fee, address _consumer) external {
        bytes32 keyHash = hashOfKey(_publicProvingKey);
        require(serviceAgreements[keyHash].vOROracle == _msgSender(), "only oracle can change the fee");
        require(_fee <= 1e9 ether, "fee too high");
        serviceAgreements[keyHash].granularFees[_consumer] = uint96(_fee);
        emit ChangeGranularFee(keyHash, _consumer, _fee);
    }

    /**
     * @dev Allows the oracle operator to withdraw their xFUND
     * @param _recipient is the address the funds will be sent to
     * @param _amount is the amount of xFUND transferred from the Coordinator contract
     */
    function withdraw(address _recipient, uint256 _amount) external hasAvailableFunds(_amount) {
        withdrawableTokens[_msgSender()] = withdrawableTokens[_msgSender()].sub(_amount);
        assert(xFUND.transfer(_recipient, _amount));
    }

    /**
     * @notice creates the request for randomness
     *
     * @param _keyHash ID of the VOR public key against which to generate output
     * @param _consumerSeed Input to the VOR, from which randomness is generated
     * @param _feePaid Amount of xFUND sent with request. Must exceed fee for key
     *
     * @dev _consumerSeed is mixed with key hash, sender address and nonce to
     * @dev obtain preSeed, which is passed to VOR oracle, which mixes it with the
     * @dev hash of the block containing this request, to compute the final seed.
     *
     * @dev The requestId used to store the request data is constructed from the
     * @dev preSeed and keyHash.
     */
    function randomnessRequest(
        bytes32 _keyHash,
        uint256 _consumerSeed,
        uint256 _feePaid
    ) external sufficientXFUND(_feePaid, _keyHash) {
        require(address(_msgSender()).isContract(), "request can only be made by a contract");

        xFUND.transferFrom(_msgSender(), address(this), _feePaid);

        uint256 nonce = nonces[_keyHash][_msgSender()];
        uint256 preSeed = makeVORInputSeed(_keyHash, _consumerSeed, _msgSender(), nonce);
        bytes32 requestId = makeRequestId(_keyHash, preSeed);

        // Cryptographically guaranteed by preSeed including an increasing nonce
        assert(callbacks[requestId].callbackContract == address(0));
        callbacks[requestId].callbackContract = _msgSender();

        assert(_feePaid < 1e27); // Total xFUND fits in uint96
        callbacks[requestId].randomnessFee = uint96(_feePaid);

        callbacks[requestId].seedAndBlockNum = keccak256(abi.encodePacked(preSeed, block.number));
        emit RandomnessRequest(_keyHash, preSeed, _msgSender(), _feePaid, requestId);
        nonces[_keyHash][_msgSender()] = nonces[_keyHash][_msgSender()].add(1);
    }

    /**
     * @notice Returns the serviceAgreements key associated with this public key
     * @param _publicKey the key to return the address for
     */
    function hashOfKey(uint256[2] memory _publicKey) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(_publicKey));
    }

    /**
     * @notice Called by the node to fulfill requests
     *
     * @param _proof the proof of randomness. Actual random output built from this
     */
    function fulfillRandomnessRequest(bytes memory _proof) public {
        (bytes32 currentKeyHash, Callback memory callback, bytes32 requestId, uint256 randomness) =
            getRandomnessFromProof(_proof);

        // Pay oracle
        address payable oracle = serviceAgreements[currentKeyHash].vOROracle;
        withdrawableTokens[oracle] = withdrawableTokens[oracle].add(callback.randomnessFee);

        // Forget request. Must precede callback (prevents reentrancy)
        delete callbacks[requestId];
        callBackWithRandomness(requestId, randomness, callback.callbackContract);

        emit RandomnessRequestFulfilled(requestId, randomness);
    }

    // Offsets into fulfillRandomnessRequest's _proof of various values
    //
    // Public key. Skips byte array's length prefix.
    uint256 public constant PUBLIC_KEY_OFFSET = 0x20;
    // Seed is 7th word in proof, plus word for length, (6+1)*0x20=0xe0
    uint256 public constant PRESEED_OFFSET = 0xe0;

    function callBackWithRandomness(bytes32 requestId, uint256 randomness, address consumerContract) internal {
        // Dummy variable; allows access to method selector in next line. See
        // https://github.com/ethereum/solidity/issues/3506#issuecomment-553727797
        IVORConsumerBase v;
        bytes memory resp = abi.encodeWithSelector(v.rawFulfillRandomness.selector, requestId, randomness);
        // The bound b here comes from https://eips.ethereum.org/EIPS/eip-150. The
        // actual gas available to the consuming contract will be b-floor(b/64).
        // This is chosen to leave the consuming contract ~200k gas, after the cost
        // of the call itself.
        uint256 b = 206000;
        require(gasleft() >= b, "not enough gas for consumer");
        // A low-level call is necessary, here, because we don't want the consuming
        // contract to be able to revert this execution, and thus deny the oracle
        // payment for a valid randomness response. This also necessitates the above
        // check on the gasleft, as otherwise there would be no indication if the
        // callback method ran out of gas.
        //
        // solhint-disable-next-line avoid-low-level-calls
        (bool success, ) = consumerContract.call(resp);
        // Avoid unused-local-variable warning. (success is only present to prevent
        // a warning that the return value of consumerContract.call is unused.)
        (success);
    }

    function getRandomnessFromProof(bytes memory _proof)
        internal
        view
        returns (
            bytes32 currentKeyHash,
            Callback memory callback,
            bytes32 requestId,
            uint256 randomness
        )
    {
        // blockNum follows proof, which follows length word (only direct-number
        // constants are allowed in assembly, so have to compute this in code)
        uint256 blocknumOffset = 0x20 + PROOF_LENGTH;
        // _proof.length skips the initial length word, so not including the
        // blocknum in this length check balances out.
        require(_proof.length == blocknumOffset, "wrong proof length");
        uint256[2] memory publicKey;
        uint256 preSeed;
        uint256 blockNum;
        assembly {
            // solhint-disable-line no-inline-assembly
            publicKey := add(_proof, PUBLIC_KEY_OFFSET)
            preSeed := mload(add(_proof, PRESEED_OFFSET))
            blockNum := mload(add(_proof, blocknumOffset))
        }
        currentKeyHash = hashOfKey(publicKey);
        requestId = makeRequestId(currentKeyHash, preSeed);
        callback = callbacks[requestId];
        require(callback.callbackContract != address(0), "no corresponding request");
        require(callback.seedAndBlockNum == keccak256(abi.encodePacked(preSeed, blockNum)), "wrong preSeed or block num");

        bytes32 blockHash = blockhash(blockNum);
        if (blockHash == bytes32(0)) {
            blockHash = blockHashStore.getBlockhash(blockNum);
            require(blockHash != bytes32(0), "please prove blockhash");
        }
        // The seed actually used by the VOR machinery, mixing in the blockhash
        uint256 actualSeed = uint256(keccak256(abi.encodePacked(preSeed, blockHash)));
        // solhint-disable-next-line no-inline-assembly
        assembly {
            // Construct the actual proof from the remains of _proof
            mstore(add(_proof, PRESEED_OFFSET), actualSeed)
            mstore(_proof, PROOF_LENGTH)
        }
        randomness = VOR.randomValueFromVORProof(_proof); // Reverts on failure
    }

    /**
     * @dev Reverts if amount is not at least what was agreed upon in the service agreement
     * @param _feePaid The payment for the request
     * @param _keyHash The key which the request is for
     */
    modifier sufficientXFUND(uint256 _feePaid, bytes32 _keyHash) {
        if(serviceAgreements[_keyHash].granularFees[_msgSender()] > 0) {
            require(_feePaid >= serviceAgreements[_keyHash].granularFees[_msgSender()], "Below agreed payment");
        } else {
            require(_feePaid >= serviceAgreements[_keyHash].fee, "Below agreed payment");
        }
        _;
    }

    /**
     * @dev Reverts if amount requested is greater than withdrawable balance
     * @param _amount The given amount to compare to `withdrawableTokens`
     */
    modifier hasAvailableFunds(uint256 _amount) {
        require(withdrawableTokens[_msgSender()] >= _amount, "can't withdraw more than balance");
        _;
    }
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_xfund","type":"address"},{"internalType":"address","name":"_blockHashStore","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"keyHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"ChangeFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"keyHash","type":"bytes32"},{"indexed":false,"internalType":"address","name":"consumer","type":"address"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"ChangeGranularFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"keyHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"NewServiceAgreement","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"keyHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"seed","type":"uint256"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"requestID","type":"bytes32"}],"name":"RandomnessRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"requestId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"output","type":"uint256"}],"name":"RandomnessRequestFulfilled","type":"event"},{"inputs":[],"name":"PRESEED_OFFSET","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PROOF_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PUBLIC_KEY_OFFSET","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"callbacks","outputs":[{"internalType":"address","name":"callbackContract","type":"address"},{"internalType":"uint96","name":"randomnessFee","type":"uint96"},{"internalType":"bytes32","name":"seedAndBlockNum","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[2]","name":"_publicProvingKey","type":"uint256[2]"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"changeFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[2]","name":"_publicProvingKey","type":"uint256[2]"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"address","name":"_consumer","type":"address"}],"name":"changeGranularFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_proof","type":"bytes"}],"name":"fulfillRandomnessRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_keyHash","type":"bytes32"}],"name":"getProviderAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_keyHash","type":"bytes32"}],"name":"getProviderFee","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_keyHash","type":"bytes32"},{"internalType":"address","name":"_consumer","type":"address"}],"name":"getProviderGranularFee","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[2]","name":"_publicKey","type":"uint256[2]"}],"name":"hashOfKey","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_keyHash","type":"bytes32"},{"internalType":"uint256","name":"_consumerSeed","type":"uint256"},{"internalType":"uint256","name":"_feePaid","type":"uint256"}],"name":"randomnessRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"address payable","name":"_oracle","type":"address"},{"internalType":"uint256[2]","name":"_publicProvingKey","type":"uint256[2]"}],"name":"registerProvingKey","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"serviceAgreements","outputs":[{"internalType":"address payable","name":"vOROracle","type":"address"},{"internalType":"uint96","name":"fee","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"withdrawableTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b5060405162002760380380620027608339818101604052604081101561003557600080fd5b50805160209091015160006100486100c7565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35060018055600280546001600160a01b039384166001600160a01b031991821617909155600380549290931691161790556100cb565b3390565b61268580620000db6000396000f3fe608060405234801561001057600080fd5b50600436106101205760003560e01c8063952942f0116100ad578063caf70c4a11610071578063caf70c4a146103e5578063da8d6d8514610430578063e911439c1461044d578063f2fde38b14610455578063f3fef3a31461047b57610120565b8063952942f0146103185780639845fb9c146103475780639c92f27714610364578063b415f4f5146103ac578063bbf70d69146103b457610120565b8063715018a6116100f4578063715018a61461027b57806375d350701461028357806381f1e046146102cb5780638aa7927b146102ec5780638da5cb5b146102f457610120565b80626f6ad01461012557806321f365091461015d578063264eb1cf146101aa5780635e1c1059146101d5575b600080fd5b61014b6004803603602081101561013b57600080fd5b50356001600160a01b03166104a7565b60408051918252519081900360200190f35b61017a6004803603602081101561017357600080fd5b50356104b9565b604080516001600160a01b0390941684526001600160601b03909216602084015282820152519081900360600190f35b6101d3600480360360608110156101c057600080fd5b50803590602081013590604001356104ee565b005b6101d3600480360360208110156101eb57600080fd5b81019060208101813564010000000081111561020657600080fd5b82018360208201111561021857600080fd5b8035906020019184600183028401116401000000008311171561023a57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061091e945050505050565b6101d3610a01565b6102a06004803603602081101561029957600080fd5b5035610abf565b604080516001600160a01b0390931683526001600160601b0390911660208301528051918290030190f35b6101d3600480360360608110156102e157600080fd5b506040810135610aec565b61014b610c50565b6102fc610c55565b604080516001600160a01b039092168252519081900360200190f35b6101d36004803603608081101561032e57600080fd5b5060408101356001600160a01b03606083013516610c64565b6102fc6004803603602081101561035d57600080fd5b5035610de7565b6103906004803603604081101561037a57600080fd5b50803590602001356001600160a01b0316610e05565b604080516001600160601b039092168252519081900360200190f35b61014b610e95565b6101d3600480360360808110156103ca57600080fd5b508035906001600160a01b0360208201351690604001610e9a565b61014b600480360360408110156103fb57600080fd5b604080518082018252918301929181830191839060029083908390808284376000920191909152509194506110789350505050565b6103906004803603602081101561044657600080fd5b50356110cd565b61014b6110ef565b6101d36004803603602081101561046b57600080fd5b50356001600160a01b03166110f5565b6101d36004803603604081101561049157600080fd5b506001600160a01b038135169060200135611209565b60066020526000908152604090205481565b600460205260009081526040902080546001909101546001600160a01b03821691600160a01b90046001600160601b03169083565b6000838152600560205260408120829185916001018161050c61136b565b6001600160a01b031681526020810191909152604001600020546001600160601b031611156105c25760008181526005602052604081206001019061054f61136b565b6001600160a01b031681526020810191909152604001600020546001600160601b03168210156105bd576040805162461bcd60e51b815260206004820152601460248201527310995b1bddc81859dc995959081c185e5b595b9d60621b604482015290519081900360640190fd5b61062c565b600081815260056020526040902054600160a01b90046001600160601b031682101561062c576040805162461bcd60e51b815260206004820152601460248201527310995b1bddc81859dc995959081c185e5b595b9d60621b604482015290519081900360640190fd5b61064561063761136b565b6001600160a01b031661136f565b6106805760405162461bcd60e51b815260040180806020018281038252602681526020018061262a6026913960400191505060405180910390fd5b6002546001600160a01b03166323b872dd61069961136b565b30866040518463ffffffff1660e01b815260040180846001600160a01b03168152602001836001600160a01b031681526020018281526020019350505050602060405180830381600087803b1580156106f157600080fd5b505af1158015610705573d6000803e3d6000fd5b505050506040513d602081101561071b57600080fd5b505060008581526007602052604081208161073461136b565b6001600160a01b03166001600160a01b03168152602001908152602001600020549050600061076c878761076661136b565b85611375565b9050600061077a88836113bc565b6000818152600460205260409020549091506001600160a01b03161561079c57fe5b6107a461136b565b600082815260046020526040902080546001600160a01b0319166001600160a01b03929092169190911790556b033b2e3c9fd0803ce800000086106107e557fe5b600081815260046020818152604080842080546001600160a01b0316600160a01b6001600160601b038d160217815581518084018890524381840152825180820384018152606090910190925281519183019190912093859052919052600101557febb37373bb11123e38f964627878b02c247f92f3913df7cf3f270b5222c8d2be888361087161136b565b6040805193845260208401929092526001600160a01b0316828201526060820189905260808201849052519081900360a00190a160008881526007602052604081206108e391600191906108c361136b565b6001600160a01b03168152602081019190915260400160002054906113e8565b6000898152600760205260408120906108fa61136b565b6001600160a01b031681526020810191909152604001600020555050505050505050565b6000610928612528565b60008061093485611449565b600084815260056020908152604080832054828701516001600160a01b0390911680855260069093529220549599509397509195509350909161097f916001600160601b03166113e8565b6001600160a01b038216600090815260066020908152604080832093909355858252600490529081208181556001015583516109be908490849061170d565b604080518481526020810184905281517fa2e7a402243ebda4a69ceeb3dfb682943b7a9b3ac66d6eefa8db65894009611c929181900390910190a1505050505050565b610a0961136b565b6001600160a01b0316610a1a610c55565b6001600160a01b031614610a75576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6005602052600090815260409020546001600160a01b03811690600160a01b90046001600160601b031682565b604080518082018252600091610b1b919085906002908390839080828437600092019190915250611078915050565b9050610b2561136b565b6000828152600560205260409020546001600160a01b03908116911614610b93576040805162461bcd60e51b815260206004820152601e60248201527f6f6e6c79206f7261636c652063616e206368616e676520746865206665650000604482015290519081900360640190fd5b6b033b2e3c9fd0803ce8000000821115610be3576040805162461bcd60e51b815260206004820152600c60248201526b0cccaca40e8dede40d0d2ced60a31b604482015290519081900360640190fd5b60008181526005602090815260409182902080546001600160a01b0316600160a01b6001600160601b03871602179055815183815290810184905281517ffc6ca2918cb95fbfc07e4567da6387d5e4209b4ced636bbe450c09895d447526929181900390910190a1505050565b602081565b6000546001600160a01b031690565b604080518082018252600091610c93919086906002908390839080828437600092019190915250611078915050565b9050610c9d61136b565b6000828152600560205260409020546001600160a01b03908116911614610d0b576040805162461bcd60e51b815260206004820152601e60248201527f6f6e6c79206f7261636c652063616e206368616e676520746865206665650000604482015290519081900360640190fd5b6b033b2e3c9fd0803ce8000000831115610d5b576040805162461bcd60e51b815260206004820152600c60248201526b0cccaca40e8dede40d0d2ced60a31b604482015290519081900360640190fd5b60008181526005602090815260408083206001600160a01b038616808552600190910183529281902080546bffffffffffffffffffffffff19166001600160601b03881617905580518481529182019290925280820185905290517fe43e8b0e04374f9e75dfd8baf9a833a47ff1eb7ecff6d460bf968f230937da62916060908290030190a150505050565b6000818152600560205260409020546001600160a01b03165b919050565b60008281526005602090815260408083206001600160a01b03851684526001019091528120546001600160601b031615610e6e575060008281526005602090815260408083206001600160a01b03851684526001019091529020546001600160601b0316610e8f565b50600082815260056020526040902054600160a01b90046001600160601b03165b92915050565b60e081565b604080518082018252600091610ec9919084906002908390839080828437600092019190915250611078915050565b6000818152600560205260409020549091506001600160a01b03168015610f37576040805162461bcd60e51b815260206004820152601960248201527f706c656173652072656769737465722061206e6577206b657900000000000000604482015290519081900360640190fd5b6001600160a01b038416610f92576040805162461bcd60e51b815260206004820152601760248201527f5f6f7261636c65206d757374206e6f7420626520307830000000000000000000604482015290519081900360640190fd5b600082815260056020526040902080546001600160a01b0319166001600160a01b0386161790556b033b2e3c9fd0803ce8000000851115611009576040805162461bcd60e51b815260206004820152600c60248201526b0cccaca40e8dede40d0d2ced60a31b604482015290519081900360640190fd5b60008281526005602090815260409182902080546001600160a01b0316600160a01b6001600160601b038a1602179055815184815290810187905281517fae189157e0628c1e62315e9179156e1ea10e90e9c15060002f7021e907dc2cfe929181900390910190a15050505050565b6000816040516020018082600260200280838360005b838110156110a657818101518382015260200161108e565b50505050905001915050604051602081830303815290604052805190602001209050919050565b600090815260056020526040902054600160a01b90046001600160601b031690565b6101a081565b6110fd61136b565b6001600160a01b031661110e610c55565b6001600160a01b031614611169576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0381166111ae5760405162461bcd60e51b81526004018080602001828103825260268152602001806125c16026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b80806006600061121761136b565b6001600160a01b03166001600160a01b0316815260200190815260200160002054101561128b576040805162461bcd60e51b815260206004820181905260248201527f63616e2774207769746864726177206d6f7265207468616e2062616c616e6365604482015290519081900360640190fd5b6112bb826006600061129b61136b565b6001600160a01b0316815260208101919091526040016000205490611857565b600660006112c761136b565b6001600160a01b0390811682526020808301939093526040918201600090812094909455600254825163a9059cbb60e01b8152888316600482015260248101889052925191169363a9059cbb93604480850194919392918390030190829087803b15801561133457600080fd5b505af1158015611348573d6000803e3d6000fd5b505050506040513d602081101561135e57600080fd5b505161136657fe5b505050565b3390565b3b151590565b60408051602080820196909652808201949094526001600160a01b039290921660608401526080808401919091528151808403909101815260a09092019052805191012090565b604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b600082820183811015611442576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000611453612528565b825160009081906101c09081146114a6576040805162461bcd60e51b81526020600482015260126024820152710eee4dedcce40e0e4dedecc40d8cadccee8d60731b604482015290519081900360640190fd5b6114ae612548565b5060e0860151818701516020880191906114c783611078565b97506114d388836113bc565b600081815260046020908152604091829020825160608101845281546001600160a01b038116808352600160a01b9091046001600160601b03169382019390935260019091015492810192909252909850909650611578576040805162461bcd60e51b815260206004820152601860248201527f6e6f20636f72726573706f6e64696e6720726571756573740000000000000000604482015290519081900360640190fd5b60408051602080820185905281830184905282518083038401815260609092018352815191012090880151146115f5576040805162461bcd60e51b815260206004820152601a60248201527f77726f6e672070726553656564206f7220626c6f636b206e756d000000000000604482015290519081900360640190fd5b8040806116c15760035460408051631d2827a760e31b81526004810185905290516001600160a01b039092169163e9413d3891602480820192602092909190829003018186803b15801561164857600080fd5b505afa15801561165c573d6000803e3d6000fd5b505050506040513d602081101561167257600080fd5b50519050806116c1576040805162461bcd60e51b81526020600482015260166024820152750e0d8cac2e6ca40e0e4deecca40c4d8dec6d6d0c2e6d60531b604482015290519081900360640190fd5b6040805160208082018690528183018490528251808303840181526060909201909252805191012060e08b018190526101a08b526116fe8b6118b4565b96505050505050509193509193565b604080516024810185905260448082018590528251808303909101815260649091019091526020810180516001600160e01b03166394985ddd60e01b179052600090620324b0805a10156117a8576040805162461bcd60e51b815260206004820152601b60248201527f6e6f7420656e6f7567682067617320666f7220636f6e73756d65720000000000604482015290519081900360640190fd5b6000846001600160a01b0316836040518082805190602001908083835b602083106117e45780518252601f1990920191602091820191016117c5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611846576040519150601f19603f3d011682016040523d82523d6000602084013e61184b565b606091505b50505050505050505050565b6000828211156118ae576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b60006101a0825114611902576040805162461bcd60e51b81526020600482015260126024820152710eee4dedcce40e0e4dedecc40d8cadccee8d60731b604482015290519081900360640190fd5b61190a612548565b611912612548565b61191a612566565b6000611924612548565b61192c612548565b6000888060200190516101a081101561194457600080fd5b5060e08101516101808201519198506040890197506080890196509450610100880193506101408801925090506119978787876000602002015188600160200201518960026020020151898989896119fd565b6003866040516020018083815260200182600260200280838360005b838110156119cb5781810151838201526020016119b3565b50505050905001925050506040516020818303038152906040528051906020012060001c975050505050505050919050565b611a0689611c4a565b611a57576040805162461bcd60e51b815260206004820152601a60248201527f7075626c6963206b6579206973206e6f74206f6e206375727665000000000000604482015290519081900360640190fd5b611a6088611c4a565b611aa9576040805162461bcd60e51b815260206004820152601560248201527467616d6d61206973206e6f74206f6e20637572766560581b604482015290519081900360640190fd5b611ab283611c4a565b611b03576040805162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e206375727665000000604482015290519081900360640190fd5b611b0c82611c4a565b611b5d576040805162461bcd60e51b815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e20637572766500000000604482015290519081900360640190fd5b611b69878a8887611c74565b611bba576040805162461bcd60e51b815260206004820152601a60248201527f6164647228632a706b2b732a6729e289a05f755769746e657373000000000000604482015290519081900360640190fd5b611bc2612548565b611bcc8a87611da9565b9050611bd6612548565b611be5898b878b868989611e4c565b90506000611bf6838d8d8a86611f57565b9050808a14611c3c576040805162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b604482015290519081900360640190fd5b505050505050505050505050565b60208101516000906401000003d019908009611c6d8360005b6020020151612057565b1492915050565b60006001600160a01b038216611cbf576040805162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b604482015290519081900360640190fd5b602084015160009060011615611cd657601c611cd9565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe19918203925060009190890990506000600183858a84602002015160001b8560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611d81573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b611db1612548565b611e0f600184846040516020018084815260200183600260200280838360005b83811015611de9578181015183820152602001611dd1565b50505050905001828152602001935050505060405160208183030381529060405261207b565b90505b611e1b81611c4a565b610e8f578051604080516020818101939093528151808203909301835281019052611e459061207b565b9050611e12565b611e54612548565b825186516401000003d01991900306611eb4576040805162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e63740000604482015290519081900360640190fd5b611ebf8789886120c9565b611efa5760405162461bcd60e51b81526004018080602001828103825260218152602001806125e76021913960400191505060405180910390fd5b611f058486856120c9565b611f405760405162461bcd60e51b81526004018080602001828103825260228152602001806126086022913960400191505060405180910390fd5b611f4b868484612228565b98975050505050505050565b6000600286868685876040516020018087815260200186600260200280838360005b83811015611f91578181015183820152602001611f79565b5050505090500185600260200280838360005b83811015611fbc578181015183820152602001611fa4565b5050505090500184600260200280838360005b83811015611fe7578181015183820152602001611fcf565b5050505090500183600260200280838360005b83811015612012578181015183820152602001611ffa565b50505050905001826001600160a01b031660601b815260140196505050505050506040516020818303038152906040528051906020012060001c905095945050505050565b6000806401000003d01980848509840990506401000003d019600782089392505050565b612083612548565b61208c826122ee565b81526120a161209c826000611c63565b612329565b602082018190526002900660011415610e00576020810180516401000003d019039052919050565b600082612114576040805162461bcd60e51b815260206004820152601460248201527307363616c6172206d757374206e6f7420626520360641b604482015290519081900360640190fd5b835160208501516000906001161561212d57601c612130565b601b5b9050600070014551231950b75fc4402da1732fc9bebe19838709604080516000808252602080830180855282905260ff871683850152606083018890526080830185905292519394509260019260a0808401939192601f1981019281900390910190855afa1580156121a6573d6000803e3d6000fd5b5050506020604051035190506000866040516020018082600260200280838360005b838110156121e05781810151838201526020016121c8565b505050509050019150506040516020818303038152906040528051906020012060001c9050806001600160a01b0316826001600160a01b031614955050505050509392505050565b612230612548565b8351602080860151855191860151600093849384936122519390919061233f565b919450925090506401000003d0198582096001146122b6576040805162461bcd60e51b815260206004820152601960248201527f696e765a206d75737420626520696e7665727365206f66207a00000000000000604482015290519081900360640190fd5b60405180604001604052806401000003d019806122cf57fe5b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d0198110610e00576040805160208082019390935281518082038401815290820190915280519101206122f6565b6000610e8f8263400000f4600160fe1b0361241f565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a089050600061237f838385856124bb565b909850905061239088828e886124df565b90985090506123a188828c876124df565b909850905060006123b48d878b856124df565b90985090506123c5888286866124bb565b90985090506123d688828e896124df565b909850905081811461240b576401000003d019818a0998506401000003d01982890997506401000003d019818309965061240f565b8196505b5050505050509450945094915050565b60008061242a612584565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a082015261245c6125a2565b60208160c0846005600019fa9250826124b1576040805162461bcd60e51b81526020600482015260126024820152716269674d6f64457870206661696c7572652160701b604482015290519081900360640190fd5b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b604080516060810182526000808252602082018190529181019190915290565b60405180604001604052806002906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b6040518060200160405280600190602082028036833750919291505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734669727374206d756c7469706c69636174696f6e20636865636b206661696c65645365636f6e64206d756c7469706c69636174696f6e20636865636b206661696c6564726571756573742063616e206f6e6c79206265206d616465206279206120636f6e7472616374a2646970667358221220f2c5a363d0a5a524a188e3c3ca80e80c90fb165d91926f3890127d42c8d90b3664736f6c634300060c0033000000000000000000000000245330351344f9301690d5d8de2a07f5f32e114900000000000000000000000095ae62e3e2261615970375cc8af8c7e6923627fa

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

000000000000000000000000245330351344f9301690d5d8de2a07f5f32e114900000000000000000000000095ae62e3e2261615970375cc8af8c7e6923627fa

-----Decoded View---------------
Arg [0] : _xfund (address): 0x245330351344f9301690d5d8de2a07f5f32e1149
Arg [1] : _blockHashStore (address): 0x95ae62e3e2261615970375cc8af8c7e6923627fa

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000245330351344f9301690d5d8de2a07f5f32e1149
Arg [1] : 00000000000000000000000095ae62e3e2261615970375cc8af8c7e6923627fa


Deployed ByteCode Sourcemap

46809:14117:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48618:53;;;;;;;;;;;;;;;;-1:-1:-1;48618:53:0;-1:-1:-1;;;;;48618:53:0;;:::i;:::-;;;;;;;;;;;;;;;;48433:45;;;;;;;;;;;;;;;;-1:-1:-1;48433:45:0;;:::i;:::-;;;;-1:-1:-1;;;;;48433:45:0;;;;;-1:-1:-1;;;;;48433:45:0;;;;;;;;;;;;;;;;;;;;53654:1169;;;;;;;;;;;;;;;;-1:-1:-1;53654:1169:0;;;;;;;;;;;;:::i;:::-;;55308:676;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55308:676:0;;-1:-1:-1;55308:676:0;;-1:-1:-1;;;;;55308:676:0:i;24602:148::-;;;:::i;48507:61::-;;;;;;;;;;;;;;;;-1:-1:-1;48507:61:0;;:::i;:::-;;;;-1:-1:-1;;;;;48507:61:0;;;;;-1:-1:-1;;;;;48507:61:0;;;;;;;;;;;;;;;;51354:401;;;;;;;;;;;;;;;;-1:-1:-1;51354:401:0;;;;;:::i;56127:48::-;;;:::i;23951:87::-;;;:::i;:::-;;;;-1:-1:-1;;;;;23951:87:0;;;;;;;;;;;;;;51988:467;;;;;;;;;;;;;;;;-1:-1:-1;51988:467:0;;;;-1:-1:-1;;;;;51988:467:0;;;;;;:::i;49323:141::-;;;;;;;;;;;;;;;;-1:-1:-1;49323:141:0;;:::i;49810:334::-;;;;;;;;;;;;;;;;-1:-1:-1;49810:334:0;;;;;;-1:-1:-1;;;;;49810:334:0;;:::i;:::-;;;;-1:-1:-1;;;;;49810:334:0;;;;;;;;;;;;;;56255:45;;;:::i;50438:702::-;;;;;;;;;;;;;;;;-1:-1:-1;50438:702:0;;;-1:-1:-1;;;;;50438:702:0;;;;;;;;;:::i;54991:144::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54991:144:0;;-1:-1:-1;54991:144:0;;-1:-1:-1;;;;54991:144:0:i;49568:130::-;;;;;;;;;;;;;;;;-1:-1:-1;49568:130:0;;:::i;42778:409::-;;;:::i;24905:244::-;;;;;;;;;;;;;;;;-1:-1:-1;24905:244:0;-1:-1:-1;;;;;24905:244:0;;:::i;52700:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;52700:244:0;;;;;;;;:::i;48618:53::-;;;;;;;;;;;;;:::o;48433:45::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;48433:45:0;;;-1:-1:-1;;;48433:45:0;;-1:-1:-1;;;;;48433:45:0;;;:::o;53654:1169::-;60324:1;60267:27;;;:17;:27;;;;;53799:8;;53809;;60267:40;;60324:1;60308:12;:10;:12::i;:::-;-1:-1:-1;;;;;60267:54:0;;;;;;;;;;;;-1:-1:-1;60267:54:0;;-1:-1:-1;;;;;60267:54:0;:58;60264:298;;;60362:27;;;;:17;:27;;;;;:40;;;60403:12;:10;:12::i;:::-;-1:-1:-1;;;;;60362:54:0;;;;;;;;;;;;-1:-1:-1;60362:54:0;;-1:-1:-1;;;;;60362:54:0;60350:66;;;60342:99;;;;;-1:-1:-1;;;60342:99:0;;;;;;;;;;;;-1:-1:-1;;;60342:99:0;;;;;;;;;;;;;;;60264:298;;;60494:27;;;;:17;:27;;;;;:31;-1:-1:-1;;;60494:31:0;;-1:-1:-1;;;;;60494:31:0;60482:43;;;60474:76;;;;;-1:-1:-1;;;60474:76:0;;;;;;;;;;;;-1:-1:-1;;;60474:76:0;;;;;;;;;;;;;;;53838:34:::1;53846:12;:10;:12::i;:::-;-1:-1:-1::0;;;;;53838:32:0::1;;:34::i;:::-;53830:85;;;;-1:-1:-1::0;;;53830:85:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53928:5;::::0;-1:-1:-1;;;;;53928:5:0::1;:18;53947:12;:10;:12::i;:::-;53969:4;53976:8;53928:57;;;;;;;;;;;;;-1:-1:-1::0;;;;;53928:57:0::1;;;;;;-1:-1:-1::0;;;;;53928:57:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;;53998:13:0::1;54014:16:::0;;;:6:::1;53928:57;54014:16:::0;;;;53998:13;54031:12:::1;:10;:12::i;:::-;-1:-1:-1::0;;;;;54014:30:0::1;-1:-1:-1::0;;;;;54014:30:0::1;;;;;;;;;;;;;53998:46;;54055:15;54073:62;54090:8;54100:13;54115:12;:10;:12::i;:::-;54129:5;54073:16;:62::i;:::-;54055:80;;54146:17;54166:32;54180:8;54190:7;54166:13;:32::i;:::-;54349:1;54300:20:::0;;;:9:::1;:20;::::0;;;;:37;54146:52;;-1:-1:-1;;;;;;54300:37:0::1;:51:::0;54293:59:::1;;;;54403:12;:10;:12::i;:::-;54363:20;::::0;;;:9:::1;:20;::::0;;;;:52;;-1:-1:-1;;;;;;54363:52:0::1;-1:-1:-1::0;;;;;54363:52:0;;;::::1;::::0;;;::::1;::::0;;54446:4:::1;54435:15:::0;::::1;54428:23;;;;54492:20;::::0;;;:9:::1;:20;::::0;;;;;;;:53;;-1:-1:-1;;;;;54492:53:0::1;-1:-1:-1::0;;;;;;;;54492:53:0;::::1;;;::::0;;54607:39;;;;::::1;::::0;;;54633:12:::1;54607:39:::0;;;;;;;;;;;;;;;;;;;;54597:50;;;;::::1;::::0;;;;54558:20;;;;;;;-1:-1:-1;54558:36:0::1;:89:::0;54663:71:::1;54681:8:::0;54607:39;54700:12:::1;:10;:12::i;:::-;54663:71;::::0;;;;;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;;;54663:71:0::1;::::0;;;;;;;;;;;;;;;;;;;;;;;;::::1;54778:16;::::0;;;:6:::1;:16;::::0;;;;:37:::1;::::0;54813:1:::1;::::0;54778:16;54795:12:::1;:10;:12::i;:::-;-1:-1:-1::0;;;;;54778:30:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;54778:30:0;;;:34:::1;:37::i;:::-;54745:16;::::0;;;:6:::1;:16;::::0;;;;;54762:12:::1;:10;:12::i;:::-;-1:-1:-1::0;;;;;54745:30:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;54745:30:0;:70;-1:-1:-1;;;;;;;;53654:1169:0:o;55308:676::-;55382:22;55406:24;;:::i;:::-;55432:17;55451:18;55486:30;55509:6;55486:22;:30::i;:::-;55552:22;55577:33;;;:17;:33;;;;;;;;:43;55691:22;;;;-1:-1:-1;;;;;55577:43:0;;;55660:26;;;:18;:26;;;;;;55381:135;;-1:-1:-1;55381:135:0;;-1:-1:-1;55381:135:0;;-1:-1:-1;55381:135:0;-1:-1:-1;55577:43:0;;55660:54;;-1:-1:-1;;;;;55660:54:0;:30;:54::i;:::-;-1:-1:-1;;;;;55631:26:0;;;;;;:18;:26;;;;;;;;:83;;;;55806:20;;;:9;:20;;;;;55799:27;;;;;;55883:25;;55837:72;;55816:9;;55871:10;;55837:22;:72::i;:::-;55927:49;;;;;;;;;;;;;;;;;;;;;;;;;55308:676;;;;;;:::o;24602:148::-;24182:12;:10;:12::i;:::-;-1:-1:-1;;;;;24171:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;24171:23:0;;24163:68;;;;;-1:-1:-1;;;24163:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24709:1:::1;24693:6:::0;;24672:40:::1;::::0;-1:-1:-1;;;;;24693:6:0;;::::1;::::0;24672:40:::1;::::0;24709:1;;24672:40:::1;24740:1;24723:19:::0;;-1:-1:-1;;;;;;24723:19:0::1;::::0;;24602:148::o;48507:61::-;;;;;;;;;;;;-1:-1:-1;;;;;48507:61:0;;;-1:-1:-1;;;48507:61:0;;-1:-1:-1;;;;;48507:61:0;;:::o;51354:401::-;51464:28;;;;;;;;51446:15;;51464:28;;;51474:17;;51464:28;;;;51474:17;;51464:28;51474:17;51464:28;;;;;;;;;-1:-1:-1;51464:9:0;;-1:-1:-1;;51464:28:0:i;:::-;51446:46;;51551:12;:10;:12::i;:::-;51511:26;;;;:17;:26;;;;;:36;-1:-1:-1;;;;;51511:36:0;;;:52;;;51503:95;;;;;-1:-1:-1;;;51503:95:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;51625:9;51617:4;:17;;51609:42;;;;;-1:-1:-1;;;51609:42:0;;;;;;;;;;;;-1:-1:-1;;;51609:42:0;;;;;;;;;;;;;;;51662:26;;;;:17;:26;;;;;;;;;:45;;-1:-1:-1;;;;;51662:45:0;-1:-1:-1;;;;;;;;51662:45:0;;;;;;51723:24;;;;;;;;;;;;;;;;;;;;;;;;51354:401;;;:::o;56127:48::-;56171:4;56127:48;:::o;23951:87::-;23997:7;24024:6;-1:-1:-1;;;;;24024:6:0;23951:87;:::o;51988:467::-;52125:28;;;;;;;;52107:15;;52125:28;;;52135:17;;52125:28;;;;52135:17;;52125:28;52135:17;52125:28;;;;;;;;;-1:-1:-1;52125:9:0;;-1:-1:-1;;52125:28:0:i;:::-;52107:46;;52212:12;:10;:12::i;:::-;52172:26;;;;:17;:26;;;;;:36;-1:-1:-1;;;;;52172:36:0;;;:52;;;52164:95;;;;;-1:-1:-1;;;52164:95:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;52286:9;52278:4;:17;;52270:42;;;;;-1:-1:-1;;;52270:42:0;;;;;;;;;;;;-1:-1:-1;;;52270:42:0;;;;;;;;;;;;;;;52323:26;;;;:17;:26;;;;;;;;-1:-1:-1;;;;;52323:50:0;;;;;:39;;;;:50;;;;;;:65;;-1:-1:-1;;52323:65:0;-1:-1:-1;;;;;52323:65:0;;;;;52404:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51988:467;;;;:::o;49323:141::-;49392:7;49419:27;;;:17;:27;;;;;:37;-1:-1:-1;;;;;49419:37:0;49323:141;;;;:::o;49810:334::-;49902:6;49924:27;;;:17;:27;;;;;;;;-1:-1:-1;;;;;49924:51:0;;;;:40;;:51;;;;;;-1:-1:-1;;;;;49924:51:0;:55;49921:216;;-1:-1:-1;50003:27:0;;;;:17;:27;;;;;;;;-1:-1:-1;;;;;50003:51:0;;;;:40;;:51;;;;;;-1:-1:-1;;;;;50003:51:0;49996:58;;49921:216;-1:-1:-1;50094:27:0;;;;:17;:27;;;;;:31;-1:-1:-1;;;50094:31:0;;-1:-1:-1;;;;;50094:31:0;49921:216;49810:334;;;;:::o;56255:45::-;56296:4;56255:45;:::o;50438:702::-;50616:28;;;;;;;;50598:15;;50616:28;;;50626:17;;50616:28;;;;50626:17;;50616:28;50626:17;50616:28;;;;;;;;;-1:-1:-1;50616:9:0;;-1:-1:-1;;50616:28:0:i;:::-;50655:20;50678:26;;;:17;:26;;;;;:36;50598:46;;-1:-1:-1;;;;;;50678:36:0;50733:26;;50725:64;;;;;-1:-1:-1;;;50725:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;50808:21:0;;50800:57;;;;;-1:-1:-1;;;50800:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;50868:26;;;;:17;:26;;;;;:46;;-1:-1:-1;;;;;;50868:46:0;-1:-1:-1;;;;;50868:46:0;;;;;51000:9;50992:17;;;50984:42;;;;;-1:-1:-1;;;50984:42:0;;;;;;;;;;;;-1:-1:-1;;;50984:42:0;;;;;;;;;;;;;;;51037:26;;;;:17;:26;;;;;;;;;:45;;-1:-1:-1;;;;;51037:45:0;-1:-1:-1;;;;;;;;51037:45:0;;;;;;51098:34;;;;;;;;;;;;;;;;;;;;;;;;50438:702;;;;;:::o;54991:144::-;55061:7;55115:10;55098:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55088:39;;;;;;55081:46;;54991:144;;;:::o;49568:130::-;49633:6;49659:27;;;:17;:27;;;;;:31;-1:-1:-1;;;49659:31:0;;-1:-1:-1;;;;;49659:31:0;;49568:130::o;42778:409::-;42826:361;42778:409;:::o;24905:244::-;24182:12;:10;:12::i;:::-;-1:-1:-1;;;;;24171:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;24171:23:0;;24163:68;;;;;-1:-1:-1;;;24163:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;24994:22:0;::::1;24986:73;;;;-1:-1:-1::0;;;24986:73:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25096:6;::::0;;25075:38:::1;::::0;-1:-1:-1;;;;;25075:38:0;;::::1;::::0;25096:6;::::1;::::0;25075:38:::1;::::0;::::1;25124:6;:17:::0;;-1:-1:-1;;;;;;25124:17:0::1;-1:-1:-1::0;;;;;25124:17:0;;;::::1;::::0;;;::::1;::::0;;24905:244::o;52700:::-;52782:7;60859;60823:18;:32;60842:12;:10;:12::i;:::-;-1:-1:-1;;;;;60823:32:0;-1:-1:-1;;;;;60823:32:0;;;;;;;;;;;;;:43;;60815:88;;;;;-1:-1:-1;;;60815:88:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52837:45:::1;52874:7;52837:18;:32;52856:12;:10;:12::i;:::-;-1:-1:-1::0;;;;;52837:32:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;52837:32:0;;;:36:::1;:45::i;:::-;52802:18;:32;52821:12;:10;:12::i;:::-;-1:-1:-1::0;;;;;52802:32:0;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;;-1:-1:-1;52802:32:0;;;:80;;;;52900:5:::1;::::0;:35;;-1:-1:-1;;;52900:35:0;;;;::::1;;::::0;::::1;::::0;;;;;;;;;:5;::::1;::::0;:14:::1;::::0;:35;;;;;52802:32;;52900:35;;;;;;;;;:5;:35;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;52900:35:0;52893:43:::1;;;;52700:244:::0;;;:::o;22578:106::-;22666:10;22578:106;:::o;12166:422::-;12533:20;12572:8;;;12166:422::o;45822:271::-;46032:51;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;46032:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46022:62;;;;;;45822:271::o;46504:174::-;46628:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46618:52;;;;;;46504:174::o;6816:179::-;6874:7;6906:5;;;6930:6;;;;6922:46;;;;;-1:-1:-1;;;6922:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;6986:1;6816:179;-1:-1:-1;;;6816:179:0:o;57805:2159::-;57922:22;57959:24;;:::i;:::-;58435:13;;57998:17;;;;58263:19;;58435:31;;58427:62;;;;;-1:-1:-1;;;58427:62:0;;;;;;;;;;;;-1:-1:-1;;;58427:62:0;;;;;;;;;;;;;;;58500:27;;:::i;:::-;-1:-1:-1;58757:14:0;58745:27;;58739:34;58805:27;;;58799:34;58696:17;58684:30;;;58739:34;58871:20;58684:30;58871:9;:20::i;:::-;58854:37;;58914:38;58928:14;58944:7;58914:13;:38::i;:::-;58974:20;;;;:9;:20;;;;;;;;;58963:31;;;;;;;;;-1:-1:-1;;;;;58963:31:0;;;;;-1:-1:-1;;;58963:31:0;;;-1:-1:-1;;;;;58963:31:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;58974:20:0;;-1:-1:-1;59005:76:0;;;;;-1:-1:-1;;;59005:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;59138:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59128:46;;;;;59100:24;;;;:74;59092:113;;;;;-1:-1:-1;;;59092:113:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;59238:19;;59272:23;59268:178;;59324:14;;:37;;;-1:-1:-1;;;59324:37:0;;;;;;;;;;-1:-1:-1;;;;;59324:14:0;;;;:27;;:37;;;;;;;;;;;;;;;:14;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59324:37:0;;-1:-1:-1;59384:23:0;59376:58;;;;;-1:-1:-1;;;59376:58:0;;;;;;;;;;;;-1:-1:-1;;;59376:58:0;;;;;;;;;;;;;;;59576:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59566:47;;;;;59795:14;59783:27;;59776:47;;;59852:12;59837:28;;59899:35;59787:6;59899:27;:35::i;:::-;59886:48;;57805:2159;;;;;;;;;;;:::o;56309:1488::-;56638:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;56638:78:0;-1:-1:-1;;;56638:78:0;;;56589:18;;57022:6;;57047:9;:14;;57039:54;;;;;-1:-1:-1;;;57039:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;57558:12;57576:16;-1:-1:-1;;;;;57576:21:0;57598:4;57576:27;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;57576:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;56309:1488:0:o;7278:158::-;7336:7;7369:1;7364;:6;;7356:49;;;;;-1:-1:-1;;;7356:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7423:5:0;;;7278:158::o;43757:1270::-;43833:14;42826:361;43868:5;:12;:28;43860:59;;;;;-1:-1:-1;;;43860:59:0;;;;;;;;;;;;-1:-1:-1;;;43860:59:0;;;;;;;;;;;;;;;43932:20;;:::i;:::-;44008:23;;:::i;:::-;44123:24;;:::i;:::-;44158:16;44185:31;;:::i;:::-;44227:30;;:::i;:::-;44268:12;44384:5;44373:294;;;;;;;;;;;;;;;-1:-1:-1;44373:294:0;;;;;;;;;;-1:-1:-1;44373:294:0;;;;-1:-1:-1;44373:294:0;;;;-1:-1:-1;44373:294:0;-1:-1:-1;44373:294:0;;;;-1:-1:-1;44373:294:0;;;;-1:-1:-1;44373:294:0;-1:-1:-1;44680:249:0;44373:294;;;44753:1;44746:9;;;;44775:6;44782:1;44775:9;;;;44804:6;44811:1;44804:9;;;;44836:8;44859:13;44887:12;44914:4;44680:14;:249::i;:::-;42696:1;45011:5;44969:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44959:59;;;;;;44951:68;;44942:77;;43757:1270;;;;;;;;;;:::o;41200:1366::-;41525:13;41535:2;41525:9;:13::i;:::-;41517:52;;;;;-1:-1:-1;;;41517:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;41588:16;41598:5;41588:9;:16::i;:::-;41580:50;;;;;-1:-1:-1;;;41580:50:0;;;;;;;;;;;;-1:-1:-1;;;41580:50:0;;;;;;;;;;;;;;;41649:24;41659:13;41649:9;:24::i;:::-;41641:66;;;;;-1:-1:-1;;;41641:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;41726:23;41736:12;41726:9;:23::i;:::-;41718:64;;;;;-1:-1:-1;;;41718:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;41801:56;41838:1;41841:2;41845:1;41848:8;41801:36;:56::i;:::-;41793:95;;;;;-1:-1:-1;;;41793:95:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;41989:22;;:::i;:::-;42014:21;42026:2;42030:4;42014:11;:21::i;:::-;41989:46;;42133:19;;:::i;:::-;42168:205;42204:1;42224:5;42248:13;42280:1;42300:4;42323:12;42354:4;42168:17;:205::i;:::-;42133:240;;42438:16;42457:51;42479:4;42485:2;42489:5;42496:8;42506:1;42457:21;:51::i;:::-;42438:70;;42532:8;42527:1;:13;42519:39;;;;;-1:-1:-1;;;42519:39:0;;;;;;;;;;;;-1:-1:-1;;;42519:39:0;;;;;;;;;;;;;;;41200:1366;;;;;;;;;;;;:::o;27843:143::-;27961:4;;;;27906;;-1:-1:-1;;25644:66:0;27961:4;27948:30;27930:14;27939:1;27941;27939:4;;;;;27930:8;:14::i;:::-;:48;;27843:143;-1:-1:-1;;27843:143:0:o;37269:1118::-;37443:4;-1:-1:-1;;;;;37537:23:0;;37529:47;;;;;-1:-1:-1;;;37529:47:0;;;;;;;;;;;;-1:-1:-1;;;37529:47:0;;;;;;;;;;;;;;;37598:4;;;;37587:7;;37598:8;;:13;37597:25;;37620:2;37597:25;;;37615:2;37597:25;37587:35;-1:-1:-1;37662:18:0;-1:-1:-1;;37718:1:0;37712;37714;37712:4;;;;37705:28;37800:4;;-1:-1:-1;;37691:42:0;;;;-1:-1:-1;37683:51:0;;25394:66;37797:1;37790:28;37782:37;-1:-1:-1;37782:37:0;38284:56;38294:10;38306:1;38317;37782:37;38317:4;;;;38309:13;;38324:15;38284:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;38284:56:0;;-1:-1:-1;;38284:56:0;;-1:-1:-1;;;;;38358:21:0;;;;;;;;-1:-1:-1;;;;;;37269:1118:0;;;;;;:::o;29752:325::-;29833:20;;:::i;:::-;29871:82;28932:1;29942:2;29946:5;29898:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29871:26;:82::i;:::-;29866:87;;29964:106;29972:13;29982:2;29972:9;:13::i;:::-;29964:106;;30051:5;;30034:23;;;30051:5;30034:23;;;;;;;;;;;;;;;;;;;;;30007:51;;:26;:51::i;:::-;30002:56;;29964:106;;38895:624;39155:17;;:::i;:::-;39210:13;;39194;;-1:-1:-1;;25644:66:0;39194:29;;39193:44;39185:92;;;;;-1:-1:-1;;;39185:92:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;39296:30;39308:2;39312:1;39315:10;39296:11;:30::i;:::-;39288:76;;;;-1:-1:-1;;;39288:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39383:30;39395:2;39399:1;39402:10;39383:11;:30::i;:::-;39375:77;;;;-1:-1:-1;;;39375:77:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39470:41;39482:10;39494;39506:4;39470:11;:41::i;:::-;39463:48;38895:624;-1:-1:-1;;;;;;;;38895:624:0:o;39971:615::-;40187:9;39658:1;40393:4;40424:2;40453:5;40485:1;40513:8;40287:257;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;40287:257:0;;;;;;;;;;;;;;;;;;;;;;;;;;;40255:308;;;;;;40229:349;;40209:369;;39971:615;;;;;;;:::o;27523:277::-;27575:7;;-1:-1:-1;;25644:66:0;27718:1;27715;27708:24;27705:1;27698:47;27681:64;-1:-1:-1;;;27778:1:0;27770:6;27763:29;27756:36;27523:277;-1:-1:-1;;;27523:277:0:o;28558:258::-;28633:19;;:::i;:::-;28672:12;28682:1;28672:9;:12::i;:::-;28665:19;;28702:26;28713:14;28665:1;28667;28722:4;;28713:14;28702:10;:26::i;:::-;28695:4;;;:33;;;28750:1;;28743:8;28755:1;28743:13;28739:70;;;28793:4;;;;;-1:-1:-1;;28780:17:0;28773:24;;28793:1;28558:258;-1:-1:-1;28558:258:0:o;30603:1094::-;30756:13;30790:11;30782:44;;;;;-1:-1:-1;;;30782:44:0;;;;;;;;;;;;-1:-1:-1;;;30782:44:0;;;;;;;;;;;;;;;30888:15;;;30954;;;30876:9;;30954:19;;:24;:34;;30986:2;30954:34;;;30981:2;30954:34;30944:44;-1:-1:-1;31362:20:0;-1:-1:-1;;31408:1:0;31400:6;31393:30;31452:50;;;31385:39;31452:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31385:39;;-1:-1:-1;31385:39:0;31452:50;;;;;;;;;-1:-1:-1;;31452:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31435:67;;31578:16;31640:7;31623:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31613:36;;;;;;31605:45;;31578:73;;31680:8;-1:-1:-1;;;;;31670:18:0;:6;-1:-1:-1;;;;;31670:18:0;;31662:27;;;;;;;30603:1094;;;;;:::o;36553:587::-;36689:17;;:::i;:::-;36807:5;;;36814;;;;36821;;36828;;;;36719:9;;;;;;36791:43;;36814:5;;36821;36791:15;:43::i;:::-;36779:55;;-1:-1:-1;36779:55:0;-1:-1:-1;36779:55:0;-1:-1:-1;;;36863:4:0;36860:1;36853:27;36884:1;36853:32;36845:70;;;;;-1:-1:-1;;;36845:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;37067:65;;;;;;;;-1:-1:-1;;37075:27:0;;;;;37085:4;37082:1;37075:27;37067:65;;;;-1:-1:-1;;37114:4:0;37111:1;37104:27;37067:65;;;36553:587;-1:-1:-1;;;;;;;36553:587:0:o;28048:434::-;28142:12;;;;;;28378:97;-1:-1:-1;;28385:2:0;:16;28378:97;;28441:20;;;;;;;;;;;;;;;;;;;;;;;;;;28431:31;;;;;28378:97;;27343:113;27397:7;27424:24;27434:1;-1:-1:-1;;;;;27424:9:0;:24::i;34060:2199::-;34226:10;;;35005:1;;34226:10;-1:-1:-1;;35131:2:0;-1:-1:-1;;35118:15:0;35114:2;35107:39;35094:52;-1:-1:-1;35157:10:0;-1:-1:-1;;35194:2:0;-1:-1:-1;;35181:15:0;35177:2;35170:39;35157:52;;35222:10;35342:29;35356:2;35360;35364;35368;35342:13;:29::i;:::-;35331:40;;-1:-1:-1;35331:40:0;-1:-1:-1;35416:29:0;35331:40;;35438:2;35442;35416:13;:29::i;:::-;35405:40;;-1:-1:-1;35405:40:0;-1:-1:-1;35493:29:0;35405:40;;35515:2;35519;35493:13;:29::i;:::-;35482:40;;-1:-1:-1;35482:40:0;-1:-1:-1;35564:10:0;35686:29;35700:2;35704;35482:40;;35686:13;:29::i;:::-;35675:40;;-1:-1:-1;35675:40:0;-1:-1:-1;35746:29:0;35675:40;;35768:2;35772;35746:13;:29::i;:::-;35735:40;;-1:-1:-1;35735:40:0;-1:-1:-1;35825:29:0;35735:40;;35847:2;35851;35825:13;:29::i;:::-;35814:40;;-1:-1:-1;35814:40:0;-1:-1:-1;35902:8:0;;;35898:354;;-1:-1:-1;;36018:2:0;36014;36007:26;36002:31;-1:-1:-1;;;36064:2:0;36060;36053:26;36048:31;-1:-1:-1;;;36110:2:0;36106;36099:26;36094:31;;35898:354;;;36238:2;36233:7;;35898:354;34060:2199;;;;;;;;;;;;;;:::o;25896:1131::-;25970:22;26005:18;26034:41;;:::i;:::-;25762:4;26086:46;;;26161:26;;;:46;;;26240:26;;;:46;26318:26;;;:33;;;26362:26;;;:37;;;-1:-1:-1;;26410:26:0;;;:39;26460:24;;:::i;:::-;26849:4;26824:6;26760:4;26718:23;26665:4;-1:-1:-1;;26589:307:0;26575:321;-1:-1:-1;26921:15:0;26917:76;;26953:28;;;-1:-1:-1;;;26953:28:0;;;;;;;;;;;;-1:-1:-1;;;26953:28:0;;;;;;;;;;;;;;26917:76;27010:9;;;-1:-1:-1;;;;;25896:1131:0:o;32255:247::-;32392:10;;-1:-1:-1;;32450:2:0;32446;32439:26;-1:-1:-1;;32478:2:0;32474;32467:26;32427:67;;;;-1:-1:-1;32255:247:0;-1:-1:-1;;;;;32255:247:0:o;31794:368::-;31931:10;;;-1:-1:-1;;31992:2:0;31988;31981:26;31966:41;-1:-1:-1;32018:12:0;-1:-1:-1;;32057:2:0;32053;-1:-1:-1;;32040:15:0;32033:39;32018:54;-1:-1:-1;;;32108:4:0;32102;32095:30;-1:-1:-1;;32138:2:0;32134;32127:26;32083:71;;;;-1:-1:-1;31794:368:0;-1:-1:-1;;;;;;;31794:368:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o

Swarm Source

ipfs://f2c5a363d0a5a524a188e3c3ca80e80c90fb165d91926f3890127d42c8d90b36
Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading

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.