From 3257b8fe00c59049cac7452f60c6886e346d2e69 Mon Sep 17 00:00:00 2001 From: Ilja Pavlovs <5300706+iljapavlovs@users.noreply.github.com> Date: Mon, 26 Aug 2024 15:42:52 +0300 Subject: [PATCH] =?UTF-8?q?DEVSVCS-138:=20adding=20default=20test=20config?= =?UTF-8?q?=20for=20VRF=20CTF=20tests;=20adding=20abi=E2=80=A6=20(#14184)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * DEVSVCS-138: adding default test config for VRF CTF tests; adding ability to deploy Test Coordinator, Arbitrum Coordinator for V2Plus, also Arbitrum Wrapper * DEVSVCS-138: fixing lint solidity issues --- contracts/scripts/native_solc_compile_all_vrf | 1 + .../testhelpers/VRFCoordinatorTestV2_5.sol | 773 ++++ .../src/v0.8/vrf/dev/testhelpers/VRFOld.sol | 588 +++ .../vrf_coordinator_test_v2_5.go | 3994 +++++++++++++++++ ...rapper-dependency-versions-do-not-edit.txt | 1 + core/gethwrappers/go_generate.go | 1 + integration-tests/actions/actions.go | 5 + .../actions/vrf/vrfv2/setup_steps.go | 40 +- .../actions/vrf/vrfv2plus/contract_steps.go | 27 + .../actions/vrf/vrfv2plus/setup_steps.go | 5 +- .../contracts/ethereum_vrfv2plus_contracts.go | 105 +- integration-tests/load/vrfv2/vrfv2_test.go | 4 +- integration-tests/testconfig/vrfv2/vrfv2.toml | 1 + .../testconfig/vrfv2plus/config.go | 5 + .../testconfig/vrfv2plus/vrfv2plus.toml | 192 +- 15 files changed, 5694 insertions(+), 48 deletions(-) create mode 100644 contracts/src/v0.8/vrf/dev/testhelpers/VRFCoordinatorTestV2_5.sol create mode 100644 contracts/src/v0.8/vrf/dev/testhelpers/VRFOld.sol create mode 100644 core/gethwrappers/generated/vrf_coordinator_test_v2_5/vrf_coordinator_test_v2_5.go diff --git a/contracts/scripts/native_solc_compile_all_vrf b/contracts/scripts/native_solc_compile_all_vrf index 4bfd4ecac72..88e7b3e1471 100755 --- a/contracts/scripts/native_solc_compile_all_vrf +++ b/contracts/scripts/native_solc_compile_all_vrf @@ -114,6 +114,7 @@ compileContract vrf/dev/testhelpers/VRFV2PlusWrapperConsumerExample.sol compileContract vrf/dev/testhelpers/VRFV2PlusRevertingExample.sol compileContract vrf/dev/testhelpers/VRFConsumerV2PlusUpgradeableExample.sol compileContract vrf/dev/testhelpers/VRFV2PlusMaliciousMigrator.sol +compileContractAltOpts vrf/dev/testhelpers/VRFCoordinatorTestV2_5.sol 500 compileContract vrf/dev/libraries/VRFV2PlusClient.sol compileContract vrf/dev/testhelpers/VRFCoordinatorV2Plus_V2Example.sol compileContract vrf/dev/TrustedBlockhashStore.sol diff --git a/contracts/src/v0.8/vrf/dev/testhelpers/VRFCoordinatorTestV2_5.sol b/contracts/src/v0.8/vrf/dev/testhelpers/VRFCoordinatorTestV2_5.sol new file mode 100644 index 00000000000..2e9c4a2da75 --- /dev/null +++ b/contracts/src/v0.8/vrf/dev/testhelpers/VRFCoordinatorTestV2_5.sol @@ -0,0 +1,773 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {BlockhashStoreInterface} from "../../interfaces/BlockhashStoreInterface.sol"; +import {VRFOld} from "./VRFOld.sol"; +import {VRFTypes} from "../../VRFTypes.sol"; +import {VRFConsumerBaseV2Plus, IVRFMigratableConsumerV2Plus} from "../VRFConsumerBaseV2Plus.sol"; +import {ChainSpecificUtil} from "../../../ChainSpecificUtil.sol"; +import {SubscriptionAPI} from "../SubscriptionAPI.sol"; +import {VRFV2PlusClient} from "../libraries/VRFV2PlusClient.sol"; +import {IVRFCoordinatorV2PlusMigration} from "../interfaces/IVRFCoordinatorV2PlusMigration.sol"; +// solhint-disable-next-line no-unused-import +import {IVRFCoordinatorV2Plus, IVRFSubscriptionV2Plus} from "../interfaces/IVRFCoordinatorV2Plus.sol"; + +// solhint-disable-next-line contract-name-camelcase +contract VRFCoordinatorTestV2_5 is VRFOld, SubscriptionAPI, IVRFCoordinatorV2Plus { + /// @dev should always be available + // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i + BlockhashStoreInterface public immutable BLOCKHASH_STORE; + + // Set this maximum to 200 to give us a 56 block window to fulfill + // the request before requiring the block hash feeder. + uint16 public constant MAX_REQUEST_CONFIRMATIONS = 200; + uint32 public constant MAX_NUM_WORDS = 500; + // 5k is plenty for an EXTCODESIZE call (2600) + warm CALL (100) + // and some arithmetic operations. + uint256 private constant GAS_FOR_CALL_EXACT_CHECK = 5_000; + // upper bound limit for premium percentages to make sure fee calculations don't overflow + uint8 private constant PREMIUM_PERCENTAGE_MAX = 155; + error InvalidRequestConfirmations(uint16 have, uint16 min, uint16 max); + error GasLimitTooBig(uint32 have, uint32 want); + error NumWordsTooBig(uint32 have, uint32 want); + error MsgDataTooBig(uint256 have, uint32 max); + error ProvingKeyAlreadyRegistered(bytes32 keyHash); + error NoSuchProvingKey(bytes32 keyHash); + error InvalidLinkWeiPrice(int256 linkWei); + error LinkDiscountTooHigh(uint32 flatFeeLinkDiscountPPM, uint32 flatFeeNativePPM); + error InvalidPremiumPercentage(uint8 premiumPercentage, uint8 max); + error NoCorrespondingRequest(); + error IncorrectCommitment(); + error BlockhashNotInStore(uint256 blockNum); + error PaymentTooLarge(); + error InvalidExtraArgsTag(); + error GasPriceExceeded(uint256 gasPrice, uint256 maxGas); + + struct ProvingKey { + bool exists; // proving key exists + uint64 maxGas; // gas lane max gas price for fulfilling requests + } + + mapping(bytes32 => ProvingKey) /* keyHash */ /* provingKey */ public s_provingKeys; + bytes32[] public s_provingKeyHashes; + mapping(uint256 => bytes32) /* requestID */ /* commitment */ public s_requestCommitments; + event ProvingKeyRegistered(bytes32 keyHash, uint64 maxGas); + event ProvingKeyDeregistered(bytes32 keyHash, uint64 maxGas); + + event RandomWordsRequested( + bytes32 indexed keyHash, + uint256 requestId, + uint256 preSeed, + uint256 indexed subId, + uint16 minimumRequestConfirmations, + uint32 callbackGasLimit, + uint32 numWords, + bytes extraArgs, + address indexed sender + ); + + event RandomWordsFulfilled( + uint256 indexed requestId, + uint256 outputSeed, + uint256 indexed subId, + uint96 payment, + bool nativePayment, + bool success, + bool onlyPremium + ); + + int256 public s_fallbackWeiPerUnitLink; + + event ConfigSet( + uint16 minimumRequestConfirmations, + uint32 maxGasLimit, + uint32 stalenessSeconds, + uint32 gasAfterPaymentCalculation, + int256 fallbackWeiPerUnitLink, + uint32 fulfillmentFlatFeeNativePPM, + uint32 fulfillmentFlatFeeLinkDiscountPPM, + uint8 nativePremiumPercentage, + uint8 linkPremiumPercentage + ); + + event FallbackWeiPerUnitLinkUsed(uint256 requestId, int256 fallbackWeiPerUnitLink); + + constructor(address blockhashStore) SubscriptionAPI() { + BLOCKHASH_STORE = BlockhashStoreInterface(blockhashStore); + } + + /** + * @notice Registers a proving key to. + * @param publicProvingKey key that oracle can use to submit vrf fulfillments + */ + function registerProvingKey(uint256[2] calldata publicProvingKey, uint64 maxGas) external onlyOwner { + bytes32 kh = hashOfKey(publicProvingKey); + if (s_provingKeys[kh].exists) { + revert ProvingKeyAlreadyRegistered(kh); + } + s_provingKeys[kh] = ProvingKey({exists: true, maxGas: maxGas}); + s_provingKeyHashes.push(kh); + emit ProvingKeyRegistered(kh, maxGas); + } + + /** + * @notice Deregisters a proving key. + * @param publicProvingKey key that oracle can use to submit vrf fulfillments + */ + function deregisterProvingKey(uint256[2] calldata publicProvingKey) external onlyOwner { + bytes32 kh = hashOfKey(publicProvingKey); + ProvingKey memory key = s_provingKeys[kh]; + if (!key.exists) { + revert NoSuchProvingKey(kh); + } + delete s_provingKeys[kh]; + uint256 s_provingKeyHashesLength = s_provingKeyHashes.length; + for (uint256 i = 0; i < s_provingKeyHashesLength; ++i) { + if (s_provingKeyHashes[i] == kh) { + // Copy last element and overwrite kh to be deleted with it + s_provingKeyHashes[i] = s_provingKeyHashes[s_provingKeyHashesLength - 1]; + s_provingKeyHashes.pop(); + break; + } + } + emit ProvingKeyDeregistered(kh, key.maxGas); + } + + /** + * @notice Returns the proving key hash key associated with this public key + * @param publicKey the key to return the hash of + */ + function hashOfKey(uint256[2] memory publicKey) public pure returns (bytes32) { + return keccak256(abi.encode(publicKey)); + } + + /** + * @notice Sets the configuration of the vrfv2 coordinator + * @param minimumRequestConfirmations global min for request confirmations + * @param maxGasLimit global max for request gas limit + * @param stalenessSeconds if the native/link feed is more stale then this, use the fallback price + * @param gasAfterPaymentCalculation gas used in doing accounting after completing the gas measurement + * @param fallbackWeiPerUnitLink fallback native/link price in the case of a stale feed + * @param fulfillmentFlatFeeNativePPM flat fee in native for native payment + * @param fulfillmentFlatFeeLinkDiscountPPM flat fee discount for link payment in native + * @param nativePremiumPercentage native premium percentage + * @param linkPremiumPercentage link premium percentage + */ + function setConfig( + uint16 minimumRequestConfirmations, + uint32 maxGasLimit, + uint32 stalenessSeconds, + uint32 gasAfterPaymentCalculation, + int256 fallbackWeiPerUnitLink, + uint32 fulfillmentFlatFeeNativePPM, + uint32 fulfillmentFlatFeeLinkDiscountPPM, + uint8 nativePremiumPercentage, + uint8 linkPremiumPercentage + ) external onlyOwner { + if (minimumRequestConfirmations > MAX_REQUEST_CONFIRMATIONS) { + revert InvalidRequestConfirmations( + minimumRequestConfirmations, + minimumRequestConfirmations, + MAX_REQUEST_CONFIRMATIONS + ); + } + if (fallbackWeiPerUnitLink <= 0) { + revert InvalidLinkWeiPrice(fallbackWeiPerUnitLink); + } + if (fulfillmentFlatFeeLinkDiscountPPM > fulfillmentFlatFeeNativePPM) { + revert LinkDiscountTooHigh(fulfillmentFlatFeeLinkDiscountPPM, fulfillmentFlatFeeNativePPM); + } + if (nativePremiumPercentage > PREMIUM_PERCENTAGE_MAX) { + revert InvalidPremiumPercentage(nativePremiumPercentage, PREMIUM_PERCENTAGE_MAX); + } + if (linkPremiumPercentage > PREMIUM_PERCENTAGE_MAX) { + revert InvalidPremiumPercentage(linkPremiumPercentage, PREMIUM_PERCENTAGE_MAX); + } + s_config = Config({ + minimumRequestConfirmations: minimumRequestConfirmations, + maxGasLimit: maxGasLimit, + stalenessSeconds: stalenessSeconds, + gasAfterPaymentCalculation: gasAfterPaymentCalculation, + reentrancyLock: false, + fulfillmentFlatFeeNativePPM: fulfillmentFlatFeeNativePPM, + fulfillmentFlatFeeLinkDiscountPPM: fulfillmentFlatFeeLinkDiscountPPM, + nativePremiumPercentage: nativePremiumPercentage, + linkPremiumPercentage: linkPremiumPercentage + }); + s_fallbackWeiPerUnitLink = fallbackWeiPerUnitLink; + emit ConfigSet( + minimumRequestConfirmations, + maxGasLimit, + stalenessSeconds, + gasAfterPaymentCalculation, + fallbackWeiPerUnitLink, + fulfillmentFlatFeeNativePPM, + fulfillmentFlatFeeLinkDiscountPPM, + nativePremiumPercentage, + linkPremiumPercentage + ); + } + + /// @dev Convert the extra args bytes into a struct + /// @param extraArgs The extra args bytes + /// @return The extra args struct + function _fromBytes(bytes calldata extraArgs) internal pure returns (VRFV2PlusClient.ExtraArgsV1 memory) { + if (extraArgs.length == 0) { + return VRFV2PlusClient.ExtraArgsV1({nativePayment: false}); + } + if (bytes4(extraArgs) != VRFV2PlusClient.EXTRA_ARGS_V1_TAG) revert InvalidExtraArgsTag(); + return abi.decode(extraArgs[4:], (VRFV2PlusClient.ExtraArgsV1)); + } + + /** + * @notice Request a set of random words. + * @param req - a struct containing following fiels for randomness request: + * keyHash - Corresponds to a particular oracle job which uses + * that key for generating the VRF proof. Different keyHash's have different gas price + * ceilings, so you can select a specific one to bound your maximum per request cost. + * subId - The ID of the VRF subscription. Must be funded + * with the minimum subscription balance required for the selected keyHash. + * requestConfirmations - How many blocks you'd like the + * oracle to wait before responding to the request. See SECURITY CONSIDERATIONS + * for why you may want to request more. The acceptable range is + * [minimumRequestBlockConfirmations, 200]. + * callbackGasLimit - How much gas you'd like to receive in your + * fulfillRandomWords callback. Note that gasleft() inside fulfillRandomWords + * may be slightly less than this amount because of gas used calling the function + * (argument decoding etc.), so you may need to request slightly more than you expect + * to have inside fulfillRandomWords. The acceptable range is + * [0, maxGasLimit] + * numWords - The number of uint256 random values you'd like to receive + * in your fulfillRandomWords callback. Note these numbers are expanded in a + * secure way by the VRFCoordinator from a single random value supplied by the oracle. + * extraArgs - Encoded extra arguments that has a boolean flag for whether payment + * should be made in native or LINK. Payment in LINK is only available if the LINK token is available to this contract. + * @return requestId - A unique identifier of the request. Can be used to match + * a request to a response in fulfillRandomWords. + */ + function requestRandomWords( + VRFV2PlusClient.RandomWordsRequest calldata req + ) external override nonReentrant returns (uint256 requestId) { + // Input validation using the subscription storage. + uint256 subId = req.subId; + if (s_subscriptionConfigs[subId].owner == address(0)) { + revert InvalidSubscription(); + } + // Its important to ensure that the consumer is in fact who they say they + // are, otherwise they could use someone else's subscription balance. + mapping(uint256 => ConsumerConfig) storage consumerConfigs = s_consumers[msg.sender]; + ConsumerConfig memory consumerConfig = consumerConfigs[subId]; + if (!consumerConfig.active) { + revert InvalidConsumer(subId, msg.sender); + } + // Input validation using the config storage word. + if ( + req.requestConfirmations < s_config.minimumRequestConfirmations || + req.requestConfirmations > MAX_REQUEST_CONFIRMATIONS + ) { + revert InvalidRequestConfirmations( + req.requestConfirmations, + s_config.minimumRequestConfirmations, + MAX_REQUEST_CONFIRMATIONS + ); + } + // No lower bound on the requested gas limit. A user could request 0 + // and they would simply be billed for the proof verification and wouldn't be + // able to do anything with the random value. + if (req.callbackGasLimit > s_config.maxGasLimit) { + revert GasLimitTooBig(req.callbackGasLimit, s_config.maxGasLimit); + } + if (req.numWords > MAX_NUM_WORDS) { + revert NumWordsTooBig(req.numWords, MAX_NUM_WORDS); + } + + // Note we do not check whether the keyHash is valid to save gas. + // The consequence for users is that they can send requests + // for invalid keyHashes which will simply not be fulfilled. + ++consumerConfig.nonce; + ++consumerConfig.pendingReqCount; + uint256 preSeed; + (requestId, preSeed) = _computeRequestId(req.keyHash, msg.sender, subId, consumerConfig.nonce); + + bytes memory extraArgsBytes = VRFV2PlusClient._argsToBytes(_fromBytes(req.extraArgs)); + s_requestCommitments[requestId] = keccak256( + abi.encode( + requestId, + ChainSpecificUtil._getBlockNumber(), + subId, + req.callbackGasLimit, + req.numWords, + msg.sender, + extraArgsBytes + ) + ); + emit RandomWordsRequested( + req.keyHash, + requestId, + preSeed, + subId, + req.requestConfirmations, + req.callbackGasLimit, + req.numWords, + extraArgsBytes, + msg.sender + ); + consumerConfigs[subId] = consumerConfig; + + return requestId; + } + + function _computeRequestId( + bytes32 keyHash, + address sender, + uint256 subId, + uint64 nonce + ) internal pure returns (uint256, uint256) { + uint256 preSeed = uint256(keccak256(abi.encode(keyHash, sender, subId, nonce))); + return (uint256(keccak256(abi.encode(keyHash, preSeed))), preSeed); + } + + /** + * @dev calls target address with exactly gasAmount gas and data as calldata + * or reverts if at least gasAmount gas is not available. + */ + function _callWithExactGas(uint256 gasAmount, address target, bytes memory data) private returns (bool success) { + assembly { + let g := gas() + // Compute g -= GAS_FOR_CALL_EXACT_CHECK and check for underflow + // The gas actually passed to the callee is min(gasAmount, 63//64*gas available). + // We want to ensure that we revert if gasAmount > 63//64*gas available + // as we do not want to provide them with less, however that check itself costs + // gas. GAS_FOR_CALL_EXACT_CHECK ensures we have at least enough gas to be able + // to revert if gasAmount > 63//64*gas available. + if lt(g, GAS_FOR_CALL_EXACT_CHECK) { + revert(0, 0) + } + g := sub(g, GAS_FOR_CALL_EXACT_CHECK) + // if g - g//64 <= gasAmount, revert + // (we subtract g//64 because of EIP-150) + if iszero(gt(sub(g, div(g, 64)), gasAmount)) { + revert(0, 0) + } + // solidity calls check that a contract actually exists at the destination, so we do the same + if iszero(extcodesize(target)) { + revert(0, 0) + } + // call and return whether we succeeded. ignore return data + // call(gas,addr,value,argsOffset,argsLength,retOffset,retLength) + success := call(gasAmount, target, 0, add(data, 0x20), mload(data), 0, 0) + } + return success; + } + + struct Output { + ProvingKey provingKey; + uint256 requestId; + uint256 randomness; + } + + function _getRandomnessFromProof( + Proof memory proof, + VRFTypes.RequestCommitmentV2Plus memory rc + ) internal view returns (Output memory) { + bytes32 keyHash = hashOfKey(proof.pk); + ProvingKey memory key = s_provingKeys[keyHash]; + // Only registered proving keys are permitted. + if (!key.exists) { + revert NoSuchProvingKey(keyHash); + } + uint256 requestId = uint256(keccak256(abi.encode(keyHash, proof.seed))); + bytes32 commitment = s_requestCommitments[requestId]; + if (commitment == 0) { + revert NoCorrespondingRequest(); + } + if ( + commitment != + keccak256(abi.encode(requestId, rc.blockNum, rc.subId, rc.callbackGasLimit, rc.numWords, rc.sender, rc.extraArgs)) + ) { + revert IncorrectCommitment(); + } + + bytes32 blockHash = ChainSpecificUtil._getBlockhash(rc.blockNum); + if (blockHash == bytes32(0)) { + blockHash = BLOCKHASH_STORE.getBlockhash(rc.blockNum); + if (blockHash == bytes32(0)) { + revert BlockhashNotInStore(rc.blockNum); + } + } + + // The seed actually used by the VRF machinery, mixing in the blockhash + uint256 actualSeed = uint256(keccak256(abi.encodePacked(proof.seed, blockHash))); + uint256 randomness = VRFOld._randomValueFromVRFProof(proof, actualSeed); // Reverts on failure + return Output(key, requestId, randomness); + } + + function _getValidatedGasPrice(bool onlyPremium, uint64 gasLaneMaxGas) internal view returns (uint256 gasPrice) { + if (tx.gasprice > gasLaneMaxGas) { + if (onlyPremium) { + // if only the premium amount needs to be billed, then the premium is capped by the gas lane max + return uint256(gasLaneMaxGas); + } else { + // Ensure gas price does not exceed the gas lane max gas price + revert GasPriceExceeded(tx.gasprice, gasLaneMaxGas); + } + } + return tx.gasprice; + } + + function _deliverRandomness( + uint256 requestId, + VRFTypes.RequestCommitmentV2Plus memory rc, + uint256[] memory randomWords + ) internal returns (bool success) { + VRFConsumerBaseV2Plus v; + bytes memory resp = abi.encodeWithSelector(v.rawFulfillRandomWords.selector, requestId, randomWords); + // Call with explicitly the amount of callback gas requested + // Important to not let them exhaust the gas budget and avoid oracle payment. + // Do not allow any non-view/non-pure coordinator functions to be called + // during the consumers callback code via reentrancyLock. + // Note that _callWithExactGas will revert if we do not have sufficient gas + // to give the callee their requested amount. + s_config.reentrancyLock = true; + success = _callWithExactGas(rc.callbackGasLimit, rc.sender, resp); + s_config.reentrancyLock = false; + return success; + } + + /* + * @notice Fulfill a randomness request. + * @param proof contains the proof and randomness + * @param rc request commitment pre-image, committed to at request time + * @param onlyPremium only charge premium + * @return payment amount billed to the subscription + * @dev simulated offchain to determine if sufficient balance is present to fulfill the request + */ + function fulfillRandomWords( + Proof memory proof, + VRFTypes.RequestCommitmentV2Plus memory rc, + bool onlyPremium + ) external nonReentrant returns (uint96 payment) { + uint256 startGas = gasleft(); + // fulfillRandomWords msg.data has 772 bytes and with an additional + // buffer of 32 bytes, we get 804 bytes. + /* Data size split: + * fulfillRandomWords function signature - 4 bytes + * proof - 416 bytes + * pk - 64 bytes + * gamma - 64 bytes + * c - 32 bytes + * s - 32 bytes + * seed - 32 bytes + * uWitness - 32 bytes + * cGammaWitness - 64 bytes + * sHashWitness - 64 bytes + * zInv - 32 bytes + * requestCommitment - 320 bytes + * blockNum - 32 bytes + * subId - 32 bytes + * callbackGasLimit - 32 bytes + * numWords - 32 bytes + * sender - 32 bytes + * extraArgs - 128 bytes + * onlyPremium - 32 bytes + */ + if (msg.data.length > 804) { + revert MsgDataTooBig(msg.data.length, 804); + } + Output memory output = _getRandomnessFromProof(proof, rc); + uint256 gasPrice = _getValidatedGasPrice(onlyPremium, output.provingKey.maxGas); + + uint256[] memory randomWords; + uint256 randomness = output.randomness; + // stack too deep error + { + uint256 numWords = rc.numWords; + randomWords = new uint256[](numWords); + for (uint256 i = 0; i < numWords; ++i) { + randomWords[i] = uint256(keccak256(abi.encode(randomness, i))); + } + } + + delete s_requestCommitments[output.requestId]; + bool success = _deliverRandomness(output.requestId, rc, randomWords); + + // Increment the req count for the subscription. + ++s_subscriptions[rc.subId].reqCount; + // Decrement the pending req count for the consumer. + --s_consumers[rc.sender][rc.subId].pendingReqCount; + + bool nativePayment = uint8(rc.extraArgs[rc.extraArgs.length - 1]) == 1; + + // stack too deep error + { + // We want to charge users exactly for how much gas they use in their callback with + // an additional premium. If onlyPremium is true, only premium is charged without + // the gas cost. The gasAfterPaymentCalculation is meant to cover these additional + // operations where we decrement the subscription balance and increment the + // withdrawable balance. + bool isFeedStale; + (payment, isFeedStale) = _calculatePaymentAmount(startGas, gasPrice, nativePayment, onlyPremium); + if (isFeedStale) { + emit FallbackWeiPerUnitLinkUsed(output.requestId, s_fallbackWeiPerUnitLink); + } + } + + _chargePayment(payment, nativePayment, rc.subId); + + // Include payment in the event for tracking costs. + emit RandomWordsFulfilled(output.requestId, randomness, rc.subId, payment, nativePayment, success, onlyPremium); + + return payment; + } + + function _chargePayment(uint96 payment, bool nativePayment, uint256 subId) internal { + Subscription storage subcription = s_subscriptions[subId]; + if (nativePayment) { + uint96 prevBal = subcription.nativeBalance; + if (prevBal < payment) { + revert InsufficientBalance(); + } + subcription.nativeBalance = prevBal - payment; + s_withdrawableNative += payment; + } else { + uint96 prevBal = subcription.balance; + if (prevBal < payment) { + revert InsufficientBalance(); + } + subcription.balance = prevBal - payment; + s_withdrawableTokens += payment; + } + } + + function _calculatePaymentAmount( + uint256 startGas, + uint256 weiPerUnitGas, + bool nativePayment, + bool onlyPremium + ) internal view returns (uint96, bool) { + if (nativePayment) { + return (_calculatePaymentAmountNative(startGas, weiPerUnitGas, onlyPremium), false); + } + return _calculatePaymentAmountLink(startGas, weiPerUnitGas, onlyPremium); + } + + function _calculatePaymentAmountNative( + uint256 startGas, + uint256 weiPerUnitGas, + bool onlyPremium + ) internal view returns (uint96) { + // Will return non-zero on chains that have this enabled + uint256 l1CostWei = ChainSpecificUtil._getCurrentTxL1GasFees(msg.data); + // calculate the payment without the premium + uint256 baseFeeWei = weiPerUnitGas * (s_config.gasAfterPaymentCalculation + startGas - gasleft()); + // calculate flat fee in native + uint256 flatFeeWei = 1e12 * uint256(s_config.fulfillmentFlatFeeNativePPM); + if (onlyPremium) { + return uint96((((l1CostWei + baseFeeWei) * (s_config.nativePremiumPercentage)) / 100) + flatFeeWei); + } else { + return uint96((((l1CostWei + baseFeeWei) * (100 + s_config.nativePremiumPercentage)) / 100) + flatFeeWei); + } + } + + // Get the amount of gas used for fulfillment + function _calculatePaymentAmountLink( + uint256 startGas, + uint256 weiPerUnitGas, + bool onlyPremium + ) internal view returns (uint96, bool) { + (int256 weiPerUnitLink, bool isFeedStale) = _getFeedData(); + if (weiPerUnitLink <= 0) { + revert InvalidLinkWeiPrice(weiPerUnitLink); + } + // Will return non-zero on chains that have this enabled + uint256 l1CostWei = ChainSpecificUtil._getCurrentTxL1GasFees(msg.data); + // (1e18 juels/link) ((wei/gas * gas) + l1wei) / (wei/link) = juels + uint256 paymentNoFee = (1e18 * + (weiPerUnitGas * (s_config.gasAfterPaymentCalculation + startGas - gasleft()) + l1CostWei)) / + uint256(weiPerUnitLink); + // calculate the flat fee in wei + uint256 flatFeeWei = 1e12 * + uint256(s_config.fulfillmentFlatFeeNativePPM - s_config.fulfillmentFlatFeeLinkDiscountPPM); + uint256 flatFeeJuels = (1e18 * flatFeeWei) / uint256(weiPerUnitLink); + uint256 payment; + if (onlyPremium) { + payment = ((paymentNoFee * (s_config.linkPremiumPercentage)) / 100 + flatFeeJuels); + } else { + payment = ((paymentNoFee * (100 + s_config.linkPremiumPercentage)) / 100 + flatFeeJuels); + } + if (payment > 1e27) { + revert PaymentTooLarge(); // Payment + fee cannot be more than all of the link in existence. + } + return (uint96(payment), isFeedStale); + } + + function _getFeedData() private view returns (int256 weiPerUnitLink, bool isFeedStale) { + uint32 stalenessSeconds = s_config.stalenessSeconds; + uint256 timestamp; + (, weiPerUnitLink, , timestamp, ) = LINK_NATIVE_FEED.latestRoundData(); + // solhint-disable-next-line not-rely-on-time + isFeedStale = stalenessSeconds > 0 && stalenessSeconds < block.timestamp - timestamp; + if (isFeedStale) { + weiPerUnitLink = s_fallbackWeiPerUnitLink; + } + return (weiPerUnitLink, isFeedStale); + } + + /** + * @inheritdoc IVRFSubscriptionV2Plus + */ + function pendingRequestExists(uint256 subId) public view override returns (bool) { + address[] storage consumers = s_subscriptionConfigs[subId].consumers; + uint256 consumersLength = consumers.length; + if (consumersLength == 0) { + return false; + } + for (uint256 i = 0; i < consumersLength; ++i) { + if (s_consumers[consumers[i]][subId].pendingReqCount > 0) { + return true; + } + } + return false; + } + + /** + * @inheritdoc IVRFSubscriptionV2Plus + */ + function removeConsumer(uint256 subId, address consumer) external override onlySubOwner(subId) nonReentrant { + if (pendingRequestExists(subId)) { + revert PendingRequestExists(); + } + if (!s_consumers[consumer][subId].active) { + revert InvalidConsumer(subId, consumer); + } + // Note bounded by MAX_CONSUMERS + address[] memory consumers = s_subscriptionConfigs[subId].consumers; + uint256 lastConsumerIndex = consumers.length - 1; + for (uint256 i = 0; i < consumers.length; ++i) { + if (consumers[i] == consumer) { + address last = consumers[lastConsumerIndex]; + // Storage write to preserve last element + s_subscriptionConfigs[subId].consumers[i] = last; + // Storage remove last element + s_subscriptionConfigs[subId].consumers.pop(); + break; + } + } + s_consumers[consumer][subId].active = false; + emit SubscriptionConsumerRemoved(subId, consumer); + } + + /** + * @inheritdoc IVRFSubscriptionV2Plus + */ + function cancelSubscription(uint256 subId, address to) external override onlySubOwner(subId) nonReentrant { + if (pendingRequestExists(subId)) { + revert PendingRequestExists(); + } + _cancelSubscriptionHelper(subId, to); + } + + /*************************************************************************** + * Section: Migration + ***************************************************************************/ + + address[] internal s_migrationTargets; + + /// @dev Emitted when new coordinator is registered as migratable target + event CoordinatorRegistered(address coordinatorAddress); + + /// @dev Emitted when new coordinator is deregistered + event CoordinatorDeregistered(address coordinatorAddress); + + /// @notice emitted when migration to new coordinator completes successfully + /// @param newCoordinator coordinator address after migration + /// @param subId subscription ID + event MigrationCompleted(address newCoordinator, uint256 subId); + + /// @notice emitted when migrate() is called and given coordinator is not registered as migratable target + error CoordinatorNotRegistered(address coordinatorAddress); + + /// @notice emitted when migrate() is called and given coordinator is registered as migratable target + error CoordinatorAlreadyRegistered(address coordinatorAddress); + + /// @dev encapsulates data to be migrated from current coordinator + // solhint-disable-next-line gas-struct-packing + struct V1MigrationData { + uint8 fromVersion; + uint256 subId; + address subOwner; + address[] consumers; + uint96 linkBalance; + uint96 nativeBalance; + } + + function _isTargetRegistered(address target) internal view returns (bool) { + uint256 migrationTargetsLength = s_migrationTargets.length; + for (uint256 i = 0; i < migrationTargetsLength; ++i) { + if (s_migrationTargets[i] == target) { + return true; + } + } + return false; + } + + function registerMigratableCoordinator(address target) external onlyOwner { + if (_isTargetRegistered(target)) { + revert CoordinatorAlreadyRegistered(target); + } + s_migrationTargets.push(target); + emit CoordinatorRegistered(target); + } + + function deregisterMigratableCoordinator(address target) external onlyOwner { + uint256 nTargets = s_migrationTargets.length; + for (uint256 i = 0; i < nTargets; ++i) { + if (s_migrationTargets[i] == target) { + s_migrationTargets[i] = s_migrationTargets[nTargets - 1]; + s_migrationTargets.pop(); + emit CoordinatorDeregistered(target); + return; + } + } + revert CoordinatorNotRegistered(target); + } + + function migrate(uint256 subId, address newCoordinator) external nonReentrant { + if (!_isTargetRegistered(newCoordinator)) { + revert CoordinatorNotRegistered(newCoordinator); + } + (uint96 balance, uint96 nativeBalance, , address subOwner, address[] memory consumers) = getSubscription(subId); + // solhint-disable-next-line gas-custom-errors + require(subOwner == msg.sender, "Not subscription owner"); + // solhint-disable-next-line gas-custom-errors + require(!pendingRequestExists(subId), "Pending request exists"); + + V1MigrationData memory migrationData = V1MigrationData({ + fromVersion: 1, + subId: subId, + subOwner: subOwner, + consumers: consumers, + linkBalance: balance, + nativeBalance: nativeBalance + }); + bytes memory encodedData = abi.encode(migrationData); + _deleteSubscription(subId); + IVRFCoordinatorV2PlusMigration(newCoordinator).onMigration{value: nativeBalance}(encodedData); + + // Only transfer LINK if the token is active and there is a balance. + if (address(LINK) != address(0) && balance != 0) { + // solhint-disable-next-line gas-custom-errors + require(LINK.transfer(address(newCoordinator), balance), "insufficient funds"); + } + + // despite the fact that we follow best practices this is still probably safest + // to prevent any re-entrancy possibilities. + s_config.reentrancyLock = true; + for (uint256 i = 0; i < consumers.length; ++i) { + IVRFMigratableConsumerV2Plus(consumers[i]).setCoordinator(newCoordinator); + } + s_config.reentrancyLock = false; + + emit MigrationCompleted(newCoordinator, subId); + } +} diff --git a/contracts/src/v0.8/vrf/dev/testhelpers/VRFOld.sol b/contracts/src/v0.8/vrf/dev/testhelpers/VRFOld.sol new file mode 100644 index 00000000000..137235fd0a3 --- /dev/null +++ b/contracts/src/v0.8/vrf/dev/testhelpers/VRFOld.sol @@ -0,0 +1,588 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/** **************************************************************************** + * @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 uniqueness, full + * @dev collision resistance, and full pseudo-randomness 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 VRFOld { + // See https://www.secg.org/sec2-v2.pdf, section 2.4.1, for these constants. + // Number of points in Secp256k1 + uint256 private constant GROUP_ORDER = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141; + // Prime characteristic of the galois field over which Secp256k1 is defined + uint256 private constant FIELD_SIZE = + // solium-disable-next-line indentation + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F; + uint256 private constant WORD_LENGTH_BYTES = 0x20; + + // (base^exponent) % FIELD_SIZE + // Cribbed from https://medium.com/@rbkhmrcr/precompiles-solidity-e5d29bd428c4 + function _bigModExp(uint256 base, uint256 exponent) internal view returns (uint256 exponentiation) { + uint256 callResult; + uint256[6] memory bigModExpContractInputs; + bigModExpContractInputs[0] = WORD_LENGTH_BYTES; // Length of base + bigModExpContractInputs[1] = WORD_LENGTH_BYTES; // Length of exponent + bigModExpContractInputs[2] = WORD_LENGTH_BYTES; // Length of modulus + bigModExpContractInputs[3] = base; + bigModExpContractInputs[4] = exponent; + bigModExpContractInputs[5] = FIELD_SIZE; + uint256[1] memory output; + assembly { + 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) { + // solhint-disable-next-line gas-custom-errors + revert("bigModExp failure!"); + } + return output[0]; + } + + // Let q=FIELD_SIZE. q % 4 = 3, ∴ x≡r^2 mod q ⇒ x^SQRT_POWER≡±r mod q. See + // https://en.wikipedia.org/wiki/Modular_square_root#Prime_or_prime_power_modulus + uint256 private constant SQRT_POWER = (FIELD_SIZE + 1) >> 2; + + // Computes a s.t. a^2 = x in the field. Assumes a exists + function _squareRoot(uint256 x) internal view returns (uint256) { + return _bigModExp(x, SQRT_POWER); + } + + // The value of y^2 given that (x,y) is on secp256k1. + function _ySquared(uint256 x) internal pure returns (uint256) { + // Curve is y^2=x^3+7. See section 2.4.1 of https://www.secg.org/sec2-v2.pdf + uint256 xCubed = mulmod(x, mulmod(x, x, FIELD_SIZE), FIELD_SIZE); + return addmod(xCubed, 7, FIELD_SIZE); + } + + // True iff p is on secp256k1 + function _isOnCurve(uint256[2] memory p) internal pure returns (bool) { + // Section 2.3.6. in https://www.secg.org/sec1-v2.pdf + // requires each ordinate to be in [0, ..., FIELD_SIZE-1] + // solhint-disable-next-line gas-custom-errors + require(p[0] < FIELD_SIZE, "invalid x-ordinate"); + // solhint-disable-next-line gas-custom-errors + require(p[1] < FIELD_SIZE, "invalid y-ordinate"); + 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_))); + } + return 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) { + unchecked { + p[0] = _fieldHash(b); + p[1] = _squareRoot(_ySquared(p[0])); + if (p[1] % 2 == 1) { + // Note that 0 <= p[1] < FIELD_SIZE + // so this cannot wrap, we use unchecked to save gas. + p[1] = FIELD_SIZE - p[1]; + } + } + return p; + } + + // Domain-separation tag for initial hash in _hashToCurve. Corresponds to + // vrf.go/hashToCurveHashPrefix + uint256 internal 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])); + } + return rv; + } + + /** ********************************************************************* + * @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) { + // solhint-disable-next-line gas-custom-errors + require(scalar != 0, "zero scalar"); // 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(uint160(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) { + unchecked { + uint256 num1 = mulmod(z2, x1, FIELD_SIZE); + // Note this cannot wrap since x2 is a point in [0, FIELD_SIZE-1] + // we use unchecked to save gas. + uint256 num2 = mulmod(FIELD_SIZE - x2, z1, FIELD_SIZE); + (x3, z3) = (addmod(num1, num2, FIELD_SIZE), mulmod(z1, z2, FIELD_SIZE)); + } + return (x3, z3); + } + + // 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)); + return (x3, z3); + } + + /** ************************************************************************** + @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) { + unchecked { + // 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 required 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. + // Cannot wrap since px and py are in [0, FIELD_SIZE-1] + 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; + } + } + return (sx, sy, sz); + } + + // 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]); + // solhint-disable-next-line gas-custom-errors + 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. + unchecked { + // solhint-disable-next-line gas-custom-errors + require(lcWitness != address(0), "bad witness"); + uint8 v = (p[1] % 2 == 0) ? 27 : 28; // parity of y-ordinate of p + // Note this cannot wrap (X - Y % X), but we use unchecked to save + // gas. + 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) { + unchecked { + // Note we are relying on the wrap around here + // solhint-disable-next-line gas-custom-errors + require((cp1Witness[0] % FIELD_SIZE) != (sp2Witness[0] % FIELD_SIZE), "points in sum must be distinct"); + // solhint-disable-next-line gas-custom-errors + require(_ecmulVerify(p1, c, cp1Witness), "First mul check failed"); + // solhint-disable-next-line gas-custom-errors + require(_ecmulVerify(p2, s, sp2Witness), "Second mul check failed"); + return _affineECAdd(cp1Witness, sp2Witness, zInv); + } + } + + // Domain-separation tag for the hash taken in _scalarFromCurvePoints. + // Corresponds to scalarFromCurveHashPrefix in vrf.go + uint256 internal 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 { + unchecked { + // solhint-disable-next-line gas-custom-errors + require(_isOnCurve(pk), "public key is not on curve"); + // solhint-disable-next-line gas-custom-errors + require(_isOnCurve(gamma), "gamma is not on curve"); + // solhint-disable-next-line gas-custom-errors + require(_isOnCurve(cGammaWitness), "cGammaWitness is not on curve"); + // solhint-disable-next-line gas-custom-errors + 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 construction in + // vrf.GenerateProof, we correspondingly take the difference instead of + // taking the sum as they do in step 7 of section 5.1.) + // solhint-disable-next-line gas-custom-errors + 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); + // solhint-disable-next-line gas-custom-errors + require(c == derivedC, "invalid proof"); + } + } + + // Domain-separation tag for the hash used as the final VRF output. + // Corresponds to vrfRandomOutputHashPrefix in vrf.go + uint256 internal constant VRF_RANDOM_OUTPUT_HASH_PREFIX = 3; + + struct Proof { + uint256[2] pk; + uint256[2] gamma; + uint256 c; + uint256 s; + uint256 seed; + address uWitness; + uint256[2] cGammaWitness; + uint256[2] sHashWitness; + uint256 zInv; + } + + /* *************************************************************************** + * @notice Returns proof's output, if proof is valid. Otherwise reverts + + * @param proof vrf proof components + * @param seed seed used to generate the vrf output + * + * Throws if proof is invalid, otherwise: + * @return output i.e., the random output implied by the proof + * *************************************************************************** + */ + function _randomValueFromVRFProof(Proof memory proof, uint256 seed) internal view returns (uint256 output) { + _verifyVRFProof( + proof.pk, + proof.gamma, + proof.c, + proof.s, + seed, + proof.uWitness, + proof.cGammaWitness, + proof.sHashWitness, + proof.zInv + ); + output = uint256(keccak256(abi.encode(VRF_RANDOM_OUTPUT_HASH_PREFIX, proof.gamma))); + return output; + } +} diff --git a/core/gethwrappers/generated/vrf_coordinator_test_v2_5/vrf_coordinator_test_v2_5.go b/core/gethwrappers/generated/vrf_coordinator_test_v2_5/vrf_coordinator_test_v2_5.go new file mode 100644 index 00000000000..6d6d38ef381 --- /dev/null +++ b/core/gethwrappers/generated/vrf_coordinator_test_v2_5/vrf_coordinator_test_v2_5.go @@ -0,0 +1,3994 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package vrf_coordinator_test_v2_5 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type VRFOldProof struct { + Pk [2]*big.Int + Gamma [2]*big.Int + C *big.Int + S *big.Int + Seed *big.Int + UWitness common.Address + CGammaWitness [2]*big.Int + SHashWitness [2]*big.Int + ZInv *big.Int +} + +type VRFTypesRequestCommitmentV2Plus struct { + BlockNum uint64 + SubId *big.Int + CallbackGasLimit uint32 + NumWords uint32 + Sender common.Address + ExtraArgs []byte +} + +type VRFV2PlusClientRandomWordsRequest struct { + KeyHash [32]byte + SubId *big.Int + RequestConfirmations uint16 + CallbackGasLimit uint32 + NumWords uint32 + ExtraArgs []byte +} + +var VRFCoordinatorTestV25MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"blockhashStore\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"BlockhashNotInStore\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorNotRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToSendNative\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxGas\",\"type\":\"uint256\"}],\"name\":\"GasPriceExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"premiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"max\",\"type\":\"uint8\"}],\"name\":\"InvalidPremiumPercentage\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"have\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"min\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"max\",\"type\":\"uint16\"}],\"name\":\"InvalidRequestConfirmations\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"flatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeNativePPM\",\"type\":\"uint32\"}],\"name\":\"LinkDiscountTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"have\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"max\",\"type\":\"uint32\"}],\"name\":\"MsgDataTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeRequestedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCorrespondingRequest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"NoSuchProvingKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"NumWordsTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"}],\"name\":\"FallbackWeiPerUnitLinkUsed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"MigrationCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativeFundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"ProvingKeyDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"ProvingKeyRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"outputSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"nativePayment\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"onlyPremium\",\"type\":\"bool\"}],\"name\":\"RandomWordsFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"preSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RandomWordsRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountLink\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountNative\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldNativeBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newNativeBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFundedWithNative\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BLOCKHASH_STORE\",\"outputs\":[{\"internalType\":\"contractBlockhashStoreInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK_NATIVE_FEED\",\"outputs\":[{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_CONSUMERS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_NUM_WORDS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_REQUEST_CONFIRMATIONS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"deregisterMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"}],\"name\":\"deregisterProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"pk\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"gamma\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seed\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"uWitness\",\"type\":\"address\"},{\"internalType\":\"uint256[2]\",\"name\":\"cGammaWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"sHashWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"zInv\",\"type\":\"uint256\"}],\"internalType\":\"structVRFOld.Proof\",\"name\":\"proof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockNum\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFTypes.RequestCommitmentV2Plus\",\"name\":\"rc\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"onlyPremium\",\"type\":\"bool\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"fundSubscriptionWithNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveSubscriptionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"reqCount\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"subOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicKey\",\"type\":\"uint256[2]\"}],\"name\":\"hashOfKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"}],\"name\":\"migrate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverNativeFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"registerProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFV2PlusClient.RandomWordsRequest\",\"name\":\"req\",\"type\":\"tuple\"}],\"name\":\"requestRandomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_config\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"reentrancyLock\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_currentSubNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fallbackWeiPerUnitLink\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_provingKeyHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_provingKeys\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"exists\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestCommitments\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalNativeBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"}],\"name\":\"setLINKAndLINKNativeFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b5060405162005e6338038062005e6383398101604081905262000034916200017e565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d3565b5050506001600160a01b0316608052620001b0565b336001600160a01b038216036200012d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019157600080fd5b81516001600160a01b0381168114620001a957600080fd5b9392505050565b608051615c90620001d3600039600081816105d2015261331e0152615c906000f3fe60806040526004361061028c5760003560e01c80638402595e11610164578063b2a7cac5116100c6578063da2f26101161008a578063e72f6e3011610064578063e72f6e3014610904578063ee9d2d3814610924578063f2fde38b1461095157600080fd5b8063da2f261014610854578063dac83d29146108b3578063dc311dd3146108d357600080fd5b8063b2a7cac5146107b4578063bec4c08c146107d4578063caf70c4a146107f4578063cb63179714610814578063d98e620e1461083457600080fd5b80639d40a6fd11610128578063a63e0bfb11610102578063a63e0bfb14610747578063aa433aff14610767578063aefb212f1461078757600080fd5b80639d40a6fd146106da578063a21a23e414610712578063a4c0ed361461072757600080fd5b80638402595e1461064957806386fe91c7146106695780638da5cb5b1461068957806395b55cfc146106a75780639b1c385e146106ba57600080fd5b8063405b84fa1161020d57806364d51a2a116101d157806372e9d565116101ab57806372e9d565146105f457806379ba5097146106145780637a5a2aef1461062957600080fd5b806364d51a2a1461058b57806365982744146105a0578063689c4517146105c057600080fd5b8063405b84fa146104d057806340d6bb82146104f057806341af6c871461051b57806351cff8d91461054b5780635d06b4ab1461056b57600080fd5b806315c48b841161025457806315c48b84146103f157806318e3dd27146104195780631b6b6d23146104585780632f622e6b14610490578063301f42e9146104b057600080fd5b806304104edb14610291578063043bd6ae146102b3578063088070f5146102dc57806308821d58146103b15780630ae09540146103d1575b600080fd5b34801561029d57600080fd5b506102b16102ac366004614f21565b610971565b005b3480156102bf57600080fd5b506102c960105481565b6040519081526020015b60405180910390f35b3480156102e857600080fd5b50600c546103549061ffff81169063ffffffff62010000820481169160ff660100000000000082048116926701000000000000008304811692600160581b8104821692600160781b8204831692600160981b83041691600160b81b8104821691600160c01b9091041689565b6040805161ffff909a168a5263ffffffff98891660208b01529615159689019690965293861660608801529185166080870152841660a08601529290921660c084015260ff91821660e084015216610100820152610120016102d3565b3480156103bd57600080fd5b506102b16103cc366004614f4f565b610aea565b3480156103dd57600080fd5b506102b16103ec366004614f6b565b610ca7565b3480156103fd57600080fd5b5061040660c881565b60405161ffff90911681526020016102d3565b34801561042557600080fd5b50600a5461044090600160601b90046001600160601b031681565b6040516001600160601b0390911681526020016102d3565b34801561046457600080fd5b50600254610478906001600160a01b031681565b6040516001600160a01b0390911681526020016102d3565b34801561049c57600080fd5b506102b16104ab366004614f21565b610cef565b3480156104bc57600080fd5b506104406104cb3660046151cd565b610d95565b3480156104dc57600080fd5b506102b16104eb366004614f6b565b6110ab565b3480156104fc57600080fd5b506105066101f481565b60405163ffffffff90911681526020016102d3565b34801561052757600080fd5b5061053b6105363660046152bb565b61148d565b60405190151581526020016102d3565b34801561055757600080fd5b506102b1610566366004614f21565b611541565b34801561057757600080fd5b506102b1610586366004614f21565b611666565b34801561059757600080fd5b50610406606481565b3480156105ac57600080fd5b506102b16105bb3660046152d4565b611724565b3480156105cc57600080fd5b506104787f000000000000000000000000000000000000000000000000000000000000000081565b34801561060057600080fd5b50600354610478906001600160a01b031681565b34801561062057600080fd5b506102b1611784565b34801561063557600080fd5b506102b1610644366004615302565b611835565b34801561065557600080fd5b506102b1610664366004614f21565b611969565b34801561067557600080fd5b50600a54610440906001600160601b031681565b34801561069557600080fd5b506000546001600160a01b0316610478565b6102b16106b53660046152bb565b611a84565b3480156106c657600080fd5b506102c96106d5366004615336565b611b94565b3480156106e657600080fd5b506007546106fa906001600160401b031681565b6040516001600160401b0390911681526020016102d3565b34801561071e57600080fd5b506102c9611fda565b34801561073357600080fd5b506102b1610742366004615370565b6121c1565b34801561075357600080fd5b506102b161076236600461541b565b612329565b34801561077357600080fd5b506102b16107823660046152bb565b612610565b34801561079357600080fd5b506107a76107a23660046154bc565b612643565b6040516102d39190615519565b3480156107c057600080fd5b506102b16107cf3660046152bb565b612745565b3480156107e057600080fd5b506102b16107ef366004614f6b565b612834565b34801561080057600080fd5b506102c961080f36600461552c565b612927565b34801561082057600080fd5b506102b161082f366004614f6b565b612957565b34801561084057600080fd5b506102c961084f3660046152bb565b612bc5565b34801561086057600080fd5b5061089461086f3660046152bb565b600d6020526000908152604090205460ff81169061010090046001600160401b031682565b6040805192151583526001600160401b039091166020830152016102d3565b3480156108bf57600080fd5b506102b16108ce366004614f6b565b612be6565b3480156108df57600080fd5b506108f36108ee3660046152bb565b612c81565b6040516102d3959493929190615581565b34801561091057600080fd5b506102b161091f366004614f21565b612d5a565b34801561093057600080fd5b506102c961093f3660046152bb565b600f6020526000908152604090205481565b34801561095d57600080fd5b506102b161096c366004614f21565b612f1b565b610979612f2c565b60115460005b81811015610abd57826001600160a01b0316601182815481106109a4576109a46155d6565b6000918252602090912001546001600160a01b031603610aad5760116109cb600184615602565b815481106109db576109db6155d6565b600091825260209091200154601180546001600160a01b039092169183908110610a0757610a076155d6565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506011805480610a4657610a46615615565b6000828152602090819020600019908301810180546001600160a01b03191690559091019091556040516001600160a01b03851681527ff80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af3791015b60405180910390a1505050565b610ab68161562b565b905061097f565b50604051635428d44960e01b81526001600160a01b03831660048201526024015b60405180910390fd5b50565b610af2612f2c565b604080518082018252600091610b21919084906002908390839080828437600092019190915250612927915050565b6000818152600d602090815260409182902082518084019093525460ff811615158084526101009091046001600160401b03169183019190915291925090610b7f57604051631dfd6e1360e21b815260048101839052602401610ade565b6000828152600d60205260408120805468ffffffffffffffffff19169055600e54905b81811015610c515783600e8281548110610bbe57610bbe6155d6565b906000526020600020015403610c4157600e610bdb600184615602565b81548110610beb57610beb6155d6565b9060005260206000200154600e8281548110610c0957610c096155d6565b600091825260209091200155600e805480610c2657610c26615615565b60019003818190600052602060002001600090559055610c51565b610c4a8161562b565b9050610ba2565b507f9b6868e0eb737bcd72205360baa6bfd0ba4e4819a33ade2db384e8a8025639a5838360200151604051610c999291909182526001600160401b0316602082015260400190565b60405180910390a150505050565b81610cb181612f88565b610cb9612fdd565b610cc28361148d565b15610ce057604051631685ecdd60e31b815260040160405180910390fd5b610cea838361300b565b505050565b610cf7612fdd565b610cff612f2c565b600b54600160601b90046001600160601b0316610d1d8115156130ee565b600b80546bffffffffffffffffffffffff60601b19169055600a8054829190600c90610d5a908490600160601b90046001600160601b0316615644565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550610d9182826001600160601b031661310c565b5050565b6000610d9f612fdd565b60005a9050610324361115610dd157604051630f28961b60e01b81523660048201526103246024820152604401610ade565b6000610ddd8686613180565b90506000610df385836000015160200151613431565b60408301516060888101519293509163ffffffff16806001600160401b03811115610e2057610e20614f9b565b604051908082528060200260200182016040528015610e49578160200160208202803683370190505b50925060005b81811015610eb15760408051602081018590529081018290526060016040516020818303038152906040528051906020012060001c848281518110610e9657610e966155d6565b6020908102919091010152610eaa8161562b565b9050610e4f565b5050602080850180516000908152600f9092526040822082905551610ed7908a8561348c565b60208a8101516000908152600690915260409020805491925090601890610f0d90600160c01b90046001600160401b0316615664565b82546101009290920a6001600160401b0381810219909316918316021790915560808a01516001600160a01b03166000908152600460209081526040808320828e01518452909152902080549091600991610f7091600160481b9091041661568a565b91906101000a8154816001600160401b0302191690836001600160401b0316021790555060008960a0015160018b60a0015151610fad9190615602565b81518110610fbd57610fbd6155d6565b60209101015160f81c60011490506000610fd98887848d613530565b909950905080156110245760208088015160105460408051928352928201527f6ca648a381f22ead7e37773d934e64885dcf861fbfbb26c40354cbf0c4662d1a910160405180910390a15b5061103488828c60200151613568565b6020808b015187820151604080518781526001600160601b038d16948101949094528415159084015284151560608401528b1515608084015290917faeb4b4786571e184246d39587f659abf0e26f41f6a3358692250382c0cdb47b79060a00160405180910390a3505050505050505b9392505050565b6110b3612fdd565b6110bc816136c5565b6110e457604051635428d44960e01b81526001600160a01b0382166004820152602401610ade565b6000806000806110f386612c81565b945094505093509350336001600160a01b0316826001600160a01b03161461115d5760405162461bcd60e51b815260206004820152601660248201527f4e6f7420737562736372697074696f6e206f776e6572000000000000000000006044820152606401610ade565b6111668661148d565b156111b35760405162461bcd60e51b815260206004820152601660248201527f50656e64696e67207265717565737420657869737473000000000000000000006044820152606401610ade565b6040805160c0810182526001815260208082018990526001600160a01b03851682840152606082018490526001600160601b038088166080840152861660a083015291519091600091611208918491016156ad565b604051602081830303815290604052905061122288613730565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b0388169061125b908590600401615772565b6000604051808303818588803b15801561127457600080fd5b505af1158015611288573d6000803e3d6000fd5b50506002546001600160a01b0316158015935091506112b1905057506001600160601b03861615155b156113815760025460405163a9059cbb60e01b81526001600160a01b0389811660048301526001600160601b03891660248301529091169063a9059cbb906044016020604051808303816000875af1158015611311573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113359190615785565b6113815760405162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e647300000000000000000000000000006044820152606401610ade565b600c805466ff0000000000001916660100000000000017905560005b8351811015611430578381815181106113b8576113b86155d6565b6020908102919091010151604051638ea9811760e01b81526001600160a01b038a8116600483015290911690638ea9811790602401600060405180830381600087803b15801561140757600080fd5b505af115801561141b573d6000803e3d6000fd5b50505050806114299061562b565b905061139d565b50600c805466ff00000000000019169055604080516001600160a01b0389168152602081018a90527fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187910160405180910390a15050505050505050565b600081815260056020526040812060020180548083036114b1575060009392505050565b60005b81811015611536576000600460008584815481106114d4576114d46155d6565b60009182526020808320909101546001600160a01b0316835282810193909352604091820181208982529092529020546001600160401b03600160481b90910416111561152657506001949350505050565b61152f8161562b565b90506114b4565b506000949350505050565b611549612fdd565b611551612f2c565b6002546001600160a01b031661157a5760405163c1f0c0a160e01b815260040160405180910390fd5b600b546001600160601b03166115918115156130ee565b600b80546bffffffffffffffffffffffff19169055600a80548291906000906115c49084906001600160601b0316615644565b82546101009290920a6001600160601b0381810219909316918316021790915560025460405163a9059cbb60e01b81526001600160a01b0386811660048301529285166024820152610d91935091169063a9059cbb906044015b6020604051808303816000875af115801561163d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116619190615785565b6130ee565b61166e612f2c565b611677816136c5565b156116a05760405163ac8a27ef60e01b81526001600160a01b0382166004820152602401610ade565b601180546001810182556000919091527f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c680180546001600160a01b0319166001600160a01b0383169081179091556040519081527fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af016259060200160405180910390a150565b61172c612f2c565b6002546001600160a01b03161561175657604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b6001546001600160a01b031633146117de5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610ade565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61183d612f2c565b60408051808201825260009161186c919085906002908390839080828437600092019190915250612927915050565b6000818152600d602052604090205490915060ff16156118a257604051634a0b8fa760e01b815260048101829052602401610ade565b60408051808201825260018082526001600160401b0385811660208085018281526000888152600d835287812096518754925168ffffffffffffffffff1990931690151568ffffffffffffffff00191617610100929095169190910293909317909455600e805493840181559091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd9091018490558251848152918201527f9b911b2c240bfbef3b6a8f7ed6ee321d1258bb2a3fe6becab52ac1cd3210afd39101610aa0565b611971612f2c565b600a544790600160601b90046001600160601b0316818111156119b1576040516354ced18160e11b81526004810182905260248101839052604401610ade565b81811015610cea5760006119c58284615602565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d8060008114611a14576040519150601f19603f3d011682016040523d82523d6000602084013e611a19565b606091505b5050905080611a3b5760405163950b247960e01b815260040160405180910390fd5b604080516001600160a01b0387168152602081018490527f4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c910160405180910390a15050505050565b611a8c612fdd565b600081815260056020526040902054611aad906001600160a01b03166138e2565b60008181526006602052604090208054600160601b90046001600160601b0316903490600c611adc83856157a2565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b0316611b2491906157a2565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e902823484611b7791906157c2565b604080519283526020830191909152015b60405180910390a25050565b6000611b9e612fdd565b602080830135600081815260059092526040909120546001600160a01b0316611bda57604051630fb532db60e11b815260040160405180910390fd5b336000908152600460209081526040808320848452808352928190208151606081018352905460ff811615158083526001600160401b036101008304811695840195909552600160481b9091049093169181019190915290611c58576040516379bfd40160e01b815260048101849052336024820152604401610ade565b600c5461ffff16611c6f60608701604088016157d5565b61ffff161080611c92575060c8611c8c60608701604088016157d5565b61ffff16115b15611cd857611ca760608601604087016157d5565b600c5460405163539c34bb60e11b815261ffff92831660048201529116602482015260c86044820152606401610ade565b600c5462010000900463ffffffff16611cf760808701606088016157f0565b63ffffffff161115611d4757611d1360808601606087016157f0565b600c54604051637aebf00f60e11b815263ffffffff9283166004820152620100009091049091166024820152604401610ade565b6101f4611d5a60a08701608088016157f0565b63ffffffff161115611da057611d7660a08601608087016157f0565b6040516311ce1afb60e21b815263ffffffff90911660048201526101f46024820152604401610ade565b806020018051611daf90615664565b6001600160401b03169052604081018051611dc990615664565b6001600160401b03908116909152602082810151604080518935818501819052338284015260608201899052929094166080808601919091528151808603909101815260a08501825280519084012060c085019290925260e08085018390528151808603909101815261010090940190528251929091019190912060009190955090506000611e6b611e66611e6160a08a018a61580b565b613909565b61398a565b905085611e766139fb565b86611e8760808b0160608c016157f0565b611e9760a08c0160808d016157f0565b3386604051602001611eaf9796959493929190615858565b60405160208183030381529060405280519060200120600f600088815260200190815260200160002081905550336001600160a01b03168588600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e89868c6040016020810190611f2291906157d5565b8d6060016020810190611f3591906157f0565b8e6080016020810190611f4891906157f0565b89604051611f5b969594939291906158af565b60405180910390a45050600092835260209182526040928390208151815493830151929094015168ffffffffffffffffff1990931693151568ffffffffffffffff001916939093176101006001600160401b03928316021770ffffffffffffffff0000000000000000001916600160481b91909216021790555b919050565b6000611fe4612fdd565b6007546001600160401b031633611ffc600143615602565b6040516bffffffffffffffffffffffff19606093841b81166020830152914060348201523090921b1660548201526001600160c01b031960c083901b16606882015260700160408051601f19818403018152919052805160209091012091506120668160016158ee565b6007805467ffffffffffffffff19166001600160401b03928316179055604080516000808252608082018352602080830182815283850183815260608086018581528a86526006855287862093518454935191516001600160601b039182166001600160c01b031990951694909417600160601b91909216021777ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b9290981691909102969096179055835194850184523385528481018281528585018481528884526005835294909220855181546001600160a01b03199081166001600160a01b0392831617835593516001830180549095169116179092559251805192949391926121769260028501920190614e0f565b5061218691506008905084613a7c565b5060405133815283907f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d9060200160405180910390a2505090565b6121c9612fdd565b6002546001600160a01b031633146121f4576040516344b0e3c360e01b815260040160405180910390fd5b6020811461221557604051638129bbcd60e01b815260040160405180910390fd5b6000612223828401846152bb565b600081815260056020526040902054909150612247906001600160a01b03166138e2565b600081815260066020526040812080546001600160601b03169186919061226e83856157a2565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b03166122b691906157a2565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a82878461230991906157c2565b6040805192835260208301919091520160405180910390a2505050505050565b612331612f2c565b60c861ffff8a16111561236b5760405163539c34bb60e11b815261ffff8a1660048201819052602482015260c86044820152606401610ade565b6000851361238f576040516321ea67b360e11b815260048101869052602401610ade565b8363ffffffff168363ffffffff1611156123cc576040516313c06e5960e11b815263ffffffff808516600483015285166024820152604401610ade565b609b60ff831611156123fd57604051631d66288d60e11b815260ff83166004820152609b6024820152604401610ade565b609b60ff8216111561242e57604051631d66288d60e11b815260ff82166004820152609b6024820152604401610ade565b604080516101208101825261ffff8b1680825263ffffffff808c16602084018190526000848601528b8216606085018190528b8316608086018190528a841660a08701819052938a1660c0870181905260ff808b1660e08901819052908a16610100909801889052600c8054600160c01b90990260ff60c01b19600160b81b9093029290921661ffff60b81b19600160981b90940263ffffffff60981b19600160781b9099029890981676ffffffffffffffff00000000000000000000000000000019600160581b9096026effffffff000000000000000000000019670100000000000000909802979097166effffffffffffffffff000000000000196201000090990265ffffffffffff19909c16909a179a909a1796909616979097179390931791909116959095179290921793909316929092179190911790556010869055517f2c6b6b12413678366b05b145c5f00745bdd00e739131ab5de82484a50c9d78b6906125fd908b908b908b908b908b908b908b908b908b9061ffff99909916895263ffffffff97881660208a0152958716604089015293861660608801526080870192909252841660a086015290921660c084015260ff91821660e0840152166101008201526101200190565b60405180910390a1505050505050505050565b612618612f2c565b6000818152600560205260409020546001600160a01b0316612639816138e2565b610d91828261300b565b606060006126516008613a88565b905080841061267357604051631390f2a160e01b815260040160405180910390fd5b600061267f84866157c2565b90508181118061268d575083155b6126975780612699565b815b905060006126a78683615602565b9050806001600160401b038111156126c1576126c1614f9b565b6040519080825280602002602001820160405280156126ea578160200160208202803683370190505b50935060005b8181101561273a5761270d61270588836157c2565b600890613a92565b85828151811061271f5761271f6155d6565b60209081029190910101526127338161562b565b90506126f0565b505050505b92915050565b61274d612fdd565b6000818152600560205260409020546001600160a01b031661276e816138e2565b6000828152600560205260409020600101546001600160a01b031633146127c7576000828152600560205260409081902060010154905163d084e97560e01b81526001600160a01b039091166004820152602401610ade565b6000828152600560209081526040918290208054336001600160a01b03199182168117835560019092018054909116905582516001600160a01b03851681529182015283917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c93869101611b88565b8161283e81612f88565b612846612fdd565b6001600160a01b03821660009081526004602090815260408083208684529091529020805460ff16156128795750505050565b60008481526005602052604090206002018054606319016128ad576040516305a48e0f60e01b815260040160405180910390fd5b8154600160ff199091168117835581549081018255600082815260209081902090910180546001600160a01b0319166001600160a01b03871690811790915560405190815286917f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e191015b60405180910390a25050505050565b60008160405160200161293a9190615931565b604051602081830303815290604052805190602001209050919050565b8161296181612f88565b612969612fdd565b6129728361148d565b1561299057604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b038216600090815260046020908152604080832086845290915290205460ff166129e6576040516379bfd40160e01b8152600481018490526001600160a01b0383166024820152604401610ade565b600083815260056020908152604080832060020180548251818502810185019093528083529192909190830182828015612a4957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612a2b575b50505050509050600060018251612a609190615602565b905060005b8251811015612b6957846001600160a01b0316838281518110612a8a57612a8a6155d6565b60200260200101516001600160a01b031603612b59576000838381518110612ab457612ab46155d6565b6020026020010151905080600560008981526020019081526020016000206002018381548110612ae657612ae66155d6565b600091825260208083209190910180546001600160a01b0319166001600160a01b039490941693909317909255888152600590915260409020600201805480612b3157612b31615615565b600082815260209020810160001990810180546001600160a01b031916905501905550612b69565b612b628161562b565b9050612a65565b506001600160a01b0384166000818152600460209081526040808320898452825291829020805460ff19169055905191825286917f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a79101612918565b600e8181548110612bd557600080fd5b600091825260209091200154905081565b81612bf081612f88565b612bf8612fdd565b600083815260056020526040902060018101546001600160a01b03848116911614612c7b576001810180546001600160a01b0319166001600160a01b03851690811790915560408051338152602081019290925285917f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a191015b60405180910390a25b50505050565b600081815260056020526040812054819081906001600160a01b03166060612ca8826138e2565b600086815260066020908152604080832054600583529281902060020180548251818502810185019093528083526001600160601b0380861695600160601b810490911694600160c01b9091046001600160401b0316938893929091839190830182828015612d4057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612d22575b505050505090509450945094509450945091939590929450565b612d62612f2c565b6002546001600160a01b0316612d8b5760405163c1f0c0a160e01b815260040160405180910390fd5b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612dd4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612df8919061593f565b600a549091506001600160601b031681811115612e32576040516354ced18160e11b81526004810182905260248101839052604401610ade565b81811015610cea576000612e468284615602565b60025460405163a9059cbb60e01b81526001600160a01b0387811660048301526024820184905292935091169063a9059cbb906044016020604051808303816000875af1158015612e9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ebf9190615785565b612edc57604051631f01ff1360e21b815260040160405180910390fd5b604080516001600160a01b0386168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b4366009101610c99565b612f23612f2c565b610ae781613a9e565b6000546001600160a01b03163314612f865760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610ade565b565b6000818152600560205260409020546001600160a01b0316612fa9816138e2565b336001600160a01b03821614610d9157604051636c51fda960e11b81526001600160a01b0382166004820152602401610ade565b600c546601000000000000900460ff1615612f865760405163769dd35360e11b815260040160405180910390fd5b60008061301784613730565b60025491935091506001600160a01b03161580159061303e57506001600160601b03821615155b156130865760025460405163a9059cbb60e01b81526001600160a01b0385811660048301526001600160601b038516602483015261308692169063a9059cbb9060440161161e565b61309983826001600160601b031661310c565b604080516001600160a01b03851681526001600160601b03808516602083015283169181019190915284907f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c490606001612c72565b80610ae757604051631e9acf1760e31b815260040160405180910390fd5b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613159576040519150601f19603f3d011682016040523d82523d6000602084013e61315e565b606091505b5050905080610cea5760405163950b247960e01b815260040160405180910390fd5b6040805160a081018252600060608201818152608083018290528252602082018190529181019190915260006131b98460000151612927565b6000818152600d602090815260409182902082518084019093525460ff811615158084526101009091046001600160401b0316918301919091529192509061321757604051631dfd6e1360e21b815260048101839052602401610ade565b6000828660800151604051602001613239929190918252602082015260400190565b60408051601f1981840301815291815281516020928301206000818152600f909352908220549092509081900361328357604051631b44092560e11b815260040160405180910390fd5b85516020808801516040808a015160608b015160808c015160a08d015193516132b2978a979096959101615958565b6040516020818303038152906040528051906020012081146132e75760405163354a450b60e21b815260040160405180910390fd5b60006132f68760000151613b47565b9050806133bf578651604051631d2827a760e31b81526001600160401b0390911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e9413d3890602401602060405180830381865afa15801561336d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613391919061593f565b9050806133bf57865160405163175dadad60e01b81526001600160401b039091166004820152602401610ade565b60008860800151826040516020016133e1929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c905060006134088a83613c1a565b604080516060810182529788526020880196909652948601949094525092979650505050505050565b6000816001600160401b03163a111561348457821561345a57506001600160401b03811661273f565b60405163435e532d60e11b81523a60048201526001600160401b0383166024820152604401610ade565b503a92915050565b6000806000631fe543e360e01b86856040516024016134ac9291906159ab565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600c805466ff000000000000191666010000000000001790559086015160808701519192506135169163ffffffff9091169083613c85565b600c805466ff000000000000191690559695505050505050565b600080831561354f57613544868685613cd1565b60009150915061355f565b61355a868685613de2565b915091505b94509492505050565b6000818152600660205260409020821561362c5780546001600160601b03600160601b90910481169085168110156135b357604051631e9acf1760e31b815260040160405180910390fd5b6135bd8582615644565b82546bffffffffffffffffffffffff60601b1916600160601b6001600160601b039283168102919091178455600b805488939192600c926136029286929004166157a2565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555050612c7b565b80546001600160601b0390811690851681101561365c57604051631e9acf1760e31b815260040160405180910390fd5b6136668582615644565b82546bffffffffffffffffffffffff19166001600160601b03918216178355600b8054879260009161369a918591166157a2565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050505050565b601154600090815b8181101561372657836001600160a01b0316601182815481106136f2576136f26155d6565b6000918252602090912001546001600160a01b031603613716575060019392505050565b61371f8161562b565b90506136cd565b5060009392505050565b60008181526005602090815260408083206006909252822054600290910180546001600160601b0380841694600160601b90940416925b818110156137dc5760046000848381548110613785576137856155d6565b60009182526020808320909101546001600160a01b0316835282810193909352604091820181208982529092529020805470ffffffffffffffffffffffffffffffffff191690556137d58161562b565b9050613767565b50600085815260056020526040812080546001600160a01b031990811682556001820180549091169055906138146002830182614e74565b5050600085815260066020526040812055613830600886613fd4565b506001600160601b0384161561388357600a805485919060009061385e9084906001600160601b0316615644565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001600160601b038316156138db5782600a600c8282829054906101000a90046001600160601b03166138b69190615644565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b5050915091565b6001600160a01b038116610ae757604051630fb532db60e11b815260040160405180910390fd5b6040805160208101909152600081526000829003613936575060408051602081019091526000815261273f565b63125fa26760e31b61394883856159cc565b6001600160e01b0319161461397057604051632923fee760e11b815260040160405180910390fd5b61397d82600481866159fc565b8101906110a49190615a26565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa826040516024016139c391511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b600046613a0781613fe0565b15613a755760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613a4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a6f919061593f565b91505090565b4391505090565b60006110a48383614003565b600061273f825490565b60006110a48383614052565b336001600160a01b03821603613af65760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610ade565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600046613b5381613fe0565b15613c0b57610100836001600160401b0316613b6d6139fb565b613b779190615602565b1180613b935750613b866139fb565b836001600160401b031610155b15613ba15750600092915050565b6040516315a03d4160e11b81526001600160401b0384166004820152606490632b407a82906024015b602060405180830381865afa158015613be7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a4919061593f565b50506001600160401b03164090565b6000613c4e8360000151846020015185604001518660600151868860a001518960c001518a60e001518b610100015161407c565b60038360200151604051602001613c66929190615a71565b60408051601f1981840301815291905280516020909101209392505050565b60005a611388811015613c9757600080fd5b611388810390508460408204820311613caf57600080fd5b50823b613cbb57600080fd5b60008083516020850160008789f1949350505050565b600080613d146000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506142a792505050565b905060005a600c54613d34908890600160581b900463ffffffff166157c2565b613d3e9190615602565b613d489086615a85565b600c54909150600090613d6d90600160781b900463ffffffff1664e8d4a51000615a85565b90508415613db957600c548190606490600160b81b900460ff16613d9185876157c2565b613d9b9190615a85565b613da59190615ab2565b613daf91906157c2565b93505050506110a4565b600c548190606490613dd590600160b81b900460ff1682615ac6565b60ff16613d9185876157c2565b600080600080613df0614387565b9150915060008213613e18576040516321ea67b360e11b815260048101839052602401610ade565b6000613e5a6000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506142a792505050565b9050600083825a600c54613e7c908d90600160581b900463ffffffff166157c2565b613e869190615602565b613e90908b615a85565b613e9a91906157c2565b613eac90670de0b6b3a7640000615a85565b613eb69190615ab2565b600c54909150600090613edf9063ffffffff600160981b8204811691600160781b900416615adf565b613ef49063ffffffff1664e8d4a51000615a85565b9050600085613f0b83670de0b6b3a7640000615a85565b613f159190615ab2565b905060008915613f5657600c548290606490613f3b90600160c01b900460ff1687615a85565b613f459190615ab2565b613f4f91906157c2565b9050613f96565b600c548290606490613f7290600160c01b900460ff1682615ac6565b613f7f9060ff1687615a85565b613f899190615ab2565b613f9391906157c2565b90505b6b033b2e3c9fd0803ce8000000811115613fc35760405163e80fa38160e01b815260040160405180910390fd5b9b949a509398505050505050505050565b60006110a48383614452565b600061a4b1821480613ff4575062066eed82145b8061273f57505062066eee1490565b600081815260018301602052604081205461404a5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561273f565b50600061273f565b6000826000018281548110614069576140696155d6565b9060005260206000200154905092915050565b6140858961454c565b6140d15760405162461bcd60e51b815260206004820152601a60248201527f7075626c6963206b6579206973206e6f74206f6e2063757276650000000000006044820152606401610ade565b6140da8861454c565b6141265760405162461bcd60e51b815260206004820152601560248201527f67616d6d61206973206e6f74206f6e20637572766500000000000000000000006044820152606401610ade565b61412f8361454c565b61417b5760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610ade565b6141848261454c565b6141d05760405162461bcd60e51b815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e206375727665000000006044820152606401610ade565b6141dc878a8887614625565b6142285760405162461bcd60e51b815260206004820152601960248201527f6164647228632a706b2b732a6729213d5f755769746e657373000000000000006044820152606401610ade565b60006142348a87614748565b90506000614247898b878b8689896147ac565b90506000614258838d8d8a866148d8565b9050808a146142995760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610ade565b505050505050505050505050565b6000466142b381613fe0565b156142f757606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613be7573d6000803e3d6000fd5b61430081614918565b1561437e5773420000000000000000000000000000000000000f6001600160a01b03166349948e0e84604051806080016040528060488152602001615c3c60489139604051602001614353929190615afc565b6040516020818303038152906040526040518263ffffffff1660e01b8152600401613bca9190615772565b50600092915050565b600c5460035460408051633fabe5a360e21b81529051600093849367010000000000000090910463ffffffff169284926001600160a01b039092169163feaf968c9160048082019260a0929091908290030181865afa1580156143ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144129190615b45565b50919650909250505063ffffffff82161580159061443e57506144358142615602565b8263ffffffff16105b9250821561444c5760105493505b50509091565b6000818152600183016020526040812054801561453b576000614476600183615602565b855490915060009061448a90600190615602565b90508181146144ef5760008660000182815481106144aa576144aa6155d6565b90600052602060002001549050808760000184815481106144cd576144cd6155d6565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061450057614500615615565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061273f565b600091505061273f565b5092915050565b80516000906401000003d019116145a55760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420782d6f7264696e61746500000000000000000000000000006044820152606401610ade565b60208201516401000003d019116145fe5760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420792d6f7264696e61746500000000000000000000000000006044820152606401610ade565b60208201516401000003d01990800961461e8360005b602002015161495f565b1492915050565b60006001600160a01b03821661466b5760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b6044820152606401610ade565b60208401516000906001161561468257601c614685565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe19918203925060009190890987516040805160008082526020820180845287905260ff88169282019290925260608101929092526080820183905291925060019060a0016020604051602081039080840390855afa158015614720573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b614750614e92565b61477d6001848460405160200161476993929190615b95565b604051602081830303815290604052614983565b90505b6147898161454c565b61273f5780516040805160208101929092526147a59101614769565b9050614780565b6147b4614e92565b825186516401000003d01991829006919006036148135760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610ade565b61481e8789886149d0565b61486a5760405162461bcd60e51b815260206004820152601660248201527f4669727374206d756c20636865636b206661696c6564000000000000000000006044820152606401610ade565b6148758486856149d0565b6148c15760405162461bcd60e51b815260206004820152601760248201527f5365636f6e64206d756c20636865636b206661696c65640000000000000000006044820152606401610ade565b6148cc868484614afb565b98975050505050505050565b6000600286868685876040516020016148f696959493929190615bb6565b60408051601f1981840301815291905280516020909101209695505050505050565b6000600a82148061492a57506101a482145b80614937575062aa37dc82145b80614943575061210582145b80614950575062014a3382145b8061273f57505062014a341490565b6000806401000003d01980848509840990506401000003d019600782089392505050565b61498b614e92565b61499482614bc2565b81526149a96149a4826000614614565b614bfd565b6020820181905260029006600103611fd5576020810180516401000003d019039052919050565b600082600003614a105760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b6044820152606401610ade565b83516020850151600090614a2690600290615c15565b15614a3257601c614a35565b601b5b9050600070014551231950b75fc4402da1732fc9bebe198387096040805160008082526020820180845281905260ff86169282019290925260608101869052608081018390529192509060019060a0016020604051602081039080840390855afa158015614aa7573d6000803e3d6000fd5b505050602060405103519050600086604051602001614ac69190615c29565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614b03614e92565b835160208086015185519186015160009384938493614b2493909190614c1d565b919450925090506401000003d019858209600114614b845760405162461bcd60e51b815260206004820152601960248201527f696e765a206d75737420626520696e7665727365206f66207a000000000000006044820152606401610ade565b60405180604001604052806401000003d01980614ba357614ba3615a9c565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d0198110611fd557604080516020808201939093528151808203840181529082019091528051910120614bca565b600061273f826002614c166401000003d01960016157c2565b901c614cfd565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614c5d83838585614da2565b9098509050614c6e88828e88614dc6565b9098509050614c7f88828c87614dc6565b90985090506000614c928d878b85614dc6565b9098509050614ca388828686614da2565b9098509050614cb488828e89614dc6565b9098509050818114614ce9576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614ced565b8196505b5050505050509450945094915050565b600080614d08614eb0565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152614d3a614ece565b60208160c0846005600019fa925082600003614d985760405162461bcd60e51b815260206004820152601260248201527f6269674d6f64457870206661696c7572652100000000000000000000000000006044820152606401610ade565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215614e64579160200282015b82811115614e6457825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614e2f565b50614e70929150614eec565b5090565b5080546000825590600052602060002090810190610ae79190614eec565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b80821115614e705760008155600101614eed565b6001600160a01b0381168114610ae757600080fd5b8035611fd581614f01565b600060208284031215614f3357600080fd5b81356110a481614f01565b806040810183101561273f57600080fd5b600060408284031215614f6157600080fd5b6110a48383614f3e565b60008060408385031215614f7e57600080fd5b823591506020830135614f9081614f01565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715614fd357614fd3614f9b565b60405290565b60405161012081016001600160401b0381118282101715614fd357614fd3614f9b565b604051601f8201601f191681016001600160401b038111828210171561502457615024614f9b565b604052919050565b600082601f83011261503d57600080fd5b604051604081018181106001600160401b038211171561505f5761505f614f9b565b806040525080604084018581111561507657600080fd5b845b81811015615090578035835260209283019201615078565b509195945050505050565b80356001600160401b0381168114611fd557600080fd5b803563ffffffff81168114611fd557600080fd5b600060c082840312156150d857600080fd5b6150e0614fb1565b90506150eb8261509b565b815260208083013581830152615103604084016150b2565b6040830152615114606084016150b2565b6060830152608083013561512781614f01565b608083015260a08301356001600160401b038082111561514657600080fd5b818501915085601f83011261515a57600080fd5b81358181111561516c5761516c614f9b565b61517e601f8201601f19168501614ffc565b9150808252868482850101111561519457600080fd5b80848401858401376000848284010152508060a085015250505092915050565b8015158114610ae757600080fd5b8035611fd5816151b4565b60008060008385036101e08112156151e457600080fd5b6101a0808212156151f457600080fd5b6151fc614fd9565b9150615208878761502c565b8252615217876040880161502c565b60208301526080860135604083015260a0860135606083015260c0860135608083015261524660e08701614f16565b60a083015261010061525a8882890161502c565b60c084015261526d88610140890161502c565b60e0840152610180870135908301529093508401356001600160401b0381111561529657600080fd5b6152a2868287016150c6565b9250506152b26101c085016151c2565b90509250925092565b6000602082840312156152cd57600080fd5b5035919050565b600080604083850312156152e757600080fd5b82356152f281614f01565b91506020830135614f9081614f01565b6000806060838503121561531557600080fd5b61531f8484614f3e565b915061532d6040840161509b565b90509250929050565b60006020828403121561534857600080fd5b81356001600160401b0381111561535e57600080fd5b820160c081850312156110a457600080fd5b6000806000806060858703121561538657600080fd5b843561539181614f01565b93506020850135925060408501356001600160401b03808211156153b457600080fd5b818701915087601f8301126153c857600080fd5b8135818111156153d757600080fd5b8860208285010111156153e957600080fd5b95989497505060200194505050565b803561ffff81168114611fd557600080fd5b803560ff81168114611fd557600080fd5b60008060008060008060008060006101208a8c03121561543a57600080fd5b6154438a6153f8565b985061545160208b016150b2565b975061545f60408b016150b2565b965061546d60608b016150b2565b955060808a0135945061548260a08b016150b2565b935061549060c08b016150b2565b925061549e60e08b0161540a565b91506154ad6101008b0161540a565b90509295985092959850929598565b600080604083850312156154cf57600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b8381101561550e578151875295820195908201906001016154f2565b509495945050505050565b6020815260006110a460208301846154de565b60006040828403121561553e57600080fd5b6110a4838361502c565b600081518084526020808501945080840160005b8381101561550e5781516001600160a01b03168752958201959082019060010161555c565b60006001600160601b0380881683528087166020840152506001600160401b03851660408301526001600160a01b038416606083015260a060808301526155cb60a0830184615548565b979650505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8181038181111561273f5761273f6155ec565b634e487b7160e01b600052603160045260246000fd5b60006001820161563d5761563d6155ec565b5060010190565b6001600160601b03828116828216039080821115614545576145456155ec565b60006001600160401b03808316818103615680576156806155ec565b6001019392505050565b60006001600160401b038216806156a3576156a36155ec565b6000190192915050565b6020815260ff8251166020820152602082015160408201526001600160a01b0360408301511660608201526000606083015160c060808401526156f360e0840182615548565b905060808401516001600160601b0380821660a08601528060a08701511660c086015250508091505092915050565b60005b8381101561573d578181015183820152602001615725565b50506000910152565b6000815180845261575e816020860160208601615722565b601f01601f19169290920160200192915050565b6020815260006110a46020830184615746565b60006020828403121561579757600080fd5b81516110a4816151b4565b6001600160601b03818116838216019080821115614545576145456155ec565b8082018082111561273f5761273f6155ec565b6000602082840312156157e757600080fd5b6110a4826153f8565b60006020828403121561580257600080fd5b6110a4826150b2565b6000808335601e1984360301811261582257600080fd5b8301803591506001600160401b0382111561583c57600080fd5b60200191503681900382131561585157600080fd5b9250929050565b878152866020820152856040820152600063ffffffff80871660608401528086166080840152506001600160a01b03841660a083015260e060c08301526158a260e0830184615746565b9998505050505050505050565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a08301526148cc60c0830184615746565b6001600160401b03818116838216019080821115614545576145456155ec565b8060005b6002811015612c7b578151845260209384019390910190600101615912565b6040810161273f828461590e565b60006020828403121561595157600080fd5b5051919050565b8781526001600160401b0387166020820152856040820152600063ffffffff80871660608401528086166080840152506001600160a01b03841660a083015260e060c08301526158a260e0830184615746565b8281526040602082015260006159c460408301846154de565b949350505050565b6001600160e01b031981358181169160048510156159f45780818660040360031b1b83161692505b505092915050565b60008085851115615a0c57600080fd5b83861115615a1957600080fd5b5050820193919092039150565b600060208284031215615a3857600080fd5b604051602081018181106001600160401b0382111715615a5a57615a5a614f9b565b6040528235615a68816151b4565b81529392505050565b828152606081016110a4602083018461590e565b808202811582820484141761273f5761273f6155ec565b634e487b7160e01b600052601260045260246000fd5b600082615ac157615ac1615a9c565b500490565b60ff818116838216019081111561273f5761273f6155ec565b63ffffffff828116828216039080821115614545576145456155ec565b60008351615b0e818460208801615722565b835190830190615b22818360208801615722565b01949350505050565b805169ffffffffffffffffffff81168114611fd557600080fd5b600080600080600060a08688031215615b5d57600080fd5b615b6686615b2b565b9450602086015193506040860151925060608601519150615b8960808701615b2b565b90509295509295909350565b838152615ba5602082018461590e565b606081019190915260800192915050565b868152615bc6602082018761590e565b615bd3606082018661590e565b615be060a082018561590e565b615bed60e082018461590e565b60609190911b6bffffffffffffffffffffffff19166101208201526101340195945050505050565b600082615c2457615c24615a9c565b500690565b615c33818361590e565b60400191905056fe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000813000a", +} + +var VRFCoordinatorTestV25ABI = VRFCoordinatorTestV25MetaData.ABI + +var VRFCoordinatorTestV25Bin = VRFCoordinatorTestV25MetaData.Bin + +func DeployVRFCoordinatorTestV25(auth *bind.TransactOpts, backend bind.ContractBackend, blockhashStore common.Address) (common.Address, *types.Transaction, *VRFCoordinatorTestV25, error) { + parsed, err := VRFCoordinatorTestV25MetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(VRFCoordinatorTestV25Bin), backend, blockhashStore) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &VRFCoordinatorTestV25{address: address, abi: *parsed, VRFCoordinatorTestV25Caller: VRFCoordinatorTestV25Caller{contract: contract}, VRFCoordinatorTestV25Transactor: VRFCoordinatorTestV25Transactor{contract: contract}, VRFCoordinatorTestV25Filterer: VRFCoordinatorTestV25Filterer{contract: contract}}, nil +} + +type VRFCoordinatorTestV25 struct { + address common.Address + abi abi.ABI + VRFCoordinatorTestV25Caller + VRFCoordinatorTestV25Transactor + VRFCoordinatorTestV25Filterer +} + +type VRFCoordinatorTestV25Caller struct { + contract *bind.BoundContract +} + +type VRFCoordinatorTestV25Transactor struct { + contract *bind.BoundContract +} + +type VRFCoordinatorTestV25Filterer struct { + contract *bind.BoundContract +} + +type VRFCoordinatorTestV25Session struct { + Contract *VRFCoordinatorTestV25 + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type VRFCoordinatorTestV25CallerSession struct { + Contract *VRFCoordinatorTestV25Caller + CallOpts bind.CallOpts +} + +type VRFCoordinatorTestV25TransactorSession struct { + Contract *VRFCoordinatorTestV25Transactor + TransactOpts bind.TransactOpts +} + +type VRFCoordinatorTestV25Raw struct { + Contract *VRFCoordinatorTestV25 +} + +type VRFCoordinatorTestV25CallerRaw struct { + Contract *VRFCoordinatorTestV25Caller +} + +type VRFCoordinatorTestV25TransactorRaw struct { + Contract *VRFCoordinatorTestV25Transactor +} + +func NewVRFCoordinatorTestV25(address common.Address, backend bind.ContractBackend) (*VRFCoordinatorTestV25, error) { + abi, err := abi.JSON(strings.NewReader(VRFCoordinatorTestV25ABI)) + if err != nil { + return nil, err + } + contract, err := bindVRFCoordinatorTestV25(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25{address: address, abi: abi, VRFCoordinatorTestV25Caller: VRFCoordinatorTestV25Caller{contract: contract}, VRFCoordinatorTestV25Transactor: VRFCoordinatorTestV25Transactor{contract: contract}, VRFCoordinatorTestV25Filterer: VRFCoordinatorTestV25Filterer{contract: contract}}, nil +} + +func NewVRFCoordinatorTestV25Caller(address common.Address, caller bind.ContractCaller) (*VRFCoordinatorTestV25Caller, error) { + contract, err := bindVRFCoordinatorTestV25(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25Caller{contract: contract}, nil +} + +func NewVRFCoordinatorTestV25Transactor(address common.Address, transactor bind.ContractTransactor) (*VRFCoordinatorTestV25Transactor, error) { + contract, err := bindVRFCoordinatorTestV25(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25Transactor{contract: contract}, nil +} + +func NewVRFCoordinatorTestV25Filterer(address common.Address, filterer bind.ContractFilterer) (*VRFCoordinatorTestV25Filterer, error) { + contract, err := bindVRFCoordinatorTestV25(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25Filterer{contract: contract}, nil +} + +func bindVRFCoordinatorTestV25(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := VRFCoordinatorTestV25MetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VRFCoordinatorTestV25.Contract.VRFCoordinatorTestV25Caller.contract.Call(opts, result, method, params...) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.VRFCoordinatorTestV25Transactor.contract.Transfer(opts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.VRFCoordinatorTestV25Transactor.contract.Transact(opts, method, params...) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VRFCoordinatorTestV25.Contract.contract.Call(opts, result, method, params...) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.contract.Transfer(opts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.contract.Transact(opts, method, params...) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) BLOCKHASHSTORE(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "BLOCKHASH_STORE") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) BLOCKHASHSTORE() (common.Address, error) { + return _VRFCoordinatorTestV25.Contract.BLOCKHASHSTORE(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) BLOCKHASHSTORE() (common.Address, error) { + return _VRFCoordinatorTestV25.Contract.BLOCKHASHSTORE(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) LINK(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "LINK") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) LINK() (common.Address, error) { + return _VRFCoordinatorTestV25.Contract.LINK(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) LINK() (common.Address, error) { + return _VRFCoordinatorTestV25.Contract.LINK(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) LINKNATIVEFEED(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "LINK_NATIVE_FEED") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) LINKNATIVEFEED() (common.Address, error) { + return _VRFCoordinatorTestV25.Contract.LINKNATIVEFEED(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) LINKNATIVEFEED() (common.Address, error) { + return _VRFCoordinatorTestV25.Contract.LINKNATIVEFEED(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) MAXCONSUMERS(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "MAX_CONSUMERS") + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) MAXCONSUMERS() (uint16, error) { + return _VRFCoordinatorTestV25.Contract.MAXCONSUMERS(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) MAXCONSUMERS() (uint16, error) { + return _VRFCoordinatorTestV25.Contract.MAXCONSUMERS(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) MAXNUMWORDS(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "MAX_NUM_WORDS") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) MAXNUMWORDS() (uint32, error) { + return _VRFCoordinatorTestV25.Contract.MAXNUMWORDS(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) MAXNUMWORDS() (uint32, error) { + return _VRFCoordinatorTestV25.Contract.MAXNUMWORDS(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) MAXREQUESTCONFIRMATIONS(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "MAX_REQUEST_CONFIRMATIONS") + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) MAXREQUESTCONFIRMATIONS() (uint16, error) { + return _VRFCoordinatorTestV25.Contract.MAXREQUESTCONFIRMATIONS(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) MAXREQUESTCONFIRMATIONS() (uint16, error) { + return _VRFCoordinatorTestV25.Contract.MAXREQUESTCONFIRMATIONS(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) GetActiveSubscriptionIds(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "getActiveSubscriptionIds", startIndex, maxCount) + + if err != nil { + return *new([]*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) GetActiveSubscriptionIds(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + return _VRFCoordinatorTestV25.Contract.GetActiveSubscriptionIds(&_VRFCoordinatorTestV25.CallOpts, startIndex, maxCount) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) GetActiveSubscriptionIds(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + return _VRFCoordinatorTestV25.Contract.GetActiveSubscriptionIds(&_VRFCoordinatorTestV25.CallOpts, startIndex, maxCount) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) GetSubscription(opts *bind.CallOpts, subId *big.Int) (GetSubscription, + + error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "getSubscription", subId) + + outstruct := new(GetSubscription) + if err != nil { + return *outstruct, err + } + + outstruct.Balance = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.NativeBalance = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.ReqCount = *abi.ConvertType(out[2], new(uint64)).(*uint64) + outstruct.SubOwner = *abi.ConvertType(out[3], new(common.Address)).(*common.Address) + outstruct.Consumers = *abi.ConvertType(out[4], new([]common.Address)).(*[]common.Address) + + return *outstruct, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) GetSubscription(subId *big.Int) (GetSubscription, + + error) { + return _VRFCoordinatorTestV25.Contract.GetSubscription(&_VRFCoordinatorTestV25.CallOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) GetSubscription(subId *big.Int) (GetSubscription, + + error) { + return _VRFCoordinatorTestV25.Contract.GetSubscription(&_VRFCoordinatorTestV25.CallOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) HashOfKey(opts *bind.CallOpts, publicKey [2]*big.Int) ([32]byte, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "hashOfKey", publicKey) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) HashOfKey(publicKey [2]*big.Int) ([32]byte, error) { + return _VRFCoordinatorTestV25.Contract.HashOfKey(&_VRFCoordinatorTestV25.CallOpts, publicKey) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) HashOfKey(publicKey [2]*big.Int) ([32]byte, error) { + return _VRFCoordinatorTestV25.Contract.HashOfKey(&_VRFCoordinatorTestV25.CallOpts, publicKey) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) Owner() (common.Address, error) { + return _VRFCoordinatorTestV25.Contract.Owner(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) Owner() (common.Address, error) { + return _VRFCoordinatorTestV25.Contract.Owner(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) PendingRequestExists(opts *bind.CallOpts, subId *big.Int) (bool, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "pendingRequestExists", subId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) PendingRequestExists(subId *big.Int) (bool, error) { + return _VRFCoordinatorTestV25.Contract.PendingRequestExists(&_VRFCoordinatorTestV25.CallOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) PendingRequestExists(subId *big.Int) (bool, error) { + return _VRFCoordinatorTestV25.Contract.PendingRequestExists(&_VRFCoordinatorTestV25.CallOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) SConfig(opts *bind.CallOpts) (SConfig, + + error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "s_config") + + outstruct := new(SConfig) + if err != nil { + return *outstruct, err + } + + outstruct.MinimumRequestConfirmations = *abi.ConvertType(out[0], new(uint16)).(*uint16) + outstruct.MaxGasLimit = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ReentrancyLock = *abi.ConvertType(out[2], new(bool)).(*bool) + outstruct.StalenessSeconds = *abi.ConvertType(out[3], new(uint32)).(*uint32) + outstruct.GasAfterPaymentCalculation = *abi.ConvertType(out[4], new(uint32)).(*uint32) + outstruct.FulfillmentFlatFeeNativePPM = *abi.ConvertType(out[5], new(uint32)).(*uint32) + outstruct.FulfillmentFlatFeeLinkDiscountPPM = *abi.ConvertType(out[6], new(uint32)).(*uint32) + outstruct.NativePremiumPercentage = *abi.ConvertType(out[7], new(uint8)).(*uint8) + outstruct.LinkPremiumPercentage = *abi.ConvertType(out[8], new(uint8)).(*uint8) + + return *outstruct, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) SConfig() (SConfig, + + error) { + return _VRFCoordinatorTestV25.Contract.SConfig(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) SConfig() (SConfig, + + error) { + return _VRFCoordinatorTestV25.Contract.SConfig(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) SCurrentSubNonce(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "s_currentSubNonce") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) SCurrentSubNonce() (uint64, error) { + return _VRFCoordinatorTestV25.Contract.SCurrentSubNonce(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) SCurrentSubNonce() (uint64, error) { + return _VRFCoordinatorTestV25.Contract.SCurrentSubNonce(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) SFallbackWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "s_fallbackWeiPerUnitLink") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) SFallbackWeiPerUnitLink() (*big.Int, error) { + return _VRFCoordinatorTestV25.Contract.SFallbackWeiPerUnitLink(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) SFallbackWeiPerUnitLink() (*big.Int, error) { + return _VRFCoordinatorTestV25.Contract.SFallbackWeiPerUnitLink(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) SProvingKeyHashes(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "s_provingKeyHashes", arg0) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) SProvingKeyHashes(arg0 *big.Int) ([32]byte, error) { + return _VRFCoordinatorTestV25.Contract.SProvingKeyHashes(&_VRFCoordinatorTestV25.CallOpts, arg0) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) SProvingKeyHashes(arg0 *big.Int) ([32]byte, error) { + return _VRFCoordinatorTestV25.Contract.SProvingKeyHashes(&_VRFCoordinatorTestV25.CallOpts, arg0) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) SProvingKeys(opts *bind.CallOpts, arg0 [32]byte) (SProvingKeys, + + error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "s_provingKeys", arg0) + + outstruct := new(SProvingKeys) + if err != nil { + return *outstruct, err + } + + outstruct.Exists = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.MaxGas = *abi.ConvertType(out[1], new(uint64)).(*uint64) + + return *outstruct, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) SProvingKeys(arg0 [32]byte) (SProvingKeys, + + error) { + return _VRFCoordinatorTestV25.Contract.SProvingKeys(&_VRFCoordinatorTestV25.CallOpts, arg0) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) SProvingKeys(arg0 [32]byte) (SProvingKeys, + + error) { + return _VRFCoordinatorTestV25.Contract.SProvingKeys(&_VRFCoordinatorTestV25.CallOpts, arg0) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) SRequestCommitments(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "s_requestCommitments", arg0) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) SRequestCommitments(arg0 *big.Int) ([32]byte, error) { + return _VRFCoordinatorTestV25.Contract.SRequestCommitments(&_VRFCoordinatorTestV25.CallOpts, arg0) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) SRequestCommitments(arg0 *big.Int) ([32]byte, error) { + return _VRFCoordinatorTestV25.Contract.SRequestCommitments(&_VRFCoordinatorTestV25.CallOpts, arg0) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) STotalBalance(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "s_totalBalance") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) STotalBalance() (*big.Int, error) { + return _VRFCoordinatorTestV25.Contract.STotalBalance(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) STotalBalance() (*big.Int, error) { + return _VRFCoordinatorTestV25.Contract.STotalBalance(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Caller) STotalNativeBalance(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFCoordinatorTestV25.contract.Call(opts, &out, "s_totalNativeBalance") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) STotalNativeBalance() (*big.Int, error) { + return _VRFCoordinatorTestV25.Contract.STotalNativeBalance(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25CallerSession) STotalNativeBalance() (*big.Int, error) { + return _VRFCoordinatorTestV25.Contract.STotalNativeBalance(&_VRFCoordinatorTestV25.CallOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "acceptOwnership") +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) AcceptOwnership() (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.AcceptOwnership(&_VRFCoordinatorTestV25.TransactOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.AcceptOwnership(&_VRFCoordinatorTestV25.TransactOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "acceptSubscriptionOwnerTransfer", subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) AcceptSubscriptionOwnerTransfer(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.AcceptSubscriptionOwnerTransfer(&_VRFCoordinatorTestV25.TransactOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) AcceptSubscriptionOwnerTransfer(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.AcceptSubscriptionOwnerTransfer(&_VRFCoordinatorTestV25.TransactOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) AddConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "addConsumer", subId, consumer) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) AddConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.AddConsumer(&_VRFCoordinatorTestV25.TransactOpts, subId, consumer) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) AddConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.AddConsumer(&_VRFCoordinatorTestV25.TransactOpts, subId, consumer) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) CancelSubscription(opts *bind.TransactOpts, subId *big.Int, to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "cancelSubscription", subId, to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) CancelSubscription(subId *big.Int, to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.CancelSubscription(&_VRFCoordinatorTestV25.TransactOpts, subId, to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) CancelSubscription(subId *big.Int, to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.CancelSubscription(&_VRFCoordinatorTestV25.TransactOpts, subId, to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "createSubscription") +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) CreateSubscription() (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.CreateSubscription(&_VRFCoordinatorTestV25.TransactOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) CreateSubscription() (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.CreateSubscription(&_VRFCoordinatorTestV25.TransactOpts) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) DeregisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "deregisterMigratableCoordinator", target) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) DeregisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.DeregisterMigratableCoordinator(&_VRFCoordinatorTestV25.TransactOpts, target) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) DeregisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.DeregisterMigratableCoordinator(&_VRFCoordinatorTestV25.TransactOpts, target) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) DeregisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "deregisterProvingKey", publicProvingKey) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) DeregisterProvingKey(publicProvingKey [2]*big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.DeregisterProvingKey(&_VRFCoordinatorTestV25.TransactOpts, publicProvingKey) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) DeregisterProvingKey(publicProvingKey [2]*big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.DeregisterProvingKey(&_VRFCoordinatorTestV25.TransactOpts, publicProvingKey) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) FulfillRandomWords(opts *bind.TransactOpts, proof VRFOldProof, rc VRFTypesRequestCommitmentV2Plus, onlyPremium bool) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "fulfillRandomWords", proof, rc, onlyPremium) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) FulfillRandomWords(proof VRFOldProof, rc VRFTypesRequestCommitmentV2Plus, onlyPremium bool) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.FulfillRandomWords(&_VRFCoordinatorTestV25.TransactOpts, proof, rc, onlyPremium) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) FulfillRandomWords(proof VRFOldProof, rc VRFTypesRequestCommitmentV2Plus, onlyPremium bool) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.FulfillRandomWords(&_VRFCoordinatorTestV25.TransactOpts, proof, rc, onlyPremium) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) FundSubscriptionWithNative(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "fundSubscriptionWithNative", subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) FundSubscriptionWithNative(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.FundSubscriptionWithNative(&_VRFCoordinatorTestV25.TransactOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) FundSubscriptionWithNative(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.FundSubscriptionWithNative(&_VRFCoordinatorTestV25.TransactOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) Migrate(opts *bind.TransactOpts, subId *big.Int, newCoordinator common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "migrate", subId, newCoordinator) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) Migrate(subId *big.Int, newCoordinator common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.Migrate(&_VRFCoordinatorTestV25.TransactOpts, subId, newCoordinator) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) Migrate(subId *big.Int, newCoordinator common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.Migrate(&_VRFCoordinatorTestV25.TransactOpts, subId, newCoordinator) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) OnTokenTransfer(opts *bind.TransactOpts, arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "onTokenTransfer", arg0, amount, data) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) OnTokenTransfer(arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.OnTokenTransfer(&_VRFCoordinatorTestV25.TransactOpts, arg0, amount, data) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) OnTokenTransfer(arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.OnTokenTransfer(&_VRFCoordinatorTestV25.TransactOpts, arg0, amount, data) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) OwnerCancelSubscription(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "ownerCancelSubscription", subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) OwnerCancelSubscription(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.OwnerCancelSubscription(&_VRFCoordinatorTestV25.TransactOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) OwnerCancelSubscription(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.OwnerCancelSubscription(&_VRFCoordinatorTestV25.TransactOpts, subId) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) RecoverFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "recoverFunds", to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) RecoverFunds(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RecoverFunds(&_VRFCoordinatorTestV25.TransactOpts, to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) RecoverFunds(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RecoverFunds(&_VRFCoordinatorTestV25.TransactOpts, to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) RecoverNativeFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "recoverNativeFunds", to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) RecoverNativeFunds(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RecoverNativeFunds(&_VRFCoordinatorTestV25.TransactOpts, to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) RecoverNativeFunds(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RecoverNativeFunds(&_VRFCoordinatorTestV25.TransactOpts, to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) RegisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "registerMigratableCoordinator", target) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) RegisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RegisterMigratableCoordinator(&_VRFCoordinatorTestV25.TransactOpts, target) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) RegisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RegisterMigratableCoordinator(&_VRFCoordinatorTestV25.TransactOpts, target) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) RegisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int, maxGas uint64) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "registerProvingKey", publicProvingKey, maxGas) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) RegisterProvingKey(publicProvingKey [2]*big.Int, maxGas uint64) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RegisterProvingKey(&_VRFCoordinatorTestV25.TransactOpts, publicProvingKey, maxGas) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) RegisterProvingKey(publicProvingKey [2]*big.Int, maxGas uint64) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RegisterProvingKey(&_VRFCoordinatorTestV25.TransactOpts, publicProvingKey, maxGas) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) RemoveConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "removeConsumer", subId, consumer) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) RemoveConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RemoveConsumer(&_VRFCoordinatorTestV25.TransactOpts, subId, consumer) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) RemoveConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RemoveConsumer(&_VRFCoordinatorTestV25.TransactOpts, subId, consumer) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) RequestRandomWords(opts *bind.TransactOpts, req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "requestRandomWords", req) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) RequestRandomWords(req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RequestRandomWords(&_VRFCoordinatorTestV25.TransactOpts, req) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) RequestRandomWords(req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RequestRandomWords(&_VRFCoordinatorTestV25.TransactOpts, req) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int, newOwner common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "requestSubscriptionOwnerTransfer", subId, newOwner) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) RequestSubscriptionOwnerTransfer(subId *big.Int, newOwner common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RequestSubscriptionOwnerTransfer(&_VRFCoordinatorTestV25.TransactOpts, subId, newOwner) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) RequestSubscriptionOwnerTransfer(subId *big.Int, newOwner common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.RequestSubscriptionOwnerTransfer(&_VRFCoordinatorTestV25.TransactOpts, subId, newOwner) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) SetConfig(opts *bind.TransactOpts, minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, fulfillmentFlatFeeNativePPM uint32, fulfillmentFlatFeeLinkDiscountPPM uint32, nativePremiumPercentage uint8, linkPremiumPercentage uint8) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "setConfig", minimumRequestConfirmations, maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, fulfillmentFlatFeeNativePPM, fulfillmentFlatFeeLinkDiscountPPM, nativePremiumPercentage, linkPremiumPercentage) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) SetConfig(minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, fulfillmentFlatFeeNativePPM uint32, fulfillmentFlatFeeLinkDiscountPPM uint32, nativePremiumPercentage uint8, linkPremiumPercentage uint8) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.SetConfig(&_VRFCoordinatorTestV25.TransactOpts, minimumRequestConfirmations, maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, fulfillmentFlatFeeNativePPM, fulfillmentFlatFeeLinkDiscountPPM, nativePremiumPercentage, linkPremiumPercentage) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) SetConfig(minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, fulfillmentFlatFeeNativePPM uint32, fulfillmentFlatFeeLinkDiscountPPM uint32, nativePremiumPercentage uint8, linkPremiumPercentage uint8) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.SetConfig(&_VRFCoordinatorTestV25.TransactOpts, minimumRequestConfirmations, maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, fulfillmentFlatFeeNativePPM, fulfillmentFlatFeeLinkDiscountPPM, nativePremiumPercentage, linkPremiumPercentage) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) SetLINKAndLINKNativeFeed(opts *bind.TransactOpts, link common.Address, linkNativeFeed common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "setLINKAndLINKNativeFeed", link, linkNativeFeed) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) SetLINKAndLINKNativeFeed(link common.Address, linkNativeFeed common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.SetLINKAndLINKNativeFeed(&_VRFCoordinatorTestV25.TransactOpts, link, linkNativeFeed) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) SetLINKAndLINKNativeFeed(link common.Address, linkNativeFeed common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.SetLINKAndLINKNativeFeed(&_VRFCoordinatorTestV25.TransactOpts, link, linkNativeFeed) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "transferOwnership", to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.TransferOwnership(&_VRFCoordinatorTestV25.TransactOpts, to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.TransferOwnership(&_VRFCoordinatorTestV25.TransactOpts, to) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) Withdraw(opts *bind.TransactOpts, recipient common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "withdraw", recipient) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) Withdraw(recipient common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.Withdraw(&_VRFCoordinatorTestV25.TransactOpts, recipient) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) Withdraw(recipient common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.Withdraw(&_VRFCoordinatorTestV25.TransactOpts, recipient) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Transactor) WithdrawNative(opts *bind.TransactOpts, recipient common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.contract.Transact(opts, "withdrawNative", recipient) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Session) WithdrawNative(recipient common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.WithdrawNative(&_VRFCoordinatorTestV25.TransactOpts, recipient) +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25TransactorSession) WithdrawNative(recipient common.Address) (*types.Transaction, error) { + return _VRFCoordinatorTestV25.Contract.WithdrawNative(&_VRFCoordinatorTestV25.TransactOpts, recipient) +} + +type VRFCoordinatorTestV25ConfigSetIterator struct { + Event *VRFCoordinatorTestV25ConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25ConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25ConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25ConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25ConfigSetIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25ConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25ConfigSet struct { + MinimumRequestConfirmations uint16 + MaxGasLimit uint32 + StalenessSeconds uint32 + GasAfterPaymentCalculation uint32 + FallbackWeiPerUnitLink *big.Int + FulfillmentFlatFeeNativePPM uint32 + FulfillmentFlatFeeLinkDiscountPPM uint32 + NativePremiumPercentage uint8 + LinkPremiumPercentage uint8 + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterConfigSet(opts *bind.FilterOpts) (*VRFCoordinatorTestV25ConfigSetIterator, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25ConfigSetIterator{contract: _VRFCoordinatorTestV25.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25ConfigSet) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25ConfigSet) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseConfigSet(log types.Log) (*VRFCoordinatorTestV25ConfigSet, error) { + event := new(VRFCoordinatorTestV25ConfigSet) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25CoordinatorDeregisteredIterator struct { + Event *VRFCoordinatorTestV25CoordinatorDeregistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25CoordinatorDeregisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25CoordinatorDeregistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25CoordinatorDeregistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25CoordinatorDeregisteredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25CoordinatorDeregisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25CoordinatorDeregistered struct { + CoordinatorAddress common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterCoordinatorDeregistered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25CoordinatorDeregisteredIterator, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "CoordinatorDeregistered") + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25CoordinatorDeregisteredIterator{contract: _VRFCoordinatorTestV25.contract, event: "CoordinatorDeregistered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchCoordinatorDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25CoordinatorDeregistered) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "CoordinatorDeregistered") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25CoordinatorDeregistered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "CoordinatorDeregistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseCoordinatorDeregistered(log types.Log) (*VRFCoordinatorTestV25CoordinatorDeregistered, error) { + event := new(VRFCoordinatorTestV25CoordinatorDeregistered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "CoordinatorDeregistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25CoordinatorRegisteredIterator struct { + Event *VRFCoordinatorTestV25CoordinatorRegistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25CoordinatorRegisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25CoordinatorRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25CoordinatorRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25CoordinatorRegisteredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25CoordinatorRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25CoordinatorRegistered struct { + CoordinatorAddress common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterCoordinatorRegistered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25CoordinatorRegisteredIterator, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "CoordinatorRegistered") + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25CoordinatorRegisteredIterator{contract: _VRFCoordinatorTestV25.contract, event: "CoordinatorRegistered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchCoordinatorRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25CoordinatorRegistered) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "CoordinatorRegistered") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25CoordinatorRegistered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "CoordinatorRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseCoordinatorRegistered(log types.Log) (*VRFCoordinatorTestV25CoordinatorRegistered, error) { + event := new(VRFCoordinatorTestV25CoordinatorRegistered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "CoordinatorRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsedIterator struct { + Event *VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed struct { + RequestId *big.Int + FallbackWeiPerUnitLink *big.Int + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterFallbackWeiPerUnitLinkUsed(opts *bind.FilterOpts) (*VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsedIterator, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "FallbackWeiPerUnitLinkUsed") + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsedIterator{contract: _VRFCoordinatorTestV25.contract, event: "FallbackWeiPerUnitLinkUsed", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchFallbackWeiPerUnitLinkUsed(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "FallbackWeiPerUnitLinkUsed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "FallbackWeiPerUnitLinkUsed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseFallbackWeiPerUnitLinkUsed(log types.Log) (*VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed, error) { + event := new(VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "FallbackWeiPerUnitLinkUsed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25FundsRecoveredIterator struct { + Event *VRFCoordinatorTestV25FundsRecovered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25FundsRecoveredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25FundsRecovered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25FundsRecovered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25FundsRecoveredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25FundsRecoveredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25FundsRecovered struct { + To common.Address + Amount *big.Int + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25FundsRecoveredIterator, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "FundsRecovered") + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25FundsRecoveredIterator{contract: _VRFCoordinatorTestV25.contract, event: "FundsRecovered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25FundsRecovered) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "FundsRecovered") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25FundsRecovered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "FundsRecovered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseFundsRecovered(log types.Log) (*VRFCoordinatorTestV25FundsRecovered, error) { + event := new(VRFCoordinatorTestV25FundsRecovered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "FundsRecovered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25MigrationCompletedIterator struct { + Event *VRFCoordinatorTestV25MigrationCompleted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25MigrationCompletedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25MigrationCompleted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25MigrationCompleted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25MigrationCompletedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25MigrationCompletedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25MigrationCompleted struct { + NewCoordinator common.Address + SubId *big.Int + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterMigrationCompleted(opts *bind.FilterOpts) (*VRFCoordinatorTestV25MigrationCompletedIterator, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "MigrationCompleted") + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25MigrationCompletedIterator{contract: _VRFCoordinatorTestV25.contract, event: "MigrationCompleted", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchMigrationCompleted(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25MigrationCompleted) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "MigrationCompleted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25MigrationCompleted) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "MigrationCompleted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseMigrationCompleted(log types.Log) (*VRFCoordinatorTestV25MigrationCompleted, error) { + event := new(VRFCoordinatorTestV25MigrationCompleted) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "MigrationCompleted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25NativeFundsRecoveredIterator struct { + Event *VRFCoordinatorTestV25NativeFundsRecovered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25NativeFundsRecoveredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25NativeFundsRecovered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25NativeFundsRecovered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25NativeFundsRecoveredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25NativeFundsRecoveredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25NativeFundsRecovered struct { + To common.Address + Amount *big.Int + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterNativeFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25NativeFundsRecoveredIterator, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "NativeFundsRecovered") + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25NativeFundsRecoveredIterator{contract: _VRFCoordinatorTestV25.contract, event: "NativeFundsRecovered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchNativeFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25NativeFundsRecovered) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "NativeFundsRecovered") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25NativeFundsRecovered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "NativeFundsRecovered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseNativeFundsRecovered(log types.Log) (*VRFCoordinatorTestV25NativeFundsRecovered, error) { + event := new(VRFCoordinatorTestV25NativeFundsRecovered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "NativeFundsRecovered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25OwnershipTransferRequestedIterator struct { + Event *VRFCoordinatorTestV25OwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25OwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25OwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25OwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25OwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25OwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25OwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorTestV25OwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25OwnershipTransferRequestedIterator{contract: _VRFCoordinatorTestV25.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25OwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25OwnershipTransferRequested) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseOwnershipTransferRequested(log types.Log) (*VRFCoordinatorTestV25OwnershipTransferRequested, error) { + event := new(VRFCoordinatorTestV25OwnershipTransferRequested) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25OwnershipTransferredIterator struct { + Event *VRFCoordinatorTestV25OwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25OwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25OwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25OwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25OwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25OwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25OwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorTestV25OwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25OwnershipTransferredIterator{contract: _VRFCoordinatorTestV25.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25OwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25OwnershipTransferred) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseOwnershipTransferred(log types.Log) (*VRFCoordinatorTestV25OwnershipTransferred, error) { + event := new(VRFCoordinatorTestV25OwnershipTransferred) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25ProvingKeyDeregisteredIterator struct { + Event *VRFCoordinatorTestV25ProvingKeyDeregistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25ProvingKeyDeregisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25ProvingKeyDeregistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25ProvingKeyDeregistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25ProvingKeyDeregisteredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25ProvingKeyDeregisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25ProvingKeyDeregistered struct { + KeyHash [32]byte + MaxGas uint64 + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterProvingKeyDeregistered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25ProvingKeyDeregisteredIterator, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "ProvingKeyDeregistered") + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25ProvingKeyDeregisteredIterator{contract: _VRFCoordinatorTestV25.contract, event: "ProvingKeyDeregistered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchProvingKeyDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25ProvingKeyDeregistered) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "ProvingKeyDeregistered") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25ProvingKeyDeregistered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "ProvingKeyDeregistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseProvingKeyDeregistered(log types.Log) (*VRFCoordinatorTestV25ProvingKeyDeregistered, error) { + event := new(VRFCoordinatorTestV25ProvingKeyDeregistered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "ProvingKeyDeregistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25ProvingKeyRegisteredIterator struct { + Event *VRFCoordinatorTestV25ProvingKeyRegistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25ProvingKeyRegisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25ProvingKeyRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25ProvingKeyRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25ProvingKeyRegisteredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25ProvingKeyRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25ProvingKeyRegistered struct { + KeyHash [32]byte + MaxGas uint64 + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterProvingKeyRegistered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25ProvingKeyRegisteredIterator, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "ProvingKeyRegistered") + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25ProvingKeyRegisteredIterator{contract: _VRFCoordinatorTestV25.contract, event: "ProvingKeyRegistered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchProvingKeyRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25ProvingKeyRegistered) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "ProvingKeyRegistered") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25ProvingKeyRegistered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "ProvingKeyRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseProvingKeyRegistered(log types.Log) (*VRFCoordinatorTestV25ProvingKeyRegistered, error) { + event := new(VRFCoordinatorTestV25ProvingKeyRegistered) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "ProvingKeyRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25RandomWordsFulfilledIterator struct { + Event *VRFCoordinatorTestV25RandomWordsFulfilled + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25RandomWordsFulfilledIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25RandomWordsFulfilled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25RandomWordsFulfilled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25RandomWordsFulfilledIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25RandomWordsFulfilledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25RandomWordsFulfilled struct { + RequestId *big.Int + OutputSeed *big.Int + SubId *big.Int + Payment *big.Int + NativePayment bool + Success bool + OnlyPremium bool + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subId []*big.Int) (*VRFCoordinatorTestV25RandomWordsFulfilledIterator, error) { + + var requestIdRule []interface{} + for _, requestIdItem := range requestId { + requestIdRule = append(requestIdRule, requestIdItem) + } + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "RandomWordsFulfilled", requestIdRule, subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25RandomWordsFulfilledIterator{contract: _VRFCoordinatorTestV25.contract, event: "RandomWordsFulfilled", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25RandomWordsFulfilled, requestId []*big.Int, subId []*big.Int) (event.Subscription, error) { + + var requestIdRule []interface{} + for _, requestIdItem := range requestId { + requestIdRule = append(requestIdRule, requestIdItem) + } + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "RandomWordsFulfilled", requestIdRule, subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25RandomWordsFulfilled) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "RandomWordsFulfilled", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseRandomWordsFulfilled(log types.Log) (*VRFCoordinatorTestV25RandomWordsFulfilled, error) { + event := new(VRFCoordinatorTestV25RandomWordsFulfilled) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "RandomWordsFulfilled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25RandomWordsRequestedIterator struct { + Event *VRFCoordinatorTestV25RandomWordsRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25RandomWordsRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25RandomWordsRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25RandomWordsRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25RandomWordsRequestedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25RandomWordsRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25RandomWordsRequested struct { + KeyHash [32]byte + RequestId *big.Int + PreSeed *big.Int + SubId *big.Int + MinimumRequestConfirmations uint16 + CallbackGasLimit uint32 + NumWords uint32 + ExtraArgs []byte + Sender common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterRandomWordsRequested(opts *bind.FilterOpts, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (*VRFCoordinatorTestV25RandomWordsRequestedIterator, error) { + + var keyHashRule []interface{} + for _, keyHashItem := range keyHash { + keyHashRule = append(keyHashRule, keyHashItem) + } + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "RandomWordsRequested", keyHashRule, subIdRule, senderRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25RandomWordsRequestedIterator{contract: _VRFCoordinatorTestV25.contract, event: "RandomWordsRequested", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchRandomWordsRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25RandomWordsRequested, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (event.Subscription, error) { + + var keyHashRule []interface{} + for _, keyHashItem := range keyHash { + keyHashRule = append(keyHashRule, keyHashItem) + } + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "RandomWordsRequested", keyHashRule, subIdRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25RandomWordsRequested) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "RandomWordsRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseRandomWordsRequested(log types.Log) (*VRFCoordinatorTestV25RandomWordsRequested, error) { + event := new(VRFCoordinatorTestV25RandomWordsRequested) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "RandomWordsRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25SubscriptionCanceledIterator struct { + Event *VRFCoordinatorTestV25SubscriptionCanceled + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25SubscriptionCanceledIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionCanceled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionCanceled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25SubscriptionCanceledIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25SubscriptionCanceledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25SubscriptionCanceled struct { + SubId *big.Int + To common.Address + AmountLink *big.Int + AmountNative *big.Int + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterSubscriptionCanceled(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionCanceledIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "SubscriptionCanceled", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25SubscriptionCanceledIterator{contract: _VRFCoordinatorTestV25.contract, event: "SubscriptionCanceled", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionCanceled, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "SubscriptionCanceled", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25SubscriptionCanceled) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionCanceled", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseSubscriptionCanceled(log types.Log) (*VRFCoordinatorTestV25SubscriptionCanceled, error) { + event := new(VRFCoordinatorTestV25SubscriptionCanceled) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionCanceled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25SubscriptionConsumerAddedIterator struct { + Event *VRFCoordinatorTestV25SubscriptionConsumerAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25SubscriptionConsumerAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionConsumerAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionConsumerAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25SubscriptionConsumerAddedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25SubscriptionConsumerAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25SubscriptionConsumerAdded struct { + SubId *big.Int + Consumer common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionConsumerAddedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "SubscriptionConsumerAdded", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25SubscriptionConsumerAddedIterator{contract: _VRFCoordinatorTestV25.contract, event: "SubscriptionConsumerAdded", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionConsumerAdded, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "SubscriptionConsumerAdded", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25SubscriptionConsumerAdded) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionConsumerAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseSubscriptionConsumerAdded(log types.Log) (*VRFCoordinatorTestV25SubscriptionConsumerAdded, error) { + event := new(VRFCoordinatorTestV25SubscriptionConsumerAdded) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionConsumerAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25SubscriptionConsumerRemovedIterator struct { + Event *VRFCoordinatorTestV25SubscriptionConsumerRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25SubscriptionConsumerRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionConsumerRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionConsumerRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25SubscriptionConsumerRemovedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25SubscriptionConsumerRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25SubscriptionConsumerRemoved struct { + SubId *big.Int + Consumer common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionConsumerRemovedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "SubscriptionConsumerRemoved", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25SubscriptionConsumerRemovedIterator{contract: _VRFCoordinatorTestV25.contract, event: "SubscriptionConsumerRemoved", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionConsumerRemoved, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "SubscriptionConsumerRemoved", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25SubscriptionConsumerRemoved) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionConsumerRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseSubscriptionConsumerRemoved(log types.Log) (*VRFCoordinatorTestV25SubscriptionConsumerRemoved, error) { + event := new(VRFCoordinatorTestV25SubscriptionConsumerRemoved) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionConsumerRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25SubscriptionCreatedIterator struct { + Event *VRFCoordinatorTestV25SubscriptionCreated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25SubscriptionCreatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25SubscriptionCreatedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25SubscriptionCreatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25SubscriptionCreated struct { + SubId *big.Int + Owner common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterSubscriptionCreated(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionCreatedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "SubscriptionCreated", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25SubscriptionCreatedIterator{contract: _VRFCoordinatorTestV25.contract, event: "SubscriptionCreated", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionCreated, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "SubscriptionCreated", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25SubscriptionCreated) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionCreated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseSubscriptionCreated(log types.Log) (*VRFCoordinatorTestV25SubscriptionCreated, error) { + event := new(VRFCoordinatorTestV25SubscriptionCreated) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionCreated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25SubscriptionFundedIterator struct { + Event *VRFCoordinatorTestV25SubscriptionFunded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25SubscriptionFundedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionFunded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionFunded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25SubscriptionFundedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25SubscriptionFundedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25SubscriptionFunded struct { + SubId *big.Int + OldBalance *big.Int + NewBalance *big.Int + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterSubscriptionFunded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionFundedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "SubscriptionFunded", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25SubscriptionFundedIterator{contract: _VRFCoordinatorTestV25.contract, event: "SubscriptionFunded", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionFunded, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "SubscriptionFunded", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25SubscriptionFunded) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionFunded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseSubscriptionFunded(log types.Log) (*VRFCoordinatorTestV25SubscriptionFunded, error) { + event := new(VRFCoordinatorTestV25SubscriptionFunded) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionFunded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25SubscriptionFundedWithNativeIterator struct { + Event *VRFCoordinatorTestV25SubscriptionFundedWithNative + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25SubscriptionFundedWithNativeIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionFundedWithNative) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionFundedWithNative) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25SubscriptionFundedWithNativeIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25SubscriptionFundedWithNativeIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25SubscriptionFundedWithNative struct { + SubId *big.Int + OldNativeBalance *big.Int + NewNativeBalance *big.Int + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterSubscriptionFundedWithNative(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionFundedWithNativeIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "SubscriptionFundedWithNative", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25SubscriptionFundedWithNativeIterator{contract: _VRFCoordinatorTestV25.contract, event: "SubscriptionFundedWithNative", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchSubscriptionFundedWithNative(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionFundedWithNative, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "SubscriptionFundedWithNative", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25SubscriptionFundedWithNative) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionFundedWithNative", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseSubscriptionFundedWithNative(log types.Log) (*VRFCoordinatorTestV25SubscriptionFundedWithNative, error) { + event := new(VRFCoordinatorTestV25SubscriptionFundedWithNative) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionFundedWithNative", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25SubscriptionOwnerTransferRequestedIterator struct { + Event *VRFCoordinatorTestV25SubscriptionOwnerTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25SubscriptionOwnerTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionOwnerTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionOwnerTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25SubscriptionOwnerTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25SubscriptionOwnerTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25SubscriptionOwnerTransferRequested struct { + SubId *big.Int + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionOwnerTransferRequestedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "SubscriptionOwnerTransferRequested", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25SubscriptionOwnerTransferRequestedIterator{contract: _VRFCoordinatorTestV25.contract, event: "SubscriptionOwnerTransferRequested", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionOwnerTransferRequested, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "SubscriptionOwnerTransferRequested", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25SubscriptionOwnerTransferRequested) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionOwnerTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseSubscriptionOwnerTransferRequested(log types.Log) (*VRFCoordinatorTestV25SubscriptionOwnerTransferRequested, error) { + event := new(VRFCoordinatorTestV25SubscriptionOwnerTransferRequested) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionOwnerTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorTestV25SubscriptionOwnerTransferredIterator struct { + Event *VRFCoordinatorTestV25SubscriptionOwnerTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorTestV25SubscriptionOwnerTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionOwnerTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorTestV25SubscriptionOwnerTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorTestV25SubscriptionOwnerTransferredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorTestV25SubscriptionOwnerTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorTestV25SubscriptionOwnerTransferred struct { + SubId *big.Int + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionOwnerTransferredIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.FilterLogs(opts, "SubscriptionOwnerTransferred", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorTestV25SubscriptionOwnerTransferredIterator{contract: _VRFCoordinatorTestV25.contract, event: "SubscriptionOwnerTransferred", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionOwnerTransferred, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorTestV25.contract.WatchLogs(opts, "SubscriptionOwnerTransferred", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorTestV25SubscriptionOwnerTransferred) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionOwnerTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25Filterer) ParseSubscriptionOwnerTransferred(log types.Log) (*VRFCoordinatorTestV25SubscriptionOwnerTransferred, error) { + event := new(VRFCoordinatorTestV25SubscriptionOwnerTransferred) + if err := _VRFCoordinatorTestV25.contract.UnpackLog(event, "SubscriptionOwnerTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetSubscription struct { + Balance *big.Int + NativeBalance *big.Int + ReqCount uint64 + SubOwner common.Address + Consumers []common.Address +} +type SConfig struct { + MinimumRequestConfirmations uint16 + MaxGasLimit uint32 + ReentrancyLock bool + StalenessSeconds uint32 + GasAfterPaymentCalculation uint32 + FulfillmentFlatFeeNativePPM uint32 + FulfillmentFlatFeeLinkDiscountPPM uint32 + NativePremiumPercentage uint8 + LinkPremiumPercentage uint8 +} +type SProvingKeys struct { + Exists bool + MaxGas uint64 +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _VRFCoordinatorTestV25.abi.Events["ConfigSet"].ID: + return _VRFCoordinatorTestV25.ParseConfigSet(log) + case _VRFCoordinatorTestV25.abi.Events["CoordinatorDeregistered"].ID: + return _VRFCoordinatorTestV25.ParseCoordinatorDeregistered(log) + case _VRFCoordinatorTestV25.abi.Events["CoordinatorRegistered"].ID: + return _VRFCoordinatorTestV25.ParseCoordinatorRegistered(log) + case _VRFCoordinatorTestV25.abi.Events["FallbackWeiPerUnitLinkUsed"].ID: + return _VRFCoordinatorTestV25.ParseFallbackWeiPerUnitLinkUsed(log) + case _VRFCoordinatorTestV25.abi.Events["FundsRecovered"].ID: + return _VRFCoordinatorTestV25.ParseFundsRecovered(log) + case _VRFCoordinatorTestV25.abi.Events["MigrationCompleted"].ID: + return _VRFCoordinatorTestV25.ParseMigrationCompleted(log) + case _VRFCoordinatorTestV25.abi.Events["NativeFundsRecovered"].ID: + return _VRFCoordinatorTestV25.ParseNativeFundsRecovered(log) + case _VRFCoordinatorTestV25.abi.Events["OwnershipTransferRequested"].ID: + return _VRFCoordinatorTestV25.ParseOwnershipTransferRequested(log) + case _VRFCoordinatorTestV25.abi.Events["OwnershipTransferred"].ID: + return _VRFCoordinatorTestV25.ParseOwnershipTransferred(log) + case _VRFCoordinatorTestV25.abi.Events["ProvingKeyDeregistered"].ID: + return _VRFCoordinatorTestV25.ParseProvingKeyDeregistered(log) + case _VRFCoordinatorTestV25.abi.Events["ProvingKeyRegistered"].ID: + return _VRFCoordinatorTestV25.ParseProvingKeyRegistered(log) + case _VRFCoordinatorTestV25.abi.Events["RandomWordsFulfilled"].ID: + return _VRFCoordinatorTestV25.ParseRandomWordsFulfilled(log) + case _VRFCoordinatorTestV25.abi.Events["RandomWordsRequested"].ID: + return _VRFCoordinatorTestV25.ParseRandomWordsRequested(log) + case _VRFCoordinatorTestV25.abi.Events["SubscriptionCanceled"].ID: + return _VRFCoordinatorTestV25.ParseSubscriptionCanceled(log) + case _VRFCoordinatorTestV25.abi.Events["SubscriptionConsumerAdded"].ID: + return _VRFCoordinatorTestV25.ParseSubscriptionConsumerAdded(log) + case _VRFCoordinatorTestV25.abi.Events["SubscriptionConsumerRemoved"].ID: + return _VRFCoordinatorTestV25.ParseSubscriptionConsumerRemoved(log) + case _VRFCoordinatorTestV25.abi.Events["SubscriptionCreated"].ID: + return _VRFCoordinatorTestV25.ParseSubscriptionCreated(log) + case _VRFCoordinatorTestV25.abi.Events["SubscriptionFunded"].ID: + return _VRFCoordinatorTestV25.ParseSubscriptionFunded(log) + case _VRFCoordinatorTestV25.abi.Events["SubscriptionFundedWithNative"].ID: + return _VRFCoordinatorTestV25.ParseSubscriptionFundedWithNative(log) + case _VRFCoordinatorTestV25.abi.Events["SubscriptionOwnerTransferRequested"].ID: + return _VRFCoordinatorTestV25.ParseSubscriptionOwnerTransferRequested(log) + case _VRFCoordinatorTestV25.abi.Events["SubscriptionOwnerTransferred"].ID: + return _VRFCoordinatorTestV25.ParseSubscriptionOwnerTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (VRFCoordinatorTestV25ConfigSet) Topic() common.Hash { + return common.HexToHash("0x2c6b6b12413678366b05b145c5f00745bdd00e739131ab5de82484a50c9d78b6") +} + +func (VRFCoordinatorTestV25CoordinatorDeregistered) Topic() common.Hash { + return common.HexToHash("0xf80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af37") +} + +func (VRFCoordinatorTestV25CoordinatorRegistered) Topic() common.Hash { + return common.HexToHash("0xb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af01625") +} + +func (VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed) Topic() common.Hash { + return common.HexToHash("0x6ca648a381f22ead7e37773d934e64885dcf861fbfbb26c40354cbf0c4662d1a") +} + +func (VRFCoordinatorTestV25FundsRecovered) Topic() common.Hash { + return common.HexToHash("0x59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600") +} + +func (VRFCoordinatorTestV25MigrationCompleted) Topic() common.Hash { + return common.HexToHash("0xd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187") +} + +func (VRFCoordinatorTestV25NativeFundsRecovered) Topic() common.Hash { + return common.HexToHash("0x4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c") +} + +func (VRFCoordinatorTestV25OwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (VRFCoordinatorTestV25OwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (VRFCoordinatorTestV25ProvingKeyDeregistered) Topic() common.Hash { + return common.HexToHash("0x9b6868e0eb737bcd72205360baa6bfd0ba4e4819a33ade2db384e8a8025639a5") +} + +func (VRFCoordinatorTestV25ProvingKeyRegistered) Topic() common.Hash { + return common.HexToHash("0x9b911b2c240bfbef3b6a8f7ed6ee321d1258bb2a3fe6becab52ac1cd3210afd3") +} + +func (VRFCoordinatorTestV25RandomWordsFulfilled) Topic() common.Hash { + return common.HexToHash("0xaeb4b4786571e184246d39587f659abf0e26f41f6a3358692250382c0cdb47b7") +} + +func (VRFCoordinatorTestV25RandomWordsRequested) Topic() common.Hash { + return common.HexToHash("0xeb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e") +} + +func (VRFCoordinatorTestV25SubscriptionCanceled) Topic() common.Hash { + return common.HexToHash("0x8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4") +} + +func (VRFCoordinatorTestV25SubscriptionConsumerAdded) Topic() common.Hash { + return common.HexToHash("0x1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e1") +} + +func (VRFCoordinatorTestV25SubscriptionConsumerRemoved) Topic() common.Hash { + return common.HexToHash("0x32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a7") +} + +func (VRFCoordinatorTestV25SubscriptionCreated) Topic() common.Hash { + return common.HexToHash("0x1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d") +} + +func (VRFCoordinatorTestV25SubscriptionFunded) Topic() common.Hash { + return common.HexToHash("0x1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a") +} + +func (VRFCoordinatorTestV25SubscriptionFundedWithNative) Topic() common.Hash { + return common.HexToHash("0x7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e902") +} + +func (VRFCoordinatorTestV25SubscriptionOwnerTransferRequested) Topic() common.Hash { + return common.HexToHash("0x21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a1") +} + +func (VRFCoordinatorTestV25SubscriptionOwnerTransferred) Topic() common.Hash { + return common.HexToHash("0xd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c9386") +} + +func (_VRFCoordinatorTestV25 *VRFCoordinatorTestV25) Address() common.Address { + return _VRFCoordinatorTestV25.address +} + +type VRFCoordinatorTestV25Interface interface { + BLOCKHASHSTORE(opts *bind.CallOpts) (common.Address, error) + + LINK(opts *bind.CallOpts) (common.Address, error) + + LINKNATIVEFEED(opts *bind.CallOpts) (common.Address, error) + + MAXCONSUMERS(opts *bind.CallOpts) (uint16, error) + + MAXNUMWORDS(opts *bind.CallOpts) (uint32, error) + + MAXREQUESTCONFIRMATIONS(opts *bind.CallOpts) (uint16, error) + + GetActiveSubscriptionIds(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) + + GetSubscription(opts *bind.CallOpts, subId *big.Int) (GetSubscription, + + error) + + HashOfKey(opts *bind.CallOpts, publicKey [2]*big.Int) ([32]byte, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + PendingRequestExists(opts *bind.CallOpts, subId *big.Int) (bool, error) + + SConfig(opts *bind.CallOpts) (SConfig, + + error) + + SCurrentSubNonce(opts *bind.CallOpts) (uint64, error) + + SFallbackWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) + + SProvingKeyHashes(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) + + SProvingKeys(opts *bind.CallOpts, arg0 [32]byte) (SProvingKeys, + + error) + + SRequestCommitments(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) + + STotalBalance(opts *bind.CallOpts) (*big.Int, error) + + STotalNativeBalance(opts *bind.CallOpts) (*big.Int, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) + + AddConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) + + CancelSubscription(opts *bind.TransactOpts, subId *big.Int, to common.Address) (*types.Transaction, error) + + CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) + + DeregisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) + + DeregisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int) (*types.Transaction, error) + + FulfillRandomWords(opts *bind.TransactOpts, proof VRFOldProof, rc VRFTypesRequestCommitmentV2Plus, onlyPremium bool) (*types.Transaction, error) + + FundSubscriptionWithNative(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) + + Migrate(opts *bind.TransactOpts, subId *big.Int, newCoordinator common.Address) (*types.Transaction, error) + + OnTokenTransfer(opts *bind.TransactOpts, arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) + + OwnerCancelSubscription(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) + + RecoverFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + RecoverNativeFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + RegisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) + + RegisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int, maxGas uint64) (*types.Transaction, error) + + RemoveConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) + + RequestRandomWords(opts *bind.TransactOpts, req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) + + RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int, newOwner common.Address) (*types.Transaction, error) + + SetConfig(opts *bind.TransactOpts, minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, fulfillmentFlatFeeNativePPM uint32, fulfillmentFlatFeeLinkDiscountPPM uint32, nativePremiumPercentage uint8, linkPremiumPercentage uint8) (*types.Transaction, error) + + SetLINKAndLINKNativeFeed(opts *bind.TransactOpts, link common.Address, linkNativeFeed common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Withdraw(opts *bind.TransactOpts, recipient common.Address) (*types.Transaction, error) + + WithdrawNative(opts *bind.TransactOpts, recipient common.Address) (*types.Transaction, error) + + FilterConfigSet(opts *bind.FilterOpts) (*VRFCoordinatorTestV25ConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25ConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*VRFCoordinatorTestV25ConfigSet, error) + + FilterCoordinatorDeregistered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25CoordinatorDeregisteredIterator, error) + + WatchCoordinatorDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25CoordinatorDeregistered) (event.Subscription, error) + + ParseCoordinatorDeregistered(log types.Log) (*VRFCoordinatorTestV25CoordinatorDeregistered, error) + + FilterCoordinatorRegistered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25CoordinatorRegisteredIterator, error) + + WatchCoordinatorRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25CoordinatorRegistered) (event.Subscription, error) + + ParseCoordinatorRegistered(log types.Log) (*VRFCoordinatorTestV25CoordinatorRegistered, error) + + FilterFallbackWeiPerUnitLinkUsed(opts *bind.FilterOpts) (*VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsedIterator, error) + + WatchFallbackWeiPerUnitLinkUsed(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed) (event.Subscription, error) + + ParseFallbackWeiPerUnitLinkUsed(log types.Log) (*VRFCoordinatorTestV25FallbackWeiPerUnitLinkUsed, error) + + FilterFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25FundsRecoveredIterator, error) + + WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25FundsRecovered) (event.Subscription, error) + + ParseFundsRecovered(log types.Log) (*VRFCoordinatorTestV25FundsRecovered, error) + + FilterMigrationCompleted(opts *bind.FilterOpts) (*VRFCoordinatorTestV25MigrationCompletedIterator, error) + + WatchMigrationCompleted(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25MigrationCompleted) (event.Subscription, error) + + ParseMigrationCompleted(log types.Log) (*VRFCoordinatorTestV25MigrationCompleted, error) + + FilterNativeFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25NativeFundsRecoveredIterator, error) + + WatchNativeFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25NativeFundsRecovered) (event.Subscription, error) + + ParseNativeFundsRecovered(log types.Log) (*VRFCoordinatorTestV25NativeFundsRecovered, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorTestV25OwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25OwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*VRFCoordinatorTestV25OwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorTestV25OwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25OwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*VRFCoordinatorTestV25OwnershipTransferred, error) + + FilterProvingKeyDeregistered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25ProvingKeyDeregisteredIterator, error) + + WatchProvingKeyDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25ProvingKeyDeregistered) (event.Subscription, error) + + ParseProvingKeyDeregistered(log types.Log) (*VRFCoordinatorTestV25ProvingKeyDeregistered, error) + + FilterProvingKeyRegistered(opts *bind.FilterOpts) (*VRFCoordinatorTestV25ProvingKeyRegisteredIterator, error) + + WatchProvingKeyRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25ProvingKeyRegistered) (event.Subscription, error) + + ParseProvingKeyRegistered(log types.Log) (*VRFCoordinatorTestV25ProvingKeyRegistered, error) + + FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subId []*big.Int) (*VRFCoordinatorTestV25RandomWordsFulfilledIterator, error) + + WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25RandomWordsFulfilled, requestId []*big.Int, subId []*big.Int) (event.Subscription, error) + + ParseRandomWordsFulfilled(log types.Log) (*VRFCoordinatorTestV25RandomWordsFulfilled, error) + + FilterRandomWordsRequested(opts *bind.FilterOpts, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (*VRFCoordinatorTestV25RandomWordsRequestedIterator, error) + + WatchRandomWordsRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25RandomWordsRequested, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (event.Subscription, error) + + ParseRandomWordsRequested(log types.Log) (*VRFCoordinatorTestV25RandomWordsRequested, error) + + FilterSubscriptionCanceled(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionCanceledIterator, error) + + WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionCanceled, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionCanceled(log types.Log) (*VRFCoordinatorTestV25SubscriptionCanceled, error) + + FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionConsumerAddedIterator, error) + + WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionConsumerAdded, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionConsumerAdded(log types.Log) (*VRFCoordinatorTestV25SubscriptionConsumerAdded, error) + + FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionConsumerRemovedIterator, error) + + WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionConsumerRemoved, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionConsumerRemoved(log types.Log) (*VRFCoordinatorTestV25SubscriptionConsumerRemoved, error) + + FilterSubscriptionCreated(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionCreatedIterator, error) + + WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionCreated, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionCreated(log types.Log) (*VRFCoordinatorTestV25SubscriptionCreated, error) + + FilterSubscriptionFunded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionFundedIterator, error) + + WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionFunded, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionFunded(log types.Log) (*VRFCoordinatorTestV25SubscriptionFunded, error) + + FilterSubscriptionFundedWithNative(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionFundedWithNativeIterator, error) + + WatchSubscriptionFundedWithNative(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionFundedWithNative, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionFundedWithNative(log types.Log) (*VRFCoordinatorTestV25SubscriptionFundedWithNative, error) + + FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionOwnerTransferRequestedIterator, error) + + WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionOwnerTransferRequested, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionOwnerTransferRequested(log types.Log) (*VRFCoordinatorTestV25SubscriptionOwnerTransferRequested, error) + + FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorTestV25SubscriptionOwnerTransferredIterator, error) + + WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorTestV25SubscriptionOwnerTransferred, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionOwnerTransferred(log types.Log) (*VRFCoordinatorTestV25SubscriptionOwnerTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 8862fef8c8c..c363892b9dc 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -82,6 +82,7 @@ vrf_consumer_v2_plus_upgradeable_example: ../../contracts/solc/v0.8.19/VRFConsum vrf_consumer_v2_upgradeable_example: ../../contracts/solc/v0.8.6/VRFConsumerV2UpgradeableExample/VRFConsumerV2UpgradeableExample.abi ../../contracts/solc/v0.8.6/VRFConsumerV2UpgradeableExample/VRFConsumerV2UpgradeableExample.bin f1790a9a2f2a04c730593e483459709cb89e897f8a19d7a3ac0cfe6a97265e6e vrf_coordinator_mock: ../../contracts/solc/v0.8.6/VRFCoordinatorMock/VRFCoordinatorMock.abi ../../contracts/solc/v0.8.6/VRFCoordinatorMock/VRFCoordinatorMock.bin 5c495cf8df1f46d8736b9150cdf174cce358cb8352f60f0d5bb9581e23920501 vrf_coordinator_test_v2: ../../contracts/solc/v0.8.6/VRFCoordinatorTestV2/VRFCoordinatorTestV2.abi ../../contracts/solc/v0.8.6/VRFCoordinatorTestV2/VRFCoordinatorTestV2.bin ff6c0056c6181ea75f667beed21ff4610f417dd50ceabf2dec8fa42e84851f50 +vrf_coordinator_test_v2_5: ../../contracts/solc/v0.8.19/VRFCoordinatorTestV2_5/VRFCoordinatorTestV2_5.abi ../../contracts/solc/v0.8.19/VRFCoordinatorTestV2_5/VRFCoordinatorTestV2_5.bin ab793e7d72b2d10d5c80b5358ca98caf5ff8a8686700735b198ed811272d7910 vrf_coordinator_v2: ../../contracts/solc/v0.8.6/VRFCoordinatorV2/VRFCoordinatorV2.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2/VRFCoordinatorV2.bin 156fbbc19489383901087c2076648ccd343bcd9a332f1ad25974da834c5be961 vrf_coordinator_v2_5: ../../contracts/solc/v0.8.19/VRFCoordinatorV2_5/VRFCoordinatorV2_5.abi ../../contracts/solc/v0.8.19/VRFCoordinatorV2_5/VRFCoordinatorV2_5.bin 3c766dbdefcc895ad475de96c65b6c48c868b8dc889ee750bba6711b1e5ec41d vrf_coordinator_v2_5_arbitrum: ../../contracts/solc/v0.8.19/VRFCoordinatorV2_5_Arbitrum/VRFCoordinatorV2_5_Arbitrum.abi ../../contracts/solc/v0.8.19/VRFCoordinatorV2_5_Arbitrum/VRFCoordinatorV2_5_Arbitrum.bin 1a2431ee76e307b45f683c439d08b9096a08f08aaf9ca132ea5b36b409962abe diff --git a/core/gethwrappers/go_generate.go b/core/gethwrappers/go_generate.go index d877c7a8dbb..32db02f2bf7 100644 --- a/core/gethwrappers/go_generate.go +++ b/core/gethwrappers/go_generate.go @@ -143,6 +143,7 @@ package gethwrappers //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/VRFCoordinatorV2_5_Optimism/VRFCoordinatorV2_5_Optimism.abi ../../contracts/solc/v0.8.19/VRFCoordinatorV2_5_Optimism/VRFCoordinatorV2_5_Optimism.bin VRFCoordinatorV2_5_Optimism vrf_coordinator_v2_5_optimism //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/VRFV2PlusWrapper_Arbitrum/VRFV2PlusWrapper_Arbitrum.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapper_Arbitrum/VRFV2PlusWrapper_Arbitrum.bin VRFV2PlusWrapper_Arbitrum vrfv2plus_wrapper_arbitrum //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/VRFV2PlusWrapper_Optimism/VRFV2PlusWrapper_Optimism.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapper_Optimism/VRFV2PlusWrapper_Optimism.bin VRFV2PlusWrapper_Optimism vrfv2plus_wrapper_optimism +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/VRFCoordinatorTestV2_5/VRFCoordinatorTestV2_5.abi ../../contracts/solc/v0.8.19/VRFCoordinatorTestV2_5/VRFCoordinatorTestV2_5.bin VRFCoordinatorTestV2_5 vrf_coordinator_test_v2_5 // Aggregators //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/AggregatorV2V3Interface/AggregatorV2V3Interface.abi ../../contracts/solc/v0.8.6/AggregatorV2V3Interface/AggregatorV2V3Interface.bin AggregatorV2V3Interface aggregator_v2v3_interface diff --git a/integration-tests/actions/actions.go b/integration-tests/actions/actions.go index b274b59416b..ae4d62ddb33 100644 --- a/integration-tests/actions/actions.go +++ b/integration-tests/actions/actions.go @@ -1243,6 +1243,11 @@ func IsOPStackChain(chainID int64) bool { chainID == 11155420 //OPTIMISM SEPOLIA } +func IsArbitrumChain(chainID int64) bool { + return chainID == 42161 || //Arbitrum MAINNET + chainID == 421614 //Arbitrum Sepolia +} + func RandBool() bool { return rand.Intn(2) == 1 } diff --git a/integration-tests/actions/vrf/vrfv2/setup_steps.go b/integration-tests/actions/vrf/vrfv2/setup_steps.go index c025a563046..0e0b68e6402 100644 --- a/integration-tests/actions/vrf/vrfv2/setup_steps.go +++ b/integration-tests/actions/vrf/vrfv2/setup_steps.go @@ -42,7 +42,7 @@ func CreateVRFV2Job( } ost, err := os.String() if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrParseJob, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrParseJob, err) } spec := &client.VRFV2JobSpec{ @@ -69,7 +69,7 @@ func CreateVRFV2Job( } job, err := chainlinkNode.MustCreateJob(spec) if err != nil { - return nil, fmt.Errorf("%s, err %w", ErrCreatingVRFv2Job, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrCreatingVRFv2Job, err) } return job, nil } @@ -113,15 +113,14 @@ func SetupVRFV2Environment( if err != nil { return nil, nil, nil, err } - l.Info().Str("Coordinator", vrfContracts.CoordinatorV2.Address()).Msg("Registering Proving Key") provingKey, err := VRFV2RegisterProvingKey(vrfKey, registerProvingKeyAgainstAddress, vrfContracts.CoordinatorV2) if err != nil { - return nil, nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrRegisteringProvingKey, err) + return nil, nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrRegisteringProvingKey, err) } keyHash, err := vrfContracts.CoordinatorV2.HashOfKey(ctx, provingKey) if err != nil { - return nil, nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrCreatingProvingKeyHash, err) + return nil, nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrCreatingProvingKeyHash, err) } vrfTXKeyAddressStrings, vrfTXKeyAddresses, err := vrfcommon.CreateFundAndGetSendingKeys( @@ -189,44 +188,47 @@ func SetupVRFV2Environment( return vrfContracts, &vrfKeyData, nodeTypeToNodeMap, nil } -func setupVRFNode(contracts *vrfcommon.VRFContracts, chainID *big.Int, vrfv2Config *testconfig.General, pubKeyCompressed string, vrfOwnerConfig *vrfcommon.VRFOwnerConfig, l zerolog.Logger, vrfNode *vrfcommon.VRFNode) error { +func setupVRFNode(contracts *vrfcommon.VRFContracts, chainID *big.Int, config *testconfig.General, pubKeyCompressed string, vrfOwnerConfig *vrfcommon.VRFOwnerConfig, l zerolog.Logger, vrfNode *vrfcommon.VRFNode) error { vrfJobSpecConfig := vrfcommon.VRFJobSpecConfig{ - ForwardingAllowed: *vrfv2Config.VRFJobForwardingAllowed, + ForwardingAllowed: *config.VRFJobForwardingAllowed, CoordinatorAddress: contracts.CoordinatorV2.Address(), BatchCoordinatorAddress: contracts.BatchCoordinatorV2.Address(), FromAddresses: vrfNode.TXKeyAddressStrings, EVMChainID: chainID.String(), - MinIncomingConfirmations: int(*vrfv2Config.MinimumConfirmations), + MinIncomingConfirmations: int(*config.MinimumConfirmations), PublicKey: pubKeyCompressed, - EstimateGasMultiplier: *vrfv2Config.VRFJobEstimateGasMultiplier, - BatchFulfillmentEnabled: *vrfv2Config.VRFJobBatchFulfillmentEnabled, - BatchFulfillmentGasMultiplier: *vrfv2Config.VRFJobBatchFulfillmentGasMultiplier, - PollPeriod: vrfv2Config.VRFJobPollPeriod.Duration, - RequestTimeout: vrfv2Config.VRFJobRequestTimeout.Duration, - SimulationBlock: vrfv2Config.VRFJobSimulationBlock, + EstimateGasMultiplier: *config.VRFJobEstimateGasMultiplier, + BatchFulfillmentEnabled: *config.VRFJobBatchFulfillmentEnabled, + BatchFulfillmentGasMultiplier: *config.VRFJobBatchFulfillmentGasMultiplier, + PollPeriod: config.VRFJobPollPeriod.Duration, + RequestTimeout: config.VRFJobRequestTimeout.Duration, + SimulationBlock: config.VRFJobSimulationBlock, VRFOwnerConfig: vrfOwnerConfig, } l.Info().Msg("Creating VRFV2 Job") - vrfV2job, err := CreateVRFV2Job( + job, err := CreateVRFV2Job( vrfNode.CLNode.API, vrfJobSpecConfig, ) if err != nil { return fmt.Errorf("%s, err %w", ErrCreateVRFV2Jobs, err) } - vrfNode.Job = vrfV2job + vrfNode.Job = job // this part is here because VRFv2 can work with only a specific key // [[EVM.KeySpecific]] // Key = '...' nodeConfig := node.NewConfig(vrfNode.CLNode.NodeConfig, - node.WithKeySpecificMaxGasPrice(vrfNode.TXKeyAddressStrings, *vrfv2Config.CLNodeMaxGasPriceGWei), + node.WithKeySpecificMaxGasPrice(vrfNode.TXKeyAddressStrings, *config.CLNodeMaxGasPriceGWei), ) - l.Info().Msg("Restarting Node with new sending key PriceMax configuration") + l.Info(). + Strs("Sending Keys", vrfNode.TXKeyAddressStrings). + Int64("Price Max Setting", *config.CLNodeMaxGasPriceGWei). + Msg("Restarting Node with new sending key PriceMax configuration") err = vrfNode.CLNode.Restart(nodeConfig) if err != nil { - return fmt.Errorf("%s, err %w", vrfcommon.ErrRestartCLNode, err) + return fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrRestartCLNode, err) } return nil } diff --git a/integration-tests/actions/vrf/vrfv2plus/contract_steps.go b/integration-tests/actions/vrf/vrfv2plus/contract_steps.go index 5a4ec9ba11a..740e9bcbceb 100644 --- a/integration-tests/actions/vrf/vrfv2plus/contract_steps.go +++ b/integration-tests/actions/vrf/vrfv2plus/contract_steps.go @@ -48,6 +48,24 @@ func DeployVRFV2_5Contracts( if err != nil { return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrLoadingCoordinator, err) } + } else if actions.IsArbitrumChain(chainClient.ChainID) { + arbitrumCoordinator, err := contracts.DeployVRFCoordinatorV2_5_Arbitrum(chainClient, bhs.Address()) + if err != nil { + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrDeployCoordinatorV2Plus, err) + } + coordinator, err = contracts.LoadVRFCoordinatorV2_5(chainClient, arbitrumCoordinator.Address.String()) + if err != nil { + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrLoadingCoordinator, err) + } + } else if *configGeneral.UseTestCoordinator { + testCoordinator, err := contracts.DeployVRFCoordinatorTestV2_5(chainClient, bhs.Address()) + if err != nil { + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrDeployCoordinatorV2Plus, err) + } + coordinator, err = contracts.LoadVRFCoordinatorV2_5(chainClient, testCoordinator.Address.String()) + if err != nil { + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrLoadingCoordinator, err) + } } else { coordinator, err = contracts.DeployVRFCoordinatorV2_5(chainClient, bhs.Address()) if err != nil { @@ -426,6 +444,15 @@ func DeployVRFV2PlusDirectFundingContracts( if err != nil { return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrLoadingCoordinator, err) } + } else if actions.IsArbitrumChain(sethClient.ChainID) { + arbitrumWrapper, err := contracts.DeployVRFV2PlusWrapperArbitrum(sethClient, linkTokenAddress, linkEthFeedAddress, coordinator.Address(), wrapperSubId) + if err != nil { + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrDeployCoordinatorV2Plus, err) + } + vrfv2PlusWrapper, err = contracts.LoadVRFV2PlusWrapper(sethClient, arbitrumWrapper.Address.String()) + if err != nil { + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrLoadingCoordinator, err) + } } else { vrfv2PlusWrapper, err = contracts.DeployVRFV2PlusWrapper(sethClient, linkTokenAddress, linkEthFeedAddress, coordinator.Address(), wrapperSubId) if err != nil { diff --git a/integration-tests/actions/vrf/vrfv2plus/setup_steps.go b/integration-tests/actions/vrf/vrfv2plus/setup_steps.go index 4833afb9fef..fe06222a79c 100644 --- a/integration-tests/actions/vrf/vrfv2plus/setup_steps.go +++ b/integration-tests/actions/vrf/vrfv2plus/setup_steps.go @@ -63,12 +63,10 @@ func CreateVRFV2PlusJob( if vrfJobSpecConfig.BatchFulfillmentEnabled { jobSpec.BatchCoordinatorAddress = vrfJobSpecConfig.BatchCoordinatorAddress } - job, err := chainlinkNode.MustCreateJob(&jobSpec) if err != nil { return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrCreatingVRFv2PlusJob, err) } - return job, nil } @@ -87,7 +85,6 @@ func SetupVRFV2_5Environment( ) (*vrfcommon.VRFContracts, *vrfcommon.VRFKeyData, map[vrfcommon.VRFNodeType]*vrfcommon.VRFNode, error) { l.Info().Msg("Starting VRFV2 Plus environment setup") configGeneral := vrfv2PlusTestConfig.GetVRFv2PlusConfig().General - vrfContracts, err := SetupVRFV2PlusContracts( sethClient, linkToken, @@ -361,7 +358,7 @@ func SetupVRFV2PlusWrapperForNewEnv( vrfv2PlusConfig, ) if err != nil { - return nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) + return nil, nil, err } // once the wrapper is deployed, wrapper address will become consumer of external EOA subscription err = vrfContracts.CoordinatorV2Plus.AddConsumer(wrapperSubId, wrapperContracts.VRFV2PlusWrapper.Address()) diff --git a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go index 9b286a1d057..5926f90cf0a 100644 --- a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go +++ b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go @@ -16,11 +16,14 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/wrappers" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/batch_blockhash_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/batch_vrf_coordinator_v2plus" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_test_v2_5" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5_arbitrum" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5_optimism" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_upgraded_version" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_arbitrum" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_optimism" ) @@ -37,6 +40,18 @@ type EthereumVRFCoordinatorV2_5_Optimism struct { coordinator vrf_coordinator_v2_5_optimism.VRFCoordinatorV25Optimism } +type EthereumVRFCoordinatorV2_5_Arbitrum struct { + Address common.Address + client *seth.Client + coordinator vrf_coordinator_v2_5_arbitrum.VRFCoordinatorV25Arbitrum +} + +type EthereumVRFCoordinatorTestV2_5 struct { + Address common.Address + client *seth.Client + coordinator vrf_coordinator_test_v2_5.VRFCoordinatorTestV25 +} + type EthereumBatchVRFCoordinatorV2Plus struct { address common.Address client *seth.Client @@ -74,6 +89,12 @@ type EthereumVRFV2PlusWrapperOptimism struct { wrapper *vrfv2plus_wrapper_optimism.VRFV2PlusWrapperOptimism } +type EthereumVRFV2PlusWrapperArbitrum struct { + Address common.Address + client *seth.Client + wrapper *vrfv2plus_wrapper_arbitrum.VRFV2PlusWrapperArbitrum +} + func (v *EthereumVRFV2PlusWrapper) Address() string { return v.address.Hex() } @@ -178,6 +199,56 @@ func DeployVRFCoordinatorV2_5_Optimism(seth *seth.Client, bhsAddr string) (*Ethe }, err } +func DeployVRFCoordinatorV2_5_Arbitrum(seth *seth.Client, bhsAddr string) (*EthereumVRFCoordinatorV2_5_Arbitrum, error) { + abi, err := vrf_coordinator_v2_5_arbitrum.VRFCoordinatorV25ArbitrumMetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to get VRFCoordinatorV2_5_Arbitrum ABI: %w", err) + } + coordinatorDeploymentData, err := seth.DeployContract( + seth.NewTXOpts(), + "VRFCoordinatorV2_5_Arbitrum", + *abi, + common.FromHex(vrf_coordinator_v2_5_arbitrum.VRFCoordinatorV25ArbitrumMetaData.Bin), + common.HexToAddress(bhsAddr)) + if err != nil { + return nil, fmt.Errorf("VRFCoordinatorV2_5_Arbitrum instance deployment have failed: %w", err) + } + contract, err := vrf_coordinator_v2_5_arbitrum.NewVRFCoordinatorV25Arbitrum(coordinatorDeploymentData.Address, wrappers.MustNewWrappedContractBackend(nil, seth)) + if err != nil { + return nil, fmt.Errorf("failed to instantiate VRFCoordinatorV2_5_Arbitrum instance: %w", err) + } + return &EthereumVRFCoordinatorV2_5_Arbitrum{ + client: seth, + coordinator: *contract, + Address: coordinatorDeploymentData.Address, + }, err +} + +func DeployVRFCoordinatorTestV2_5(seth *seth.Client, bhsAddr string) (*EthereumVRFCoordinatorTestV2_5, error) { + abi, err := vrf_coordinator_test_v2_5.VRFCoordinatorTestV25MetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to get VRFCoordinatorTestV2_5 ABI: %w", err) + } + coordinatorDeploymentData, err := seth.DeployContract( + seth.NewTXOpts(), + "VRFCoordinatorTestV2_5", + *abi, + common.FromHex(vrf_coordinator_test_v2_5.VRFCoordinatorTestV25MetaData.Bin), + common.HexToAddress(bhsAddr)) + if err != nil { + return nil, fmt.Errorf("VRFCoordinatorTestV2_5 instance deployment have failed: %w", err) + } + contract, err := vrf_coordinator_test_v2_5.NewVRFCoordinatorTestV25(coordinatorDeploymentData.Address, wrappers.MustNewWrappedContractBackend(nil, seth)) + if err != nil { + return nil, fmt.Errorf("failed to instantiate VRFCoordinatorTestV2_5 instance: %w", err) + } + return &EthereumVRFCoordinatorTestV2_5{ + client: seth, + coordinator: *contract, + Address: coordinatorDeploymentData.Address, + }, err +} + func DeployBatchVRFCoordinatorV2Plus(seth *seth.Client, coordinatorAddress string) (BatchVRFCoordinatorV2Plus, error) { abi, err := batch_vrf_coordinator_v2plus.BatchVRFCoordinatorV2PlusMetaData.GetAbi() if err != nil { @@ -1185,24 +1256,50 @@ func DeployVRFV2PlusWrapper(seth *seth.Client, linkAddr string, linkEthFeedAddr }, err } +func DeployVRFV2PlusWrapperArbitrum(seth *seth.Client, linkAddr string, linkEthFeedAddr string, coordinatorAddr string, subId *big.Int) (*EthereumVRFV2PlusWrapperArbitrum, error) { + abi, err := vrfv2plus_wrapper_arbitrum.VRFV2PlusWrapperArbitrumMetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to get VRFV2PlusWrapper_Arbitrum ABI: %w", err) + } + data, err := seth.DeployContract( + seth.NewTXOpts(), + "VRFV2PlusWrapper_Arbitrum", + *abi, + common.FromHex(vrfv2plus_wrapper_arbitrum.VRFV2PlusWrapperArbitrumMetaData.Bin), + common.HexToAddress(linkAddr), common.HexToAddress(linkEthFeedAddr), + common.HexToAddress(coordinatorAddr), subId) + if err != nil { + return nil, fmt.Errorf("VRFV2PlusWrapper_Arbitrum instance deployment have failed: %w", err) + } + contract, err := vrfv2plus_wrapper_arbitrum.NewVRFV2PlusWrapperArbitrum(data.Address, wrappers.MustNewWrappedContractBackend(nil, seth)) + if err != nil { + return nil, fmt.Errorf("failed to instantiate VRFV2PlusWrapper_Arbitrum instance: %w", err) + } + return &EthereumVRFV2PlusWrapperArbitrum{ + client: seth, + wrapper: contract, + Address: data.Address, + }, err +} + func DeployVRFV2PlusWrapperOptimism(seth *seth.Client, linkAddr string, linkEthFeedAddr string, coordinatorAddr string, subId *big.Int) (*EthereumVRFV2PlusWrapperOptimism, error) { abi, err := vrfv2plus_wrapper_optimism.VRFV2PlusWrapperOptimismMetaData.GetAbi() if err != nil { - return nil, fmt.Errorf("failed to get VRFV2PlusWrapperOptimism ABI: %w", err) + return nil, fmt.Errorf("failed to get VRFV2PlusWrapper_Optimism ABI: %w", err) } data, err := seth.DeployContract( seth.NewTXOpts(), - "VRFV2PlusWrapperOptimism", + "VRFV2PlusWrapper_Optimism", *abi, common.FromHex(vrfv2plus_wrapper_optimism.VRFV2PlusWrapperOptimismMetaData.Bin), common.HexToAddress(linkAddr), common.HexToAddress(linkEthFeedAddr), common.HexToAddress(coordinatorAddr), subId) if err != nil { - return nil, fmt.Errorf("VRFV2PlusWrapperOptimism instance deployment have failed: %w", err) + return nil, fmt.Errorf("VRFV2PlusWrapper_Optimism instance deployment have failed: %w", err) } contract, err := vrfv2plus_wrapper_optimism.NewVRFV2PlusWrapperOptimism(data.Address, wrappers.MustNewWrappedContractBackend(nil, seth)) if err != nil { - return nil, fmt.Errorf("failed to instantiate VRFV2PlusWrapperOptimism instance: %w", err) + return nil, fmt.Errorf("failed to instantiate VRFV2PlusWrapper_Optimism instance: %w", err) } return &EthereumVRFV2PlusWrapperOptimism{ client: seth, diff --git a/integration-tests/load/vrfv2/vrfv2_test.go b/integration-tests/load/vrfv2/vrfv2_test.go index 7913d26904c..c0a4153ba07 100644 --- a/integration-tests/load/vrfv2/vrfv2_test.go +++ b/integration-tests/load/vrfv2/vrfv2_test.go @@ -72,9 +72,9 @@ func TestVRFV2Performance(t *testing.T) { Uint16("RandomnessRequestCountPerRequestDeviation", *vrfv2Config.General.RandomnessRequestCountPerRequestDeviation). Bool("UseExistingEnv", *vrfv2Config.General.UseExistingEnv). Msg("Performance Test Configuration") + cleanupFn := func() { teardown(t, vrfContracts.VRFV2Consumers[0], lc, updatedLabels, testReporter, testType, &testConfig) - require.NoError(t, err, "Getting Seth client shouldn't fail") if sethClient.Cfg.IsSimulatedNetwork() { l.Info(). @@ -309,7 +309,7 @@ func TestVRFV2BHSPerformance(t *testing.T) { wgBlockNumberTobe.Add(1) //Wait at least 256 blocks latestBlockNumber, err := sethClient.Client.BlockNumber(testcontext.Get(t)) - require.NoError(t, err) + require.NoError(t, err, "error getting latest block number") _, err = actions.WaitForBlockNumberToBe( testcontext.Get(t), latestBlockNumber+uint64(257), diff --git a/integration-tests/testconfig/vrfv2/vrfv2.toml b/integration-tests/testconfig/vrfv2/vrfv2.toml index de7200b1e79..634e3074feb 100644 --- a/integration-tests/testconfig/vrfv2/vrfv2.toml +++ b/integration-tests/testconfig/vrfv2/vrfv2.toml @@ -19,6 +19,7 @@ MaxSize = '0b' [WebServer] AllowOrigins = '*' HTTPPort = 6688 +HTTPWriteTimeout = '1m0s' SecureCookies = false [WebServer.RateLimit] diff --git a/integration-tests/testconfig/vrfv2plus/config.go b/integration-tests/testconfig/vrfv2plus/config.go index 9d863afdd14..52d518e5395 100644 --- a/integration-tests/testconfig/vrfv2plus/config.go +++ b/integration-tests/testconfig/vrfv2plus/config.go @@ -59,6 +59,8 @@ type General struct { //OP Stack chains settings L1FeeCalculationMode uint8 `toml:"l1_fee_calculation_mode"` L1FeeCoefficient uint8 `toml:"l1_fee_coefficient"` + + UseTestCoordinator *bool `toml:"use_test_coordinator"` } func (c *General) Validate() error { @@ -101,6 +103,9 @@ func (c *General) Validate() error { if c.CoordinatorLinkPremiumPercentage == nil { return errors.New("coordinator_link_premium_percentage must not be nil") } + if c.UseTestCoordinator == nil { + return errors.New("use_test_coordinator must not be nil") + } return nil } diff --git a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml index 860c0c158bf..1281ae7f2dd 100644 --- a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml +++ b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml @@ -30,7 +30,78 @@ Unauthenticated = 100 HTTPSPort = 0 """ +# Node TOML config depending on the chain [NodeConfig.ChainConfigTOMLByChainID] +# ETHEREUM SEPOLIA +11155111 = """ +BlockBackfillDepth = 500 +MinIncomingConfirmations = 3 + +[GasEstimator] +LimitDefault = 3500000 +""" + +# BNB TESTNET +97 = """ +BlockBackfillDepth = 500 +RPCDefaultBatchSize = 25 +LogBackfillBatchSize = 1000 + +[GasEstimator] +LimitDefault = 3500000 + +[GasEstimator.BlockHistory] +BatchSize = 100 +""" + +# Polygon Amoy +80002 = """ +BlockBackfillDepth = 500 +RPCDefaultBatchSize = 25 +LogBackfillBatchSize = 1000 + +[Transactions] +MaxInFlight = 128 +MaxQueued = 0 + +[GasEstimator] +LimitDefault = 3500000 + +[GasEstimator.BlockHistory] +BatchSize = 100 +""" + +# Avalanche Fuji +43113 = """ +BlockBackfillDepth = 500 +RPCDefaultBatchSize = 25 +LogBackfillBatchSize = 1000 + +[GasEstimator] +LimitDefault = 3500000 + +[GasEstimator.BlockHistory] +BatchSize = 100 +""" + +# Arbitrum Sepolia +# NOTE: PROD env has `LimitDefault = 100_000_000`, but it is decreased in order not to over spend testnet tokens +421614 = """ +BlockBackfillDepth = 15000 +LogBackfillBatchSize = 1000 +RPCDefaultBatchSize = 25 + +[Transactions] +MaxInFlight = 128 +MaxQueued = 0 + +[GasEstimator] +LimitDefault = 3_500_000 + +[GasEstimator.BlockHistory] +BatchSize = 100 +""" + # OPTIMISM SEPOLIA 11155420 = """ BlockBackfillDepth = 500 @@ -56,12 +127,69 @@ LimitDefault = 3500000 [GasEstimator.BlockHistory] BatchSize = 100 """ +# Nexon Staging +847799 = """ +BlockBackfillDepth = 500 +RPCDefaultBatchSize = 25 +LogBackfillBatchSize = 1000 +NoNewHeadsThreshold = '0s' + +[GasEstimator] +LimitDefault = 3500000 + +[GasEstimator.BlockHistory] +BatchSize = 100 +""" + +# Nexon QA +807424 = """ +BlockBackfillDepth = 500 +RPCDefaultBatchSize = 25 +LogBackfillBatchSize = 1000 +NoNewHeadsThreshold = '0s' + +[GasEstimator] +LimitDefault = 3500000 + +[GasEstimator.BlockHistory] +BatchSize = 100 +""" + +# Nexon TEST +595581 = """ +BlockBackfillDepth = 500 +RPCDefaultBatchSize = 25 +LogBackfillBatchSize = 1000 +NoNewHeadsThreshold = '0s' + +[GasEstimator] +LimitDefault = 3500000 + +[GasEstimator.BlockHistory] +BatchSize = 100 +""" + +# Nexon DEV +5668 = """ +BlockBackfillDepth = 500 +RPCDefaultBatchSize = 25 +LogBackfillBatchSize = 1000 +NoNewHeadsThreshold = '0s' + +[GasEstimator] +LimitDefault = 3500000 + +[GasEstimator.BlockHistory] +BatchSize = 100 +""" + [Common] chainlink_node_funding = 0.7 [VRFv2Plus] [VRFv2Plus.General] +use_test_coordinator = false cancel_subs_after_test_run = true use_existing_env = false #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request @@ -222,8 +350,10 @@ bhs_test_rate_limit_unit_duration = "3s" bhs_test_rps = 1 ### POLYGON AMOY Config - +[POLYGON_AMOY.Common] +chainlink_node_funding = 5 [POLYGON_AMOY.VRFv2Plus.General] +use_test_coordinator = true #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request minimum_confirmations = 3 @@ -233,7 +363,7 @@ callback_gas_limit = 1000000 # NEW ENV CONFIG # CL Node config -cl_node_max_gas_price_gwei = 200 +cl_node_max_gas_price_gwei = 500 number_of_sending_keys_to_create = 0 # Coordinator config @@ -303,16 +433,16 @@ node_sending_keys = [ randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 5 +subscription_funding_amount_link = 3 subscription_funding_amount_native = 1 -subscription_refunding_amount_link = 5 +subscription_refunding_amount_link = 3 subscription_refunding_amount_native = 1 number_of_words = 1 random_words_fulfilled_event_timeout = "1m30s" wait_for_256_blocks_timeout = "15m" wrapper_consumer_funding_amount_native_token = 1.0 -wrapper_consumer_funding_amount_link = 5 +wrapper_consumer_funding_amount_link = 3 [POLYGON_AMOY-Smoke.VRFv2Plus.Performance] @@ -364,15 +494,20 @@ rps = 1 ### ARBITRUM SEPOLIA Config [ARBITRUM_SEPOLIA.VRFv2Plus.General] +use_test_coordinator = true #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request minimum_confirmations = 0 -subscription_billing_type = "LINK_AND_NATIVE" +## NEW ENV CONFIG +## CL Node config cl_node_max_gas_price_gwei = 50 number_of_sending_keys_to_create = 0 -# Coordinator config +# Consumer Request config +subscription_billing_type = "LINK_AND_NATIVE" callback_gas_limit = 1000000 + +# Coordinator config max_gas_limit_coordinator_config = 2500000 fallback_wei_per_unit_link = "5352799651145251" staleness_seconds = 172_800 @@ -445,8 +580,8 @@ randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be l number_of_sub_to_create = 1 subscription_funding_amount_link = 5 subscription_funding_amount_native = 1 -subscription_refunding_amount_link = 20 -subscription_refunding_amount_native = 10 +subscription_refunding_amount_link = 5 +subscription_refunding_amount_native = 1 number_of_words = 1 random_words_fulfilled_event_timeout = "1m30s" wait_for_256_blocks_timeout = "100s" @@ -502,7 +637,10 @@ rps = 1 ### AVALANCHE FUJI Config +[AVALANCHE_FUJI.Common] +chainlink_node_funding = 3 [AVALANCHE_FUJI.VRFv2Plus.General] +use_test_coordinator = true #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request minimum_confirmations = 0 @@ -568,10 +706,10 @@ node_sending_keys = [ randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 20 -subscription_funding_amount_native = 20 -subscription_refunding_amount_link = 20 -subscription_refunding_amount_native = 20 +subscription_funding_amount_link = 3 +subscription_funding_amount_native = 1 +subscription_refunding_amount_link = 3 +subscription_refunding_amount_native = 1 number_of_words = 1 random_words_fulfilled_event_timeout = "1m30s" wait_for_256_blocks_timeout = "10m" @@ -627,6 +765,7 @@ rps = 1 ### ETH SEPOLIA Config [SEPOLIA.VRFv2Plus.General] +use_test_coordinator = true #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request minimum_confirmations = 3 @@ -692,16 +831,16 @@ node_sending_keys = [ randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 5 +subscription_funding_amount_link = 3 subscription_funding_amount_native = 1 -subscription_refunding_amount_link = 5 +subscription_refunding_amount_link = 3 subscription_refunding_amount_native = 1 number_of_words = 1 random_words_fulfilled_event_timeout = "1m30s" wait_for_256_blocks_timeout = "70m" wrapper_consumer_funding_amount_native_token = 1.0 -wrapper_consumer_funding_amount_link = 5 +wrapper_consumer_funding_amount_link = 3 [SEPOLIA-Smoke.VRFv2Plus.Performance] test_duration = "2s" @@ -747,8 +886,9 @@ test_duration = "2m" rate_limit_unit_duration = "3s" rps = 1 -### BSC SEPOLIA Config +### BSC TESTNET Config [BSC_TESTNET.VRFv2Plus.General] +use_test_coordinator = true #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request minimum_confirmations = 3 @@ -814,8 +954,16 @@ node_sending_keys = [ randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 -subscription_funding_amount_link = 10 -subscription_funding_amount_native = 10 +subscription_funding_amount_link = 3 +subscription_funding_amount_native = 1 +subscription_refunding_amount_link = 3 +subscription_refunding_amount_native = 1 +number_of_words = 1 +random_words_fulfilled_event_timeout = "1m30s" +wait_for_256_blocks_timeout = "15m" + +wrapper_consumer_funding_amount_native_token = 1.0 +wrapper_consumer_funding_amount_link = 5 [BSC_TESTNET-Smoke.VRFv2Plus.Performance] test_duration = "15s" @@ -866,6 +1014,7 @@ rps = 1 ### NEXON QA Config [NEXON_QA.VRFv2Plus.General] +use_test_coordinator = true #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request minimum_confirmations = 0 generate_txs_on_chain = true @@ -952,6 +1101,7 @@ rps = 1 ### NEXON DEV Config [NEXON_DEV.VRFv2Plus.General] +use_test_coordinator = true #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request minimum_confirmations = 0 generate_txs_on_chain = true @@ -1037,6 +1187,7 @@ rps = 1 ### NEXON TEST Config [NEXON_TEST.VRFv2Plus.General] +use_test_coordinator = true #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request minimum_confirmations = 0 generate_txs_on_chain = true @@ -1123,6 +1274,7 @@ rps = 1 ### NEXON STAGE Config [NEXON_STAGE.VRFv2Plus.General] +use_test_coordinator = true #todo - need to have separate minimum_confirmations config for Coordinator, CL Node and Consumer request minimum_confirmations = 0 generate_txs_on_chain = true @@ -1201,3 +1353,5 @@ subscription_funding_amount_native = 0.1 test_duration = "2m" rate_limit_unit_duration = "3s" rps = 1 + +