// SPDX-License-Identifier: MIT // An example of a consumer contract that directly pays for each request. pragma solidity ^0.8.7; import "./ConfirmedOwner.sol"; import "./VRFV2WrapperConsumerBase.sol"; /** * Request testnet PLI and ETH here: https://faucets.chain.link/ * Find information on PLI Token Contracts and get the latest ETH and PLI faucets here: https://docs.chain.link/docs/link-token-contracts/ */ /** * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ contract VRFv2DirectFundingConsumer is VRFV2WrapperConsumerBase, ConfirmedOwner { event RequestSent(uint256 requestId, uint32 numWords); event RequestFulfilled( uint256 requestId, uint256[] randomWords, uint256 payment ); struct RequestStatus { uint256 paid; // amount paid in link bool fulfilled; // whether the request has been successfully fulfilled uint256[] randomWords; } mapping(uint256 => RequestStatus) public s_requests; /* requestId --> requestStatus */ // past requests Id. uint256[] public requestIds; uint256 public lastRequestId; // Depends on the number of requested values that you want sent to the // fulfillRandomWords() function. Test and adjust // this limit based on the network that you select, the size of the request, // and the processing of the callback request in the fulfillRandomWords() // function. uint32 callbackGasLimit = 100000; // The default is 3, but you can set this higher. uint16 requestConfirmations = 3; // For this example, retrieve 2 random values in one request. // Cannot exceed VRFV2Wrapper.getConfig().maxNumWords. uint32 numWords = 2; // Address PLI - hardcoded for Sepolia address pliAddress =0x33f4212b027E22aF7e6BA21Fc572843C0D701CD1; // address WRAPPER - hardcoded for Sepolia address wrapperAddress = 0xCA24FbBb16Cdf23763439d1Ff5b41110962184F8; constructor() ConfirmedOwner(msg.sender) VRFV2WrapperConsumerBase(pliAddress, wrapperAddress) {} function requestRandomWords() external onlyOwner returns (uint256 requestId) { requestId = requestRandomness( callbackGasLimit, requestConfirmations, numWords ); s_requests[requestId] = RequestStatus({ paid: VRF_V2_WRAPPER.calculateRequestPrice(callbackGasLimit), randomWords: new uint256[](0), fulfilled: false }); requestIds.push(requestId); lastRequestId = requestId; emit RequestSent(requestId, numWords); return requestId; } function fulfillRandomWords( uint256 _requestId, uint256[] memory _randomWords ) internal override { require(s_requests[_requestId].paid > 0, "request not found"); s_requests[_requestId].fulfilled = true; s_requests[_requestId].randomWords = _randomWords; emit RequestFulfilled( _requestId, _randomWords, s_requests[_requestId].paid ); } function getRequestStatus( uint256 _requestId ) external view returns (uint256 paid, bool fulfilled, uint256[] memory randomWords) { require(s_requests[_requestId].paid > 0, "request not found"); RequestStatus memory request = s_requests[_requestId]; return (request.paid, request.fulfilled, request.randomWords); } /** * Allow withdraw of Pli tokens from the contract */ function withdrawPli() public onlyOwner { PliTokenInterface pli = PliTokenInterface(pliAddress); require( pli.transfer(msg.sender, pli.balanceOf(address(this))), "Unable to transfer" ); } }