Contract 0xa555fc018435bef5a13c6c6870a9d4c11dec329c 2

Contract Overview

Balance:
0 BNB

Token:
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x64eee5d4475e9f2ad12567235598645809aa295e6b868a3fc85ca258ba268086Fulfill Randomne...126470772021-09-24 14:20:2018 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.002429952
0x22422fbce18b050a350094b7118f191e776237e20d293b1c40bea030bbfdabccFulfill Randomne...126466792021-09-24 14:00:2638 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.002119803
0xef15f62b7e28c9cecf0cc7c0543166eabcb522ee848d504145ba000be9f895d1Fulfill Randomne...126464932021-09-24 13:51:0847 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.001178163
0xbcc0287dc240f24fb6b50501c6d6d7b84c275147f6b65e569f911dcf38665ad3Fulfill Randomne...126459082021-09-24 13:21:531 hr 17 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.001177365
0x577e10b5c7310a026e78f1047a9ae92dd89ff6e18eb4666e60bd42d3a89d6e4cFulfill Randomne...126456462021-09-24 13:08:471 hr 30 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.001590771
0xd2590ba30ca52c5b5a1028fc2ce262d281ca16d258755ee920661efb712e0b89Fulfill Randomne...126453382021-09-24 12:53:231 hr 45 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.001590477
0xfb9e27f2c762ae4990ac4f76cd8965e510717d0df41706a6e1f6ee1bb4fba6dcFulfill Randomne...126453232021-09-24 12:52:381 hr 46 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.001493205
0xb7840d9a3635686f5801cf62326f98b7f3496f9f4781bcdb9085819a208db125Fulfill Randomne...126451052021-09-24 12:41:441 hr 57 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.001590225
0xa0077db793ccd3f2dfd2082dedebf7d64a8eabadaf4b0c60cfdc7ae93135cd3cFulfill Randomne...126447672021-09-24 12:24:502 hrs 14 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.002703687
0xde1c000e5140578d0a8845783cc082272266b88249f4f908c0944a2d95f283d1Fulfill Randomne...126447392021-09-24 12:23:262 hrs 15 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.001177617
0xeb9c8b294b6f20af1d991dcabcf497f45dbb70911359aa82de4115986f04bd30Fulfill Randomne...126443312021-09-24 12:03:022 hrs 36 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.003016293
0x956f435184e32e2680af9dbef0da688b5a56141eaf53423c1af799ffd461a880Fulfill Randomne...126441552021-09-24 11:54:142 hrs 44 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.001805013
0x815db897b097636d0c600d346443abf5499fb77b7f27a7ebe9c80339e4458e2aFulfill Randomne...126439422021-09-24 11:43:352 hrs 55 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.001275162
0xf992ab07721630702751fbcb1fbb328089a090c38cdce978f2178a783ca6c910Fulfill Randomne...126427042021-09-24 10:41:413 hrs 57 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.014700252
0x3eb0eceb5257a420fd6eec3b3fe5efbd54de532a8b28c48e2d633d46da71d117Fulfill Randomne...126426712021-09-24 10:40:023 hrs 59 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.010118976
0x0c1fb63096ab3a81111180cc532bd53dbb0c309492d5a17f762cce6696025fa4Fulfill Randomne...126426282021-09-24 10:37:534 hrs 1 min ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.013703235
0x344f171cca7da2b2f370bcdf248e389ca8cf2a9cecc359504bf022ff1ef38f95Fulfill Randomne...126425762021-09-24 10:35:174 hrs 3 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.013702941
0xbbeb5a7c6c28e6710429314b415c461ecf562d06d96443cb0c70e2c162162c3eFulfill Randomne...126425472021-09-24 10:33:504 hrs 5 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.013634607
0xd70a6c0243657123f2c9b9457690cbcb618a8a5461ac52865244e442b1eb7ff2Fulfill Randomne...126425092021-09-24 10:31:564 hrs 7 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.013452222
0xe5316648748a8fb79c2d8c6c04c5fea8d443712b1a4069e0354a18893e213c4dFulfill Randomne...126424742021-09-24 10:30:114 hrs 8 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.014136843
0x796794236f7a2b2154450842e76e4f4620a9457bae731497626100c83ca6cac9Fulfill Randomne...126414872021-09-24 9:40:504 hrs 58 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.001636488
0xf75fe3614cef26349395642e7d35ac6190773b2a648d0d0d38242a268ff075b1Fulfill Randomne...126407302021-09-24 9:02:595 hrs 36 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.002703015
0x338fe10b14985b7e41344df768129942df28ba3e2f494401487e524809af34acFulfill Randomne...126402842021-09-24 8:40:415 hrs 58 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.00138852
0xea2a5f939f9e4e910f978db110d22242be0461a7266ed7ef18ed5edc8208a3a0Fulfill Randomne...126396292021-09-24 8:07:516 hrs 31 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.002419284
0x558ba8021f598cc91a656ee038503c08f82df9b34680c2299da680b27ce943f6Fulfill Randomne...126378022021-09-24 6:36:308 hrs 2 mins ago0x4edfb2663b3f0dc627fd45c61d8a037848b6f86f IN  0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB0.002120013
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x64eee5d4475e9f2ad12567235598645809aa295e6b868a3fc85ca258ba268086126470772021-09-24 14:20:2018 mins ago 0xa555fc018435bef5a13c6c6870a9d4c11dec329c 0x43100a0f16211e790e807ed2cf341ac9b248482f0 BNB
0x7d576fb9485eda608f1bdec1fb1c2f8410788574cf5a5980465f8d6690260737126470602021-09-24 14:19:2919 mins ago 0x84b9b910527ad5c03a9ca831909e21e236ea7b06 0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB
0x22422fbce18b050a350094b7118f191e776237e20d293b1c40bea030bbfdabcc126466792021-09-24 14:00:2638 mins ago 0xa555fc018435bef5a13c6c6870a9d4c11dec329c 0x3fdbaeba43995966ce3b11b731f1da292752d80b0 BNB
0xff06fc289bb4e8d0c6133e223aa59e73a43be5ea221783fac44dda176ec12adf126466622021-09-24 13:59:3539 mins ago 0x84b9b910527ad5c03a9ca831909e21e236ea7b06 0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB
0xef15f62b7e28c9cecf0cc7c0543166eabcb522ee848d504145ba000be9f895d1126464932021-09-24 13:51:0847 mins ago 0xa555fc018435bef5a13c6c6870a9d4c11dec329c 0x43100a0f16211e790e807ed2cf341ac9b248482f0 BNB
0x91fe7277422aad855586147e80c4a5d29d78a60a689955976bfb10fce8c31cbb126464762021-09-24 13:50:1748 mins ago 0x84b9b910527ad5c03a9ca831909e21e236ea7b06 0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB
0xbcc0287dc240f24fb6b50501c6d6d7b84c275147f6b65e569f911dcf38665ad3126459082021-09-24 13:21:531 hr 17 mins ago 0xa555fc018435bef5a13c6c6870a9d4c11dec329c 0x43100a0f16211e790e807ed2cf341ac9b248482f0 BNB
0x50ba8363981c318476bf1a4bd39973df5df34fc446c37fb1c98d9521b29a402d126458912021-09-24 13:21:021 hr 18 mins ago 0x84b9b910527ad5c03a9ca831909e21e236ea7b06 0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB
0x577e10b5c7310a026e78f1047a9ae92dd89ff6e18eb4666e60bd42d3a89d6e4c126456462021-09-24 13:08:471 hr 30 mins ago 0xa555fc018435bef5a13c6c6870a9d4c11dec329c 0x429c804a3c4a14a2476087b8297d5a5d14fd16d40 BNB
0x6934b36f1cdd83d6fb1864fb073eb58a91e47f465a60824a064d70c5bc77a38a126456292021-09-24 13:07:561 hr 31 mins ago 0x84b9b910527ad5c03a9ca831909e21e236ea7b06 0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB
0x524be9efe81dbdb591a44a8b39b8c257c4a6257698d75fcde4760ce84e041385126454382021-09-24 12:58:231 hr 40 mins ago 0x84b9b910527ad5c03a9ca831909e21e236ea7b06 0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB
0x6336e58594069ea016cc86e431dc504b09ec466512e754d9b3cb5b8d5df2964f126454232021-09-24 12:57:381 hr 41 mins ago 0x84b9b910527ad5c03a9ca831909e21e236ea7b06 0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB
0xd2590ba30ca52c5b5a1028fc2ce262d281ca16d258755ee920661efb712e0b89126453382021-09-24 12:53:231 hr 45 mins ago 0xa555fc018435bef5a13c6c6870a9d4c11dec329c 0xdb97d4afaaf3b390547a319f2481357a58781d030 BNB
0xfb9e27f2c762ae4990ac4f76cd8965e510717d0df41706a6e1f6ee1bb4fba6dc126453232021-09-24 12:52:381 hr 46 mins ago 0xa555fc018435bef5a13c6c6870a9d4c11dec329c 0x43100a0f16211e790e807ed2cf341ac9b248482f0 BNB
0xf4e4feb3e1a10e585f6061381a8b66f001999d5e4c994e82cbb725998f0fd598126453212021-09-24 12:52:321 hr 46 mins ago 0x84b9b910527ad5c03a9ca831909e21e236ea7b06 0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB
0x0987265e1062879075fa31b127ecb57637adeacc3932f6562d435912f15e59c2126453062021-09-24 12:51:471 hr 47 mins ago 0x84b9b910527ad5c03a9ca831909e21e236ea7b06 0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB
0xb7840d9a3635686f5801cf62326f98b7f3496f9f4781bcdb9085819a208db125126451052021-09-24 12:41:441 hr 57 mins ago 0xa555fc018435bef5a13c6c6870a9d4c11dec329c 0x4bd8d86fc41e0a7cc810183a6f14d20b5e81a9d10 BNB
0x6318384c8b9bbf32211710cc307c4e831b9b6afa111543c356d7b70ada04de2f126450882021-09-24 12:40:531 hr 58 mins ago 0x84b9b910527ad5c03a9ca831909e21e236ea7b06 0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB
0xa0077db793ccd3f2dfd2082dedebf7d64a8eabadaf4b0c60cfdc7ae93135cd3c126447672021-09-24 12:24:502 hrs 14 mins ago 0xa555fc018435bef5a13c6c6870a9d4c11dec329c 0x6fe8cd3ba80a0afd68efbb0e3614cbcec6aa95c70 BNB
0x85227c535a05f18e405237189fed3d629871ba5a404ec17dad91c58c8c98d0f2126447502021-09-24 12:23:592 hrs 15 mins ago 0x84b9b910527ad5c03a9ca831909e21e236ea7b06 0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB
0xde1c000e5140578d0a8845783cc082272266b88249f4f908c0944a2d95f283d1126447392021-09-24 12:23:262 hrs 15 mins ago 0xa555fc018435bef5a13c6c6870a9d4c11dec329c 0x43100a0f16211e790e807ed2cf341ac9b248482f0 BNB
0x2073b82106064c5fe0fa32b8fbcb17b8b196e882b75489f09fe333a717bd6895126447222021-09-24 12:22:352 hrs 16 mins ago 0x84b9b910527ad5c03a9ca831909e21e236ea7b06 0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB
0xeb9c8b294b6f20af1d991dcabcf497f45dbb70911359aa82de4115986f04bd30126443312021-09-24 12:03:022 hrs 36 mins ago 0xa555fc018435bef5a13c6c6870a9d4c11dec329c 0x679b12547dc89edf2cf8ca2631c303d5a06de2da0 BNB
0x45bb04638cb16676310822cee2b69d837e3635d6ad0cdca85b0018f72e45feeb126443142021-09-24 12:02:112 hrs 36 mins ago 0x84b9b910527ad5c03a9ca831909e21e236ea7b06 0xa555fc018435bef5a13c6c6870a9d4c11dec329c0 BNB
0x956f435184e32e2680af9dbef0da688b5a56141eaf53423c1af799ffd461a880126441552021-09-24 11:54:142 hrs 44 mins ago 0xa555fc018435bef5a13c6c6870a9d4c11dec329c 0x43100a0f16211e790e807ed2cf341ac9b248482f0 BNB
[ Download CSV Export 
Loading

Contract Source Code Verified (Similar Match)
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0xe69427c0D3A0103ec51CE70b66cc46D3eaCac0Ef

Contract Name:
VRFCoordinator

Compiler Version
v0.6.6+commit.6c089d02

Optimization Enabled:
Yes with 1000000 runs

Other Settings:
istanbul EvmVersion, MIT license

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 7 : VRFCoordinator.sol
pragma solidity 0.6.6;

import "./vendor/SafeMath.sol";

import "./interfaces/LinkTokenInterface.sol";
import "./interfaces/BlockHashStoreInterface.sol";

import "./VRF.sol";
import "./VRFRequestIDBase.sol";
import "./VRFConsumerBase.sol";

/**
 * @title VRFCoordinator coordinates on-chain verifiable-randomness requests
 * @title with off-chain responses
 */
contract VRFCoordinator is VRF, VRFRequestIDBase {

  using SafeMath for uint256;

  LinkTokenInterface internal LINK;
  BlockHashStoreInterface internal blockHashStore;

  constructor(address _link, address _blockHashStore) public {
    LINK = LinkTokenInterface(_link);
    blockHashStore = BlockHashStoreInterface(_blockHashStore);
  }

  struct Callback { // Tracks an ongoing request
    address callbackContract; // Requesting contract, which will receive response
    // Amount of LINK paid at request time. Total LINK = 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 VRF service
    address vRFOracle; // Oracle committing to respond with VRF service
    uint96 fee; // Minimum payment for oracle response. Total LINK=1e9*1e18<2^96
    bytes32 jobID; // ID of corresponding chainlink job in oracle's DB
  }

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

  // The oracle only needs the jobID to look up the VRF, but specifying public
  // key as well prevents a malicious oracle from inducing VRF outputs from
  // another oracle by reusing the jobID.
  event RandomnessRequest(
    bytes32 keyHash,
    uint256 seed,
    bytes32 indexed jobID,
    address sender,
    uint256 fee,
    bytes32 requestID);

  event NewServiceAgreement(bytes32 keyHash, uint256 fee);

  event RandomnessRequestFulfilled(bytes32 requestId, uint256 output);

  /**
   * @notice Commits calling address to serve randomness
   * @param _fee minimum LINK payment required to serve randomness
   * @param _oracle the address of the Chainlink node with the proving key and job
   * @param _publicProvingKey public key used to prove randomness
   * @param _jobID ID of the corresponding chainlink job in the oracle's db
   */
  function registerProvingKey(
    uint256 _fee, address _oracle, uint256[2] calldata _publicProvingKey, bytes32 _jobID
  )
    external
  {
    bytes32 keyHash = hashOfKey(_publicProvingKey);
    address oldVRFOracle = serviceAgreements[keyHash].vRFOracle;
    require(oldVRFOracle == address(0), "please register a new key");
    require(_oracle != address(0), "_oracle must not be 0x0");
    serviceAgreements[keyHash].vRFOracle = _oracle;
    serviceAgreements[keyHash].jobID = _jobID;
    // Yes, this revert message doesn't fit in a word
    require(_fee <= 1e9 ether,
      "you can't charge more than all the LINK in the world, greedy");
    serviceAgreements[keyHash].fee = uint96(_fee);
    emit NewServiceAgreement(keyHash, _fee);
  }

  /**
   * @notice Called by LINK.transferAndCall, on successful LINK transfer
   *
   * @dev To invoke this, use the requestRandomness method in VRFConsumerBase.
   *
   * @dev The VRFCoordinator will call back to the calling contract when the
   * @dev oracle responds, on the method fulfillRandomness. See
   * @dev VRFConsumerBase.fulfilRandomness for its signature. Your consuming
   * @dev contract should inherit from VRFConsumerBase, and implement
   * @dev fulfilRandomness.
   *
   * @param _sender address: who sent the LINK (must be a contract)
   * @param _fee amount of LINK sent
   * @param _data abi-encoded call to randomnessRequest
   */
  function onTokenTransfer(address _sender, uint256 _fee, bytes memory _data)
    public
    onlyLINK
  {
    (bytes32 keyHash, uint256 seed) = abi.decode(_data, (bytes32, uint256));
    randomnessRequest(keyHash, seed, _fee, _sender);
  }

  /**
   * @notice creates the chainlink request for randomness
   *
   * @param _keyHash ID of the VRF public key against which to generate output
   * @param _consumerSeed Input to the VRF, from which randomness is generated
   * @param _feePaid Amount of LINK sent with request. Must exceed fee for key
   * @param _sender Requesting contract; to be called back with VRF output
   *
   * @dev _consumerSeed is mixed with key hash, sender address and nonce to
   * @dev obtain preSeed, which is passed to VRF 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,
    address _sender
  )
    internal
    sufficientLINK(_feePaid, _keyHash)
  {
    uint256 nonce = nonces[_keyHash][_sender];
    uint256 preSeed = makeVRFInputSeed(_keyHash, _consumerSeed, _sender, nonce);
    bytes32 requestId = makeRequestId(_keyHash, preSeed);
    // Cryptographically guaranteed by preSeed including an increasing nonce
    assert(callbacks[requestId].callbackContract == address(0));
    callbacks[requestId].callbackContract = _sender;
    assert(_feePaid < 1e27); // Total LINK fits in uint96
    callbacks[requestId].randomnessFee = uint96(_feePaid);
    callbacks[requestId].seedAndBlockNum = keccak256(abi.encodePacked(
      preSeed, block.number));
    emit RandomnessRequest(_keyHash, preSeed, serviceAgreements[_keyHash].jobID,
      _sender, _feePaid, requestId);
    nonces[_keyHash][_sender] = nonces[_keyHash][_sender].add(1);
  }

  // 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;

  /**
   * @notice Called by the chainlink node to fulfill requests
   *
   * @param _proof the proof of randomness. Actual random output built from this
   *
   * @dev The structure of _proof corresponds to vrf.MarshaledOnChainResponse,
   * @dev in the node source code. I.e., it is a vrf.MarshaledProof with the
   * @dev seed replaced by the preSeed, followed by the hash of the requesting
   * @dev block.
   */
  function fulfillRandomnessRequest(bytes memory _proof) public {
    (bytes32 currentKeyHash, Callback memory callback, bytes32 requestId,
     uint256 randomness) = getRandomnessFromProof(_proof);

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

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

    emit RandomnessRequestFulfilled(requestId, randomness);
  }

  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
    VRFConsumerBase 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 BLOCKNUM_OFFSET = 0x20 + PROOF_LENGTH;
    // _proof.length skips the initial length word, so not including the
    // blocknum in this length check balances out.
    require(_proof.length == BLOCKNUM_OFFSET, "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, BLOCKNUM_OFFSET))
    }
    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 VRF 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 = VRF.randomValueFromVRFProof(_proof); // Reverts on failure
  }

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

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

  /**
   * @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 sufficientLINK(uint256 _feePaid, bytes32 _keyHash) {
    require(_feePaid >= serviceAgreements[_keyHash].fee, "Below agreed payment");
    _;
  }

/**
   * @dev Reverts if not sent from the LINK token
   */
  modifier onlyLINK() {
    require(msg.sender == address(LINK), "Must use LINK token");
    _;
  }

  /**
   * @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[msg.sender] >= _amount, "can't withdraw more than balance");
    _;
  }

}

File 2 of 7 : SafeMath.sol
pragma solidity ^0.6.0;

/**
 * @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, 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");
    uint256 c = a - b;

    return c;
  }

  /**
    * @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) {
    // 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-solidity/pull/522
    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. Reverts 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) {
    // Solidity only automatically asserts when dividing by 0
    require(b > 0, "SafeMath: division by zero");
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold

    return c;
  }

  /**
    * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
    * Reverts 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;
  }
}

File 3 of 7 : LinkTokenInterface.sol
pragma solidity ^0.6.0;

interface LinkTokenInterface {
  function allowance(address owner, address spender) external view returns (uint256 remaining);
  function approve(address spender, uint256 value) external returns (bool success);
  function balanceOf(address owner) external view returns (uint256 balance);
  function decimals() external view returns (uint8 decimalPlaces);
  function decreaseApproval(address spender, uint256 addedValue) external returns (bool success);
  function increaseApproval(address spender, uint256 subtractedValue) external;
  function name() external view returns (string memory tokenName);
  function symbol() external view returns (string memory tokenSymbol);
  function totalSupply() external view returns (uint256 totalTokensIssued);
  function transfer(address to, uint256 value) external returns (bool success);
  function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool success);
  function transferFrom(address from, address to, uint256 value) external returns (bool success);
}

File 4 of 7 : BlockHashStoreInterface.sol
pragma solidity 0.6.6;

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

File 5 of 7 : VRF.sol
pragma solidity 0.6.6;

/** ****************************************************************************
  * @notice Verification of verifiable-random-function (VRF) proofs, following
  * @notice https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.3
  * @notice See https://eprint.iacr.org/2017/099.pdf for security proofs.

  * @dev Bibliographic references:

  * @dev Goldberg, et al., "Verifiable Random Functions (VRFs)", Internet Draft
  * @dev draft-irtf-cfrg-vrf-05, IETF, Aug 11 2019,
  * @dev https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05

  * @dev Papadopoulos, et al., "Making NSEC5 Practical for DNSSEC", Cryptology
  * @dev ePrint Archive, Report 2017/099, https://eprint.iacr.org/2017/099.pdf
  * ****************************************************************************
  * @dev USAGE

  * @dev The main entry point is randomValueFromVRFProof. See its docstring.
  * ****************************************************************************
  * @dev PURPOSE

  * @dev Reggie the Random Oracle (not his real job) wants to provide randomness
  * @dev to Vera the verifier in such a way that Vera can be sure he's not
  * @dev making his output up to suit himself. Reggie provides Vera a public key
  * @dev to which he knows the secret key. Each time Vera provides a seed to
  * @dev Reggie, he gives back a value which is computed completely
  * @dev deterministically from the seed and the secret key.

  * @dev Reggie provides a proof by which Vera can verify that the output was
  * @dev correctly computed once Reggie tells it to her, but without that proof,
  * @dev the output is computationally indistinguishable to her from a uniform
  * @dev random sample from the output space.

  * @dev The purpose of this contract is to perform that verification.
  * ****************************************************************************
  * @dev DESIGN NOTES

  * @dev The VRF algorithm verified here satisfies the full unqiqueness, full
  * @dev collision resistance, and full pseudorandomness security properties.
  * @dev See "SECURITY PROPERTIES" below, and
  * @dev https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-3

  * @dev An elliptic curve point is generally represented in the solidity code
  * @dev as a uint256[2], corresponding to its affine coordinates in
  * @dev GF(FIELD_SIZE).

  * @dev For the sake of efficiency, this implementation deviates from the spec
  * @dev in some minor ways:

  * @dev - Keccak hash rather than the SHA256 hash recommended in
  * @dev   https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.5
  * @dev   Keccak costs much less gas on the EVM, and provides similar security.

  * @dev - Secp256k1 curve instead of the P-256 or ED25519 curves recommended in
  * @dev   https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.5
  * @dev   For curve-point multiplication, it's much cheaper to abuse ECRECOVER

  * @dev - hashToCurve recursively hashes until it finds a curve x-ordinate. On
  * @dev   the EVM, this is slightly more efficient than the recommendation in
  * @dev   https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.4.1.1
  * @dev   step 5, to concatenate with a nonce then hash, and rehash with the
  * @dev   nonce updated until a valid x-ordinate is found.

  * @dev - hashToCurve does not include a cipher version string or the byte 0x1
  * @dev   in the hash message, as recommended in step 5.B of the draft
  * @dev   standard. They are unnecessary here because no variation in the
  * @dev   cipher suite is allowed.

  * @dev - Similarly, the hash input in scalarFromCurvePoints does not include a
  * @dev   commitment to the cipher suite, either, which differs from step 2 of
  * @dev   https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.4.3
  * @dev   . Also, the hash input is the concatenation of the uncompressed
  * @dev   points, not the compressed points as recommended in step 3.

  * @dev - In the calculation of the challenge value "c", the "u" value (i.e.
  * @dev   the value computed by Reggie as the nonce times the secp256k1
  * @dev   generator point, see steps 5 and 7 of
  * @dev   https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.3
  * @dev   ) is replaced by its ethereum address, i.e. the lower 160 bits of the
  * @dev   keccak hash of the original u. This is because we only verify the
  * @dev   calculation of u up to its address, by abusing ECRECOVER.
  * ****************************************************************************
  * @dev   SECURITY PROPERTIES

  * @dev Here are the security properties for this VRF:

  * @dev Full uniqueness: For any seed and valid VRF public key, there is
  * @dev   exactly one VRF output which can be proved to come from that seed, in
  * @dev   the sense that the proof will pass verifyVRFProof.

  * @dev Full collision resistance: It's cryptographically infeasible to find
  * @dev   two seeds with same VRF output from a fixed, valid VRF key

  * @dev Full pseudorandomness: Absent the proofs that the VRF outputs are
  * @dev   derived from a given seed, the outputs are computationally
  * @dev   indistinguishable from randomness.

  * @dev https://eprint.iacr.org/2017/099.pdf, Appendix B contains the proofs
  * @dev for these properties.

  * @dev For secp256k1, the key validation described in section
  * @dev https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.6
  * @dev is unnecessary, because secp256k1 has cofactor 1, and the
  * @dev representation of the public key used here (affine x- and y-ordinates
  * @dev of the secp256k1 point on the standard y^2=x^3+7 curve) cannot refer to
  * @dev the point at infinity.
  * ****************************************************************************
  * @dev OTHER SECURITY CONSIDERATIONS
  *
  * @dev The seed input to the VRF could in principle force an arbitrary amount
  * @dev of work in hashToCurve, by requiring extra rounds of hashing and
  * @dev checking whether that's yielded the x ordinate of a secp256k1 point.
  * @dev However, under the Random Oracle Model the probability of choosing a
  * @dev point which forces n extra rounds in hashToCurve is 2⁻ⁿ. The base cost
  * @dev for calling hashToCurve is about 25,000 gas, and each round of checking
  * @dev for a valid x ordinate costs about 15,555 gas, so to find a seed for
  * @dev which hashToCurve would cost more than 2,017,000 gas, one would have to
  * @dev try, in expectation, about 2¹²⁸ seeds, which is infeasible for any
  * @dev foreseeable computational resources. (25,000 + 128 * 15,555 < 2,017,000.)

  * @dev Since the gas block limit for the Ethereum main net is 10,000,000 gas,
  * @dev this means it is infeasible for an adversary to prevent correct
  * @dev operation of this contract by choosing an adverse seed.

  * @dev (See TestMeasureHashToCurveGasCost for verification of the gas cost for
  * @dev hashToCurve.)

  * @dev It may be possible to make a secure constant-time hashToCurve function.
  * @dev See notes in hashToCurve docstring.
*/
contract VRF {

  // See https://www.secg.org/sec2-v2.pdf, section 2.4.1, for these constants.
  uint256 constant private 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 constant private FIELD_SIZE =
    // solium-disable-next-line indentation
    0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F;
  uint256 constant private 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 constant private 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. The y ordinate
  // is always even, due to
  // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.4.1.1
  // step 5.C, which references arbitrary_string_to_point, defined in
  // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.5 as
  // returning the point with given x ordinate, and even y ordinate.
  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. Corresponds to
  // vrf.go/hashToCurveHashPrefix
  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); // 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 isValidVRFOutput. But consider using a faster
      @dev re-implementation such as ProjectiveECAdd in the golang vrf package.

      @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 verifyVRFProof 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.
  // Corresponds to scalarFromCurveHashPrefix in vrf.go
  uint256 constant SCALAR_FROM_CURVE_POINTS_HASH_PREFIX = 2;

  // Pseudo-random number from inputs. Matches vrf.go/scalarFromCurvePoints, and
  // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-05#section-5.4.3
  // The draft calls (in step 7, via the definition of string_to_int, in
  // https://datatracker.ietf.org/doc/html/rfc8017#section-4.2 ) for taking the
  // first hash without checking that it corresponds to a number less than the
  // group order, which will lead to a slight bias in the sample.
  //
  // 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 verifyVRFProof(
    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");
      // Step 5. of IETF draft section 5.3 (pk corresponds to 5.3's Y, and here
      // we use the address of u instead of u itself. Also, here we add the
      // terms instead of taking the difference, and in the proof consruction in
      // vrf.GenerateProof, we correspondingly take the difference instead of
      // taking the sum as they do in step 7 of section 5.1.)
      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 VRF output.
  // Corresponds to vrfRandomOutputHashPrefix in vrf.go
  uint256 constant VRF_RANDOM_OUTPUT_HASH_PREFIX = 3;

  // Length of proof marshaled to bytes array. Shows layout of proof
  uint 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, as output by vrf.Proof.MarshalForSolidityVerifier
   *
   * 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 randomValueFromVRFProof(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));
      verifyVRFProof(
        pk,
        gamma,
        cSSeed[0], // c
        cSSeed[1], // s
        cSSeed[2], // seed
        uWitness,
        cGammaWitness,
        sHashWitness,
        zInv
      );
      output = uint256(keccak256(abi.encode(VRF_RANDOM_OUTPUT_HASH_PREFIX, gamma)));
    }
}

