|
| 1 | +// SPDX-License-Identifier: MIT |
| 2 | +pragma solidity ^0.8.0; |
| 3 | + |
| 4 | +import "@chainlink/contracts/src/v0.8/interfaces/LinkTokenInterface.sol"; |
| 5 | +import "@chainlink/contracts/src/v0.8/interfaces/VRFV2WrapperInterface.sol"; |
| 6 | + |
| 7 | +/** ******************************************************************************* |
| 8 | + * @notice Interface for contracts using VRF randomness through the VRF V2 wrapper |
| 9 | + * ******************************************************************************** |
| 10 | + * @dev PURPOSE |
| 11 | + * |
| 12 | + * @dev Create VRF V2 requests without the need for subscription management. Rather than creating |
| 13 | + * @dev and funding a VRF V2 subscription, a user can use this wrapper to create one off requests, |
| 14 | + * @dev paying up front rather than at fulfillment. |
| 15 | + * |
| 16 | + * @dev Since the price is determined using the gas price of the request transaction rather than |
| 17 | + * @dev the fulfillment transaction, the wrapper charges an additional premium on callback gas |
| 18 | + * @dev usage, in addition to some extra overhead costs associated with the VRFV2Wrapper contract. |
| 19 | + * ***************************************************************************** |
| 20 | + * @dev USAGE |
| 21 | + * |
| 22 | + * @dev Calling contracts must inherit from VRFV2WrapperConsumerBase. The consumer must be funded |
| 23 | + * @dev with enough LINK to make the request, otherwise requests will revert. To request randomness, |
| 24 | + * @dev call the 'requestRandomness' function with the desired VRF parameters. This function handles |
| 25 | + * @dev paying for the request based on the current pricing. |
| 26 | + * |
| 27 | + * @dev Consumers must implement the fullfillRandomWords function, which will be called during |
| 28 | + * @dev fulfillment with the randomness result. |
| 29 | + */ |
| 30 | +abstract contract VRFV2WrapperConsumerBase { |
| 31 | + // solhint-disable-next-line var-name-mixedcase |
| 32 | + LinkTokenInterface internal immutable LINK; |
| 33 | + // solhint-disable-next-line var-name-mixedcase |
| 34 | + VRFV2WrapperInterface internal immutable VRF_V2_WRAPPER; |
| 35 | + |
| 36 | + /** |
| 37 | + * @param _link is the address of LinkToken |
| 38 | + * @param _vrfV2Wrapper is the address of the VRFV2Wrapper contract |
| 39 | + */ |
| 40 | + constructor(address _link, address _vrfV2Wrapper) { |
| 41 | + LINK = LinkTokenInterface(_link); |
| 42 | + VRF_V2_WRAPPER = VRFV2WrapperInterface(_vrfV2Wrapper); |
| 43 | + } |
| 44 | + |
| 45 | + /** |
| 46 | + * @dev Requests randomness from the VRF V2 wrapper. |
| 47 | + * |
| 48 | + * @param _callbackGasLimit is the gas limit that should be used when calling the consumer's |
| 49 | + * fulfillRandomWords function. |
| 50 | + * @param _requestConfirmations is the number of confirmations to wait before fulfilling the |
| 51 | + * request. A higher number of confirmations increases security by reducing the likelihood |
| 52 | + * that a chain re-org changes a published randomness outcome. |
| 53 | + * @param _numWords is the number of random words to request. |
| 54 | + * |
| 55 | + * @return requestId is the VRF V2 request ID of the newly created randomness request. |
| 56 | + */ |
| 57 | + function requestRandomness( |
| 58 | + uint32 _callbackGasLimit, |
| 59 | + uint16 _requestConfirmations, |
| 60 | + uint32 _numWords |
| 61 | + ) internal returns (uint256 requestId) { |
| 62 | + LINK.transferAndCall( |
| 63 | + address(VRF_V2_WRAPPER), |
| 64 | + VRF_V2_WRAPPER.calculateRequestPrice(_callbackGasLimit), |
| 65 | + abi.encode(_callbackGasLimit, _requestConfirmations, _numWords) |
| 66 | + ); |
| 67 | + return VRF_V2_WRAPPER.lastRequestId(); |
| 68 | + } |
| 69 | + |
| 70 | + /** |
| 71 | + * @notice fulfillRandomWords handles the VRF V2 wrapper response. The consuming contract must |
| 72 | + * @notice implement it. |
| 73 | + * |
| 74 | + * @param _requestId is the VRF V2 request ID. |
| 75 | + * @param _randomWords is the randomness result. |
| 76 | + */ |
| 77 | + function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal virtual; |
| 78 | + |
| 79 | + function rawFulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) external { |
| 80 | + require(msg.sender == address(VRF_V2_WRAPPER), "only VRF V2 wrapper can fulfill"); |
| 81 | + fulfillRandomWords(_requestId, _randomWords); |
| 82 | + } |
| 83 | +} |
0 commit comments