File 6 of 7 : VRFRequestIDBase.sol
pragma solidity ^0.6.0;

contract VRFRequestIDBase {

  /**
   * @notice returns the seed which is actually input to the VRF coordinator
   *
   * @dev To prevent repetition of VRF 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 VRF seed input provided by user
   * @param _requester Address of the requesting contract
   * @param _nonce User-specific nonce at the time of the request
   */
  function makeVRFInputSeed(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 _vRFInputSeed The seed to be passed directly to the VRF
   * @return The id for this request
   *
   * @dev Note that _vRFInputSeed is not the seed passed by the consuming
   * @dev contract, but the one generated by makeVRFInputSeed
   */
  function makeRequestId(
    bytes32 _keyHash, uint256 _vRFInputSeed) internal pure returns (bytes32) {
    return keccak256(abi.encodePacked(_keyHash, _vRFInputSeed));
  }
}

File 7 of 7 : VRFConsumerBase.sol
pragma solidity ^0.6.0;

import { SafeMath as SafeMath_Chainlink } from "./vendor/SafeMath.sol";

import "./interfaces/LinkTokenInterface.sol";

import "./VRFRequestIDBase.sol";

/** ****************************************************************************
 * @notice Interface for contracts using VRF randomness
 * *****************************************************************************
 * @dev PURPOSE
 *
 * @dev Reggie the Random Oracle (not his real job) wants to provide randomness
 * @dev to Vera the verifier in such a way that Vera can be sure he's not
 * @dev making his output up to suit himself. Reggie provides Vera a public key
 * @dev to which he knows the secret key. Each time Vera provides a seed to
 * @dev Reggie, he gives back a value which is computed completely
 * @dev deterministically from the seed and the secret key.
 *
 * @dev Reggie provides a proof by which Vera can verify that the output was
 * @dev correctly computed once Reggie tells it to her, but without that proof,
 * @dev the output is indistinguishable to her from a uniform random sample
 * @dev from the output space.
 *
 * @dev The purpose of this contract is to make it easy for unrelated contracts
 * @dev to talk to Vera the verifier about the work Reggie is doing, to provide
 * @dev simple access to a verifiable source of randomness.
 * *****************************************************************************
 * @dev USAGE
 *
 * @dev Calling contracts must inherit from VRFConsumerInterface, and can
 * @dev initialize VRFConsumerInterface's attributes in their constructor as
 * @dev shown:
 *
 * @dev   contract VRFConsumer {
 * @dev     constuctor(<other arguments>, address _vrfCoordinator, address _link)
 * @dev       VRFConsumerBase(_vrfCoordinator, _link) public {
 * @dev         <initialization with other arguments goes here>
 * @dev       }
 * @dev   }
 *
 * @dev The oracle will have given you an ID for the VRF keypair they have
 * @dev committed to (let's call it keyHash), and have told you the minimum LINK
 * @dev price for VRF service. Make sure your contract has sufficient LINK, and
 * @dev call requestRandomness(keyHash, fee, seed), where seed is the input you
 * @dev want to generate randomness from.
 *
 * @dev Once the VRFCoordinator has received and validated the oracle's response
 * @dev to your request, it will call your contract's fulfillRandomness method.
 *
 * @dev The randomness argument to fulfillRandomness is the actual random value
 * @dev generated from your seed.
 *
 * @dev The requestId argument is generated from the keyHash and the seed by
 * @dev makeRequestId(keyHash, seed). If your contract could have concurrent
 * @dev requests open, you can use the requestId to track which seed is
 * @dev associated with which randomness. See VRFRequestIDBase.sol for more
 * @dev details.
 *
 * @dev Colliding `requestId`s are cryptographically impossible as long as seeds
 * @dev differ. (Which is critical to making unpredictable randomness! See the
 * @dev next section.)
 *
 * *****************************************************************************
 * @dev SECURITY CONSIDERATIONS
 *
 * @dev Since the ultimate input to the VRF is mixed with the block hash of the
 * @dev block in which the request is made, user-provided seeds have no impact
 * @dev on its economic security properties. They are only included for API
 * @dev compatability with previous versions of this contract.
 *
 * @dev Since the block hash of the block which contains the requestRandomness()
 * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful
 * @dev miner could, in principle, fork the blockchain to evict the block
 * @dev containing the request, forcing the request to be included in a
 * @dev different block with a different hash, and therefore a different input
 * @dev to the VRF. However, such an attack would incur a substantial economic
 * @dev cost. This cost scales with the number of blocks the VRF oracle waits
 * @dev until it calls fulfillRandomness().
 */
abstract contract VRFConsumerBase is VRFRequestIDBase {

  using SafeMath_Chainlink for uint256;

  /**
   * @notice fulfillRandomness handles the VRF response. Your contract must
   * @notice implement it.
   *
   * @dev The VRFCoordinator expects a calling contract to have a method with
   * @dev this signature, and will trigger it once it has verified the proof
   * @dev associated with the randomness (It is triggered via a call to
   * @dev rawFulfillRandomness, below.)
   *
   * @param requestId The Id initially returned by requestRandomness
   * @param randomness the VRF output
   */
  function fulfillRandomness(bytes32 requestId, uint256 randomness)
    internal virtual;

  /**
   * @notice requestRandomness initiates a request for VRF output given _seed
   *
   * @dev See "SECURITY CONSIDERATIONS" above for more information on _seed.
   *
   * @dev The fulfillRandomness method receives the output, once it's provided
   * @dev by the Oracle, and verified by the vrfCoordinator.
   *
   * @dev The _keyHash must already be registered with the VRFCoordinator, and
   * @dev the _fee must exceed the fee specified during registration of the
   * @dev _keyHash.
   *
   * @param _keyHash ID of public key against which randomness is generated
   * @param _fee The amount of LINK to send with the request
   * @param _seed seed mixed into the input of the VRF
   *
   * @return requestId unique ID for this request
   *
   * @dev The returned requestId can be used to distinguish responses to *
   * @dev concurrent requests. It is passed as the first argument to
   * @dev fulfillRandomness.
   */
  function requestRandomness(bytes32 _keyHash, uint256 _fee, uint256 _seed)
    public returns (bytes32 requestId)
  {
    LINK.transferAndCall(vrfCoordinator, _fee, abi.encode(_keyHash, _seed));
    // This is the seed passed to VRFCoordinator. The oracle will mix this with
    // the hash of the block containing this request to obtain the seed/input
    // which is finally passed to the VRF cryptographic machinery.
    uint256 vRFSeed  = makeVRFInputSeed(_keyHash, _seed, address(this), nonces[_keyHash]);
    // nonces[_keyHash] must stay in sync with
    // VRFCoordinator.nonces[_keyHash][this], which was incremented by the above
    // successful LINK.transferAndCall (in VRFCoordinator.randomnessRequest).
    // This provides protection against the user repeating their input
    // seed, which would result in a predictable/duplicate output.
    nonces[_keyHash] = nonces[_keyHash].add(1);
    return makeRequestId(_keyHash, vRFSeed);
  }

  LinkTokenInterface immutable internal LINK;
  address immutable private vrfCoordinator;

  // Nonces for each VRF key from which randomness has been requested.
  //
  // Must stay in sync with VRFCoordinator[_keyHash][this]
  mapping(bytes32 /* keyHash */ => uint256 /* nonce */) public nonces;
  constructor(address _vrfCoordinator, address _link) public {
    vrfCoordinator = _vrfCoordinator;
    LINK = LinkTokenInterface(_link);
  }

  // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF
  // proof. rawFulfillRandomness then calls fulfillRandomness, after validating
  // the origin of the call
  function rawFulfillRandomness(bytes32 requestId, uint256 randomness) external {
    require(msg.sender == vrfCoordinator, "Only VRFCoordinator can fulfill");
    fulfillRandomness(requestId, randomness);
  }
}

Settings
{
  "remappings": [],
  "optimizer": {
    "enabled": true,
    "runs": 1000000
  },
  "evmVersion": "istanbul",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_link","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":"NewServiceAgreement","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"keyHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"seed","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"jobID","type":"bytes32"},{"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":"bytes","name":"_proof","type":"bytes"}],"name":"fulfillRandomnessRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[2]","name":"_publicKey","type":"uint256[2]"}],"name":"hashOfKey","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"onTokenTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"uint256[2]","name":"_publicProvingKey","type":"uint256[2]"},{"internalType":"bytes32","name":"_jobID","type":"bytes32"}],"name":"registerProvingKey","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"serviceAgreements","outputs":[{"internalType":"address","name":"vRFOracle","type":"address"},{"internalType":"uint96","name":"fee","type":"uint96"},{"internalType":"bytes32","name":"jobID","type":"bytes32"}],"stateMutability":"view","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"}]

608060405234801561001057600080fd5b5060405161275e38038061275e8339818101604052604081101561003357600080fd5b508051602090910151600080546001600160a01b039384166001600160a01b031991821617909155600180549390921692169190911790556126e48061007a6000396000f3fe608060405234801561001057600080fd5b50600436106100c85760003560e01c8063a4c0ed3611610081578063d83402091161005b578063d834020914610359578063e911439c1461039d578063f3fef3a3146103a5576100c8565b8063a4c0ed361461023e578063b415f4f514610306578063caf70c4a1461030e576100c8565b80635e1c1059116100b25780635e1c10591461017157806375d35070146102195780638aa7927b14610236576100c8565b80626f6ad0146100cd57806321f3650914610112575b600080fd5b610100600480360360208110156100e357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166103de565b60408051918252519081900360200190f35b61012f6004803603602081101561012857600080fd5b50356103f0565b6040805173ffffffffffffffffffffffffffffffffffffffff90941684526bffffffffffffffffffffffff909216602084015282820152519081900360600190f35b6102176004803603602081101561018757600080fd5b8101906020810181356401000000008111156101a257600080fd5b8201836020820111156101b457600080fd5b803590602001918460018302840111640100000000831117156101d657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610448945050505050565b005b61012f6004803603602081101561022f57600080fd5b5035610550565b6101006105a8565b6102176004803603606081101561025457600080fd5b73ffffffffffffffffffffffffffffffffffffffff8235169160208101359181019060608101604082013564010000000081111561029157600080fd5b8201836020820111156102a357600080fd5b803590602001918460018302840111640100000000831117156102c557600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506105ad945050505050565b61010061066c565b6101006004803603604081101561032457600080fd5b604080518082018252918301929181830191839060029083908390808284376000920191909152509194506106719350505050565b610217600480360360a081101561036f57600080fd5b5080359073ffffffffffffffffffffffffffffffffffffffff602082013516906040810190608001356106c7565b610100610957565b610217600480360360408110156103bb57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906020013561095d565b60046020526000908152604090205481565b6002602052600090815260409020805460019091015473ffffffffffffffffffffffffffffffffffffffff8216917401000000000000000000000000000000000000000090046bffffffffffffffffffffffff169083565b6000610452612597565b60008061045e85610abf565b6000848152600360209081526040808320548287015173ffffffffffffffffffffffffffffffffffffffff9091168085526004909352922054959950939750919550935090916104c1916bffffffffffffffffffffffff1663ffffffff610e4616565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600460209081526040808320939093558582526002905290812081815560010155835161050d9084908490610ec3565b604080518481526020810184905281517fa2e7a402243ebda4a69ceeb3dfb682943b7a9b3ac66d6eefa8db65894009611c929181900390910190a1505050505050565b6003602052600090815260409020805460019091015473ffffffffffffffffffffffffffffffffffffffff8216917401000000000000000000000000000000000000000090046bffffffffffffffffffffffff169083565b602081565b60005473ffffffffffffffffffffffffffffffffffffffff16331461063357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4d75737420757365204c494e4b20746f6b656e00000000000000000000000000604482015290519081900360640190fd5b60008082806020019051604081101561064b57600080fd5b508051602090910151909250905061066582828688611080565b5050505050565b60e081565b6000816040516020018082600260200280838360005b8381101561069f578181015183820152602001610687565b505050509050019150506040516020818303038152906040528051906020012090505b919050565b6040805180820182526000916106f6919085906002908390839080828437600092019190915250610671915050565b60008181526003602052604090205490915073ffffffffffffffffffffffffffffffffffffffff16801561078b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f706c656173652072656769737465722061206e6577206b657900000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff851661080d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f5f6f7261636c65206d757374206e6f7420626520307830000000000000000000604482015290519081900360640190fd5b600082815260036020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff87161781556001018390556b033b2e3c9fd0803ce80000008611156108c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180612630603c913960400191505060405180910390fd5b600082815260036020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000006bffffffffffffffffffffffff8b1602179055815184815290810188905281517fae189157e0628c1e62315e9179156e1ea10e90e9c15060002f7021e907dc2cfe929181900390910190a1505050505050565b6101a081565b3360009081526004602052604090205481908111156109dd57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f63616e2774207769746864726177206d6f7265207468616e2062616c616e6365604482015290519081900360640190fd5b336000908152600460205260409020546109fd908363ffffffff61136116565b33600090815260046020818152604080842094909455825484517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8981169482019490945260248101889052945192169363a9059cbb93604480830194928390030190829087803b158015610a8857600080fd5b505af1158015610a9c573d6000803e3d6000fd5b505050506040513d6020811015610ab257600080fd5b5051610aba57fe5b505050565b6000610ac9612597565b825160009081906101c0908114610b4157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f77726f6e672070726f6f66206c656e6774680000000000000000000000000000604482015290519081900360640190fd5b610b496125b7565b5060e086015181870151602088019190610b6283610671565b9750610b6e88836113d8565b6000818152600260209081526040918290208251606081018452815473ffffffffffffffffffffffffffffffffffffffff8116808352740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff169382019390935260019091015492810192909252909850909650610c5057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6e6f20636f72726573706f6e64696e6720726571756573740000000000000000604482015290519081900360640190fd5b6040805160208082018590528183018490528251808303840181526060909201835281519101209088015114610ce757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e672070726553656564206f7220626c6f636b206e756d000000000000604482015290519081900360640190fd5b804080610dfa57600154604080517fe9413d3800000000000000000000000000000000000000000000000000000000815260048101859052905173ffffffffffffffffffffffffffffffffffffffff9092169163e9413d3891602480820192602092909190829003018186803b158015610d6057600080fd5b505afa158015610d74573d6000803e3d6000fd5b505050506040513d6020811015610d8a57600080fd5b5051905080610dfa57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f706c656173652070726f766520626c6f636b6861736800000000000000000000604482015290519081900360640190fd5b6040805160208082018690528183018490528251808303840181526060909201909252805191012060e08b018190526101a08b52610e378b611404565b96505050505050509193509193565b600082820183811015610eba57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b604080516024810185905260448082018590528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f94985ddd00000000000000000000000000000000000000000000000000000000179052600090620324b0805a1015610fa657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f6e6f7420656e6f7567682067617320666f7220636f6e73756d65720000000000604482015290519081900360640190fd5b60008473ffffffffffffffffffffffffffffffffffffffff16836040518082805190602001908083835b6020831061100d57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fd0565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461106f576040519150601f19603f3d011682016040523d82523d6000602084013e611074565b606091505b50505050505050505050565b600084815260036020526040902054829085907401000000000000000000000000000000000000000090046bffffffffffffffffffffffff1682101561112757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f42656c6f7720616772656564207061796d656e74000000000000000000000000604482015290519081900360640190fd5b600086815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549061116488888785611572565b9050600061117289836113d8565b60008181526002602052604090205490915073ffffffffffffffffffffffffffffffffffffffff16156111a157fe5b600081815260026020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff88161790556b033b2e3c9fd0803ce8000000871061120257fe5b600081815260026020908152604080832080546bffffffffffffffffffffffff8c16740100000000000000000000000000000000000000000273ffffffffffffffffffffffffffffffffffffffff91821617825582518085018890524381850152835180820385018152606082018086528151918701919091206001948501558f875260039095529483902090910154928d905260808401869052891660a084015260c083018a905260e083018490525190917f56bd374744a66d531874338def36c906e3a6cf31176eb1e9afd9f1de69725d5191908190036101000190a2600089815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff8a16845290915290205461132290600163ffffffff610e4616565b6000998a52600560209081526040808c2073ffffffffffffffffffffffffffffffffffffffff9099168c52979052959098209490945550505050505050565b6000828211156113d257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b60006101a082511461147757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f77726f6e672070726f6f66206c656e6774680000000000000000000000000000604482015290519081900360640190fd5b61147f6125b7565b6114876125b7565b61148f6125d5565b60006114996125b7565b6114a16125b7565b6000888060200190516101a08110156114b957600080fd5b5060e081015161018082015191985060408901975060808901965094506101008801935061014088019250905061150c8787876000602002015188600160200201518960026020020151898989896115c6565b6003866040516020018083815260200182600260200280838360005b83811015611540578181015183820152602001611528565b50505050905001925050506040516020818303038152906040528051906020012060001c975050505050505050919050565b604080516020808201969096528082019490945273ffffffffffffffffffffffffffffffffffffffff9290921660608401526080808401919091528151808403909101815260a09092019052805191012090565b6115cf896118c7565b61163a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f7075626c6963206b6579206973206e6f74206f6e206375727665000000000000604482015290519081900360640190fd5b611643886118c7565b6116ae57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f67616d6d61206973206e6f74206f6e2063757276650000000000000000000000604482015290519081900360640190fd5b6116b7836118c7565b61172257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e206375727665000000604482015290519081900360640190fd5b61172b826118c7565b61179657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e20637572766500000000604482015290519081900360640190fd5b6117a2878a888761190b565b61180d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6164647228632a706b2b732a6729e289a05f755769746e657373000000000000604482015290519081900360640190fd5b6118156125b7565b61181f8a87611ad7565b90506118296125b7565b611838898b878b868989611b7a565b90506000611849838d8d8a86611ced565b9050808a146118b957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f696e76616c69642070726f6f6600000000000000000000000000000000000000604482015290519081900360640190fd5b505050505050505050505050565b60208101516000907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f9080096119048360005b6020020151611e10565b1492915050565b600073ffffffffffffffffffffffffffffffffffffffff821661198f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f626164207769746e657373000000000000000000000000000000000000000000604482015290519081900360640190fd5b6020840151600090600116156119a657601c6119a9565b601b5b905060007ffffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641418587600060200201510986517ffffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036414191820392506000919089098751604080516000808252602082810180855288905260ff8916838501526060830194909452608082018590529151939450909260019260a08084019391927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081019281900390910190855afa158015611a84573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015173ffffffffffffffffffffffffffffffffffffffff9081169088161495505050505050949350505050565b611adf6125b7565b611b3d600184846040516020018084815260200183600260200280838360005b83811015611b17578181015183820152602001611aff565b505050509050018281526020019350505050604051602081830303815290604052611e68565b90505b611b49816118c7565b610ebd578051604080516020818101939093528151808203909301835281019052611b7390611e68565b9050611b40565b611b826125b7565b825186517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f91900306611c1657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e63740000604482015290519081900360640190fd5b611c21878988611ed0565b611c76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061266c6021913960400191505060405180910390fd5b611c81848685611ed0565b611cd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061268d6022913960400191505060405180910390fd5b611ce1868484612036565b98975050505050505050565b6000600286868685876040516020018087815260200186600260200280838360005b83811015611d27578181015183820152602001611d0f565b5050505090500185600260200280838360005b83811015611d52578181015183820152602001611d3a565b5050505090500184600260200280838360005b83811015611d7d578181015183820152602001611d65565b5050505090500183600260200280838360005b83811015611da8578181015183820152602001611d90565b505050509050018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b815260140196505050505050506040516020818303038152906040528051906020012060001c905095945050505050565b6000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f80848509840990507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f600782089392505050565b611e706125b7565b611e7982612164565b8152611e8e611e898260006118fa565b6121b9565b6020820181905260029006600114156106c2576020810180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f039052919050565b600082611edc57600080fd5b8351602085015160009060011615611ef557601c611ef8565b601b5b905060007ffffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141838709604080516000808252602080830180855282905260ff871683850152606083018890526080830185905292519394509260019260a08084019391927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081019281900390910190855afa158015611f9a573d6000803e3d6000fd5b5050506020604051035190506000866040516020018082600260200280838360005b83811015611fd4578181015183820152602001611fbc565b505050509050019150506040516020818303038152906040528051906020012060001c90508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614955050505050509392505050565b61203e6125b7565b83516020808601518551918601516000938493849361205f939091906121e5565b919450925090507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f8582096001146120f857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f696e765a206d75737420626520696e7665727365206f66207a00000000000000604482015290519081900360640190fd5b60405180604001604052807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f8061212b57fe5b87860981526020017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f8785099052979650505050505050565b805160208201205b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f81106106c25760408051602080820193909352815180820384018152908201909152805191012061216c565b6000610ebd827f3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff0c61237b565b60008080600180827ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f897ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f038808905060007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f8b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f038a089050600061228d83838585612474565b909850905061229e88828e886124cc565b90985090506122af88828c876124cc565b909850905060006122c28d878b856124cc565b90985090506122d388828686612474565b90985090506122e488828e896124cc565b9098509050818114612367577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f818a0998507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f82890997507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f818309965061236b565b8196505b5050505050509450945094915050565b6000806123866125f3565b6020808252818101819052604082015260608101859052608081018490527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f60a08201526123d2612611565b60208160c08460057ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa92508261246a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6269674d6f64457870206661696c757265210000000000000000000000000000604482015290519081900360640190fd5b5195945050505050565b6000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f8487097ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f8487099097909650945050505050565b600080807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f878509905060007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f87877ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f030990507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f8183087ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f86890990999098509650505050505050565b604080516060810182526000808252602082018190529181019190915290565b60405180604001604052806002906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b6040518060200160405280600190602082028036833750919291505056fe796f752063616e277420636861726765206d6f7265207468616e20616c6c20746865204c494e4b20696e2074686520776f726c642c206772656564794669727374206d756c7469706c69636174696f6e20636865636b206661696c65645365636f6e64206d756c7469706c69636174696f6e20636865636b206661696c6564a26469706673582212208efd269ea7bf9a8c5cbb2c356789a9eb5e07d283e5353619b2112b069842f0f564736f6c63430006060033000000000000000000000000eac444eab7aa773207d8bcad51a5a7b2bdfc899a00000000000000000000000084b9b910527ad5c03a9ca831909e21e236ea7b06

Deployed ByteCode Sourcemap

361:12051:2:-:0;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;361:12051:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;9;2:12;1821:89:2;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;1821:89:2;;;;:::i;:::-;;;;;;;;;;;;;;;;1661:70;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;1661:70:2;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6935:615;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;6935:615:2;;;;;;;;27:11:-1;11:28;;8:2;;;52:1;49;42:12;8:2;6935:615:2;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;6935:615:2;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;6935:615:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;6935:615:2;;-1:-1:-1;6935:615:2;;-1:-1:-1;;;;;6935:615:2:i;:::-;;1735:82;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;1735:82:2;;:::i;6346:48::-;;;:::i;4265:237::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;4265:237:2;;;;;;;;;;;;;;;;;;;;27:11:-1;11:28;;8:2;;;52:1;49;42:12;8:2;4265:237:2;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;4265:237:2;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;4265:237:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;4265:237:2;;-1:-1:-1;4265:237:2;;-1:-1:-1;;;;;4265:237:2:i;6468:45::-;;;:::i;11438:136::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;11438:136:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;11438:136:2;;-1:-1:-1;11438:136:2;;-1:-1:-1;;;;11438:136:2:i;2862:743::-;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;2862:743:2;;;;;;;;;;;;;;;;;;:::i;24594:351:0:-;;;:::i;11050:236:2:-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;11050:236:2;;;;;;;;;:::i;1821:89::-;;;;;;;;;;;;;:::o;1661:70::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;6935:615::-;7004:22;7028:24;;:::i;:::-;7054:17;7078:18;7100:30;7123:6;7100:22;:30::i;:::-;7155:12;7170:33;;;:17;:33;;;;;;;;:43;7282:22;;;;7170:43;;;;7246:24;;;:18;:24;;;;;;7003:127;;-1:-1:-1;7003:127:2;;-1:-1:-1;7003:127:2;;-1:-1:-1;7003:127:2;-1:-1:-1;7170:43:2;;7246:59;;;;;:28;:59;:::i;:::-;7219:24;;;;;;;:18;:24;;;;;;;;:86;;;;7386:20;;;:9;:20;;;;;7379:27;;;;;;7458:25;;7412:72;;7396:9;;7446:10;;7412:22;:72::i;:::-;7496:49;;;;;;;;;;;;;;;;;;;;;;;;;6935:615;;;;;;:::o;1735:82::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;6346:48::-;6390:4;6346:48;:::o;4265:237::-;12057:4;;;;12035:10;:27;12027:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4374:15:::1;4391:12:::0;4418:5:::1;4407:37;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;4407:37:2;;::::1;::::0;;::::1;::::0;;;-1:-1:-1;4407:37:2;-1:-1:-1;4450:47:2::1;4407:37:::0;;4483:4;4489:7;4450:17:::1;:47::i;:::-;12092:1;;4265:237:::0;;;:::o;6468:45::-;6509:4;6468:45;:::o;11438:136::-;11508:7;11557:10;11540:28;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;11540:28:2;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;11540:28:2;;;11530:39;;;;;;11523:46;;11438:136;;;;:::o;2862:743::-;3023:28;;;;;;;;3005:15;;3023:28;;;3033:17;;3023:28;;;;3033:17;;3023:28;3033:17;3023:28;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;3023:9:2;;-1:-1:-1;;3023:28:2:i;:::-;3057:20;3080:26;;;:17;:26;;;;;:36;3005:46;;-1:-1:-1;3080:36:2;;3130:26;;3122:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3200:21;;;3192:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3255:26;;;;:17;:26;;;;;:46;;;;;;;;;;-1:-1:-1;3307:32:2;:41;;;3424:9;3416:17;;;3408:96;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3510:26;;;;:17;:26;;;;;;;;;:45;;;;;;;;;;;;3566:34;;;;;;;;;;;;;;;;;;;;;;;;2862:743;;;;;;:::o;24594:351:0:-;24630:315;24594:351;:::o;11050:236:2:-;12338:10;12319:30;;;;:18;:30;;;;;;11140:7;;12319:41;-1:-1:-1;12319:41:2;12311:86;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11209:10:::1;11190:30;::::0;;;:18:::1;:30;::::0;;;;;:43:::1;::::0;11225:7;11190:43:::1;:34;:43;:::i;:::-;11176:10;11157:30;::::0;;;:18:::1;:30;::::0;;;;;;;:76;;;;11246:4;;:34;;;;;11157:30:::1;11246:34:::0;;::::1;::::0;;::::1;::::0;;;;;;;;;;;;:4;::::1;::::0;:13:::1;::::0;:34;;;;;;;;;;;;;:4;:34;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;11246:34:2;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;11246:34:2;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;11246:34:2;11239:42:::1;;;;11050:236:::0;;;:::o;8947:1879::-;9027:22;9051:24;;:::i;:::-;9463:13;;9083:17;;;;9306:19;;9463:32;;9455:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9524:27;;:::i;:::-;-1:-1:-1;9739:14:2;9727:27;;9721:34;9780:28;;;9774:35;9685:17;9673:30;;;9721:34;9837:20;9673:30;9837:9;:20::i;:::-;9820:37;;9875:38;9889:14;9905:7;9875:13;:38::i;:::-;9930:20;;;;:9;:20;;;;;;;;;9919:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9930:20:2;;-1:-1:-1;9956:76:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10084:41;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;10084:41:2;;;;;;10074:52;;;;;10046:24;;;;:80;10038:119;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10184:19;;10213:23;10209:159;;10258:14;;:37;;;;;;;;;;;;;;:14;;;;;:27;;:37;;;;;;;;;;;;;;;:14;:37;;;2:2:-1;;;;27:1;24;17:12;2:2;10258:37:2;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;10258:37:2;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;10258:37:2;;-1:-1:-1;10311:23:2;10303:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10488:36;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;10488:36:2;;;;;;;10478:47;;;;;10677:14;10665:27;;10658:47;;;10727:12;10712:28;;10764:35;10669:6;10764:27;:35::i;:::-;10751:48;;8947:1879;;;;;;;;;;;:::o;822:162:6:-;880:7;907:5;;;926:6;;;;918:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;978:1;-1:-1:-1;822:162:6;;;;;:::o;7554:1389:2:-;7866:85;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;7866:85:2;;;;;;;;25:18:-1;;61:17;;7866:85:2;182:15:-1;7896:31:2;179:29:-1;160:49;;7823:17:2;;8232:6;;8252:9;:14;;8244:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8723:12;8740:16;:21;;8762:4;8740:27;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;139:12;;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;8740:27:2;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;19;14:27;;;;67:4;61:11;56:16;;134:4;130:9;123:4;105:16;101:27;97:43;94:1;90:51;84:4;77:65;157:16;154:1;147:27;211:16;208:1;201:4;198:1;194:12;179:49;5:228;;14:27;32:4;27:9;;5:228;-1:-1;;;;;;;;;;7554:1389:2:o;5250:966::-;11869:27;;;;:17;:27;;;;;:31;5405:8;;11869:27;;:31;;;;;11857:43;;;11849:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5433:13:::1;5449:16:::0;;;:6:::1;:16;::::0;;;;;;;:25:::1;::::0;::::1;::::0;;;;;;;;;5498:57:::1;5456:8:::0;5525:13;5466:7;5449:25;5498:16:::1;:57::i;:::-;5480:75;;5561:17;5581:32;5595:8;5605:7;5581:13;:32::i;:::-;5752:1;5703:20:::0;;;:9:::1;:20;::::0;;;;:37;5561:52;;-1:-1:-1;5703:51:2::1;:37;:51:::0;5696:59:::1;;;;5761:20;::::0;;;:9:::1;:20;::::0;;;;:47;;;::::1;;::::0;::::1;;::::0;;5832:4:::1;5821:15:::0;::::1;5814:23;;;;5872:20;::::0;;;:9:::1;:20;::::0;;;;;;;:53;;::::1;::::0;::::1;::::0;::::1;::::0;;;::::1;;::::0;;5980:46;;;;::::1;::::0;;;6013:12:::1;5980:46:::0;;;;;;26:21:-1;;;22:32;;6:49;;5980:46:2;;;;;;5970:57;;;;::::1;::::0;;;;-1:-1:-1;5931:36:2;;::::1;:96:::0;6075:27;;;:17:::1;:27:::0;;;;;;;:33;;::::1;::::0;6038:107;;;;;;;;;;;::::1;::::0;;;;;;;;;;;;;;;;;6075:33;;6038:107:::1;::::0;;;;;5872:53:::1;6038:107:::0;;::::1;6179:16;::::0;;;:6:::1;:16;::::0;;;;;;;:25:::1;::::0;::::1;::::0;;;;;;;;:32:::1;::::0;6209:1:::1;6179:32;:29;:32;:::i;:::-;6151:16;::::0;;;:6:::1;:16;::::0;;;;;;;:25:::1;::::0;;::::1;::::0;;;;;;;;;:60;;;;-1:-1:-1;;;;;;;5250:966:2:o;1236:165:6:-;1294:7;1322:1;1317;:6;;1309:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1376:5:6;;;1236:165::o;1376:171:3:-;1500:41;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;1500:41:3;;;;;;1490:52;;;;;;1376:171::o;25549:997:0:-;25629:14;24630:315;25661:5;:12;:28;25653:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25721:20;;:::i;:::-;25794:23;;:::i;:::-;25903:24;;:::i;:::-;25935:16;25959:31;;:::i;:::-;25998:30;;:::i;:::-;26036:12;26143:5;26123:122;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;26123:122:0;;;;;;;;;;-1:-1:-1;26123:122:0;;;;-1:-1:-1;26123:122:0;;;;-1:-1:-1;26123:122:0;-1:-1:-1;26123:122:0;;;;-1:-1:-1;26123:122:0;;;;-1:-1:-1;26123:122:0;-1:-1:-1;26253:201:0;26123:122;;;26311:1;26304:9;;;;26328:6;26335:1;26328:9;;;;26352:6;26359:1;26352:9;;;;26379:8;26397:13;26420:12;26442:4;26253:14;:201::i;:::-;24519:1;26531:5;26489:48;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;26489:48:0;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;26489:48:0;;;26479:59;;;;;;26471:68;;26462:77;;25549:997;;;;;;;;;;:::o;765:231:3:-;938:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;938:51:3;;;;;;928:62;;;;;;765:231::o;22819:1521:0:-;23070:13;23080:2;23070:9;:13::i;:::-;23062:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23130:16;23140:5;23130:9;:16::i;:::-;23122:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23188:24;23198:13;23188:9;:24::i;:::-;23180:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23262:23;23272:12;23262:9;:23::i;:::-;23254:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23720:56;23757:1;23760:2;23764:1;23767:8;23720:36;:56::i;:::-;23703:119;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23917:22;;:::i;:::-;23942:21;23954:2;23958:4;23942:11;:21::i;:::-;23917:46;;24055:19;;:::i;:::-;24077:80;24104:1;24107:5;24114:13;24129:1;24132:4;24138:12;24152:4;24077:17;:80::i;:::-;24055:102;;24216:16;24235:51;24257:4;24263:2;24267:5;24274:8;24284:1;24235:21;:51::i;:::-;24216:70;;24307:8;24302:1;:13;24294:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22819:1521;;;;;;;;;;;;:::o;9658:135::-;9771:4;;;;9721;;7588:66;;9771:4;9758:30;9740:14;9749:1;9751;9749:4;;;;;9740:8;:14::i;:::-;:48;;9658:135;-1:-1:-1;;9658:135:0:o;18872:1044::-;19012:4;19100:23;;;19092:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19158:4;;;;19147:7;;19158:8;;:13;19157:25;;19180:2;19157:25;;;19175:2;19157:25;19147:35;-1:-1:-1;19219:18:0;7354:66;19275:1;19269;19271;19269:4;;;;19262:28;19354:4;;7354:66;19248:42;;;;-1:-1:-1;19240:51:0;;7354:66;19351:1;19344:28;19850:4;;19817:56;;;19336:37;19817:56;;;19850:4;19817:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19336:37;;-1:-1:-1;19336:37:0;;19817:56;;;;;;;19850:4;;-1:-1:-1;19817:56:0;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;19817:56:0;;;;;19888:21;;;;;;;;;-1:-1:-1;;;;;;18872:1044:0;;;;;;:::o;11832:369::-;11917:20;;:::i;:::-;11952:137;11058:1;12078:2;12082:5;11979:109;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;11979:109:0;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;11979:109:0;;;11952:26;:137::i;:::-;11947:142;;12097:98;12105:13;12115:2;12105:9;:13::i;:::-;12097:98;;12179:5;;12162:23;;;12179:5;12162:23;;;;;;;;;26:21:-1;;;22:32;;;6:49;;12162:23:0;;;;12135:51;;:26;:51::i;:::-;12130:56;;12097:98;;20399:572;20606:17;;:::i;:::-;20658:13;;20642;;7588:66;;20642:29;;20641:44;20633:106;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20755:30;20767:2;20771:1;20774:10;20755:11;:30::i;:::-;20747:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20839:30;20851:2;20855:1;20858:10;20839:11;:30::i;:::-;20831:77;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20923:41;20935:10;20947;20959:4;20923:11;:41::i;:::-;20916:48;20399:572;-1:-1:-1;;;;;;;;20399:572:0:o;21878:358::-;22055:9;21159:1;22198:4;22204:2;22208:5;22215:1;22218:8;22108:119;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;22108:119:0;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;22108:119:0;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;22108:119:0;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;22108:119:0;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;22108:119:0;;;22098:130;;;;;;22081:148;;22074:155;;21878:358;;;;;;;:::o;9363:259::-;9415:7;;7588:66;;9548:1;9545;9538:24;9535:1;9528:47;9511:64;-1:-1:-1;7588:66:0;9603:1;9595:6;9588:29;9581:36;9363:259;-1:-1:-1;;;9363:259:0:o;10656:244::-;10735:19;;:::i;:::-;10771:12;10781:1;10771:9;:12::i;:::-;10764:19;;10798:26;10809:14;10764:1;10766;10818:4;;10809:14;10798:10;:26::i;:::-;10791:4;;;:33;;;10843:1;;10836:8;10848:1;10836:13;10832:62;;;10881:4;;;;;7588:66;10868:17;10861:24;;10881:1;10656:244;-1:-1:-1;10656:244:0:o;12693:978::-;12815:13;12846:11;12838:20;;12:1:-1;9;2:12;12838:20:0;12915:15;;;12976;;;12903:9;;12976:19;;:24;:34;;13008:2;12976:34;;;13003:2;12976:34;12966:44;-1:-1:-1;13359:20:0;7354:66;13405:1;13397:6;13390:30;13444:50;;;13382:39;13444:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13382:39;;-1:-1:-1;13382:39:0;13444:50;;;;;;;;;-1:-1:-1;13444:50:0;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;13444:50:0;;;;;;;;13427:67;;13560:16;13622:7;13605:25;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;13605:25:0;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;13605:25:0;;;13595:36;;;;;;13587:45;;13560:73;;13657:8;13647:18;;:6;:18;;;13639:27;;;;;;;12693:978;;;;;:::o;18234:519::-;18345:17;;:::i;:::-;18443:5;;;18450;;;;18457;;18464;;;;18370:9;;;;;;18427:43;;18450:5;;18457;18427:15;:43::i;:::-;18415:55;;-1:-1:-1;18415:55:0;-1:-1:-1;18415:55:0;-1:-1:-1;7588:66:0;18494:4;18491:1;18484:27;18515:1;18484:32;18476:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18683:65;;;;;;;;7588:66;18691:27;;;;;18701:4;18698:1;18691:27;18683:65;;;;7588:66;18730:4;18727:1;18720:27;18683:65;;;18234:519;-1:-1:-1;;;;;;;18234:519:0:o;9848:394::-;9937:12;;;;;;10153:85;7588:66;10160:2;:16;10153:85;;10209:20;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;10209:20:0;;;;;;10199:31;;;;;10153:85;;9198:105;9252:7;9274:24;9284:1;9112:21;9274:9;:24::i;15969:1996::-;16068:10;;;16810:1;;16068:10;7588:66;16929:2;7588:66;16916:15;16912:2;16905:39;16892:52;-1:-1:-1;16952:10:0;7588:66;16989:2;7588:66;16976:15;16972:2;16965:39;16952:52;;17013:10;17127:29;17141:2;17145;17149;17153;17127:13;:29::i;:::-;17116:40;;-1:-1:-1;17116:40:0;-1:-1:-1;17198:29:0;17116:40;;17220:2;17224;17198:13;:29::i;:::-;17187:40;;-1:-1:-1;17187:40:0;-1:-1:-1;17272:29:0;17187:40;;17294:2;17298;17272:13;:29::i;:::-;17261:40;;-1:-1:-1;17261:40:0;-1:-1:-1;17339:10:0;17455:29;17469:2;17473;17261:40;;17455:13;:29::i;:::-;17444:40;;-1:-1:-1;17444:40:0;-1:-1:-1;17512:29:0;17444:40;;17534:2;17538;17512:13;:29::i;:::-;17501:40;;-1:-1:-1;17501:40:0;-1:-1:-1;17588:29:0;17501:40;;17610:2;17614;17588:13;:29::i;:::-;17577:40;;-1:-1:-1;17577:40:0;-1:-1:-1;17661:8:0;;;17657:302;;7588:66;17759:2;17755;17748:26;17743:31;-1:-1:-1;7588:66:0;17800:2;17796;17789:26;17784:31;-1:-1:-1;7588:66:0;17841:2;17837;17830:26;17825:31;;17657:302;;;17948:2;17943:7;;17657:302;15969:1996;;;;;;;;;;;;;;:::o;7827:1072::-;7905:22;7937:18;7963:41;;:::i;:::-;7703:4;8012:46;;;8085:26;;;:46;;;8162:26;;;:46;8238:26;;;:33;;;8279:26;;;:37;;;7588:66;8324:26;;;:39;8371:24;;:::i;:::-;8741:4;8725:6;8650:4;8617:23;8553:4;8497:6;8477:325;8463:339;-1:-1:-1;8821:15:0;8817:52;;8839:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8817:52;8883:9;;;-1:-1:-1;;;;;7827:1072:0:o;14165:203::-;14262:10;;7588:66;14317:2;14313;14306:26;7588:66;14345:2;14341;14334:26;14294:67;;;;-1:-1:-1;14165:203:0;-1:-1:-1;;;;;14165:203:0:o;13761:318::-;13858:10;;;7588:66;13916:2;13912;13905:26;13890:41;-1:-1:-1;13939:12:0;7588:66;13978:2;13974;7588:66;13961:15;13954:39;13939:54;-1:-1:-1;7588:66:0;14026:4;14020;14013:30;7588:66;14056:2;14052;14045:26;14001:71;;;;-1:-1:-1;13761:318:0;-1:-1:-1;;;;;;;13761:318:0:o;361:12051:2:-;;;;;;;;;-1:-1:-1;361:12051:2;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;29:2:-1;21:6;17:15;125:4;109:14;101:6;88:42;-1:-1;361:12051:2;;;-1:-1:-1;;361:12051:2:o;:::-;;;;;;;;;;;29:2:-1;21:6;17:15;125:4;109:14;101:6;88:42;-1:-1;361:12051:2;;;-1:-1:-1;;361:12051:2:o;:::-;;;;;;;;;;;29:2:-1;21:6;17:15;125:4;109:14;101:6;88:42;-1:-1;361:12051:2;;;-1:-1:-1;;361:12051:2:o;:::-;;;;;;;;;;;29:2:-1;21:6;17:15;125:4;109:14;101:6;88:42;-1:-1;361:12051:2;;;-1:-1:-1;;361:12051:2:o

Swarm Source

ipfs://8efd269ea7bf9a8c5cbb2c356789a9eb5e07d283e5353619b2112b069842f0f5
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading