Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sketch wrapper support for wrapped native #10737

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 61 additions & 5 deletions contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import "../interfaces/IVRFCoordinatorV2Plus.sol";
import "../interfaces/VRFV2PlusWrapperInterface.sol";
import "./VRFV2PlusWrapperConsumerBase.sol";
import "../../ChainSpecificUtil.sol";
import "../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/IERC20.sol";

/**
* @notice A wrapper for VRFCoordinatorV2 that provides an interface better suited to one-off
Expand All @@ -18,9 +19,13 @@ import "../../ChainSpecificUtil.sol";
contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsumerBaseV2Plus, VRFV2PlusWrapperInterface {
event WrapperFulfillmentFailed(uint256 indexed requestId, address indexed consumer);

error WrappedNativeAlreadySet();
error LinkAlreadySet();
error FailedToTransferLink();

// The wrapped native token that is accepted for transfers.
IERC20 public s_wrappedNative;

LinkTokenInterface public s_link;
AggregatorV3Interface public s_linkEthFeed;
ExtendedVRFCoordinatorV2PlusInterface public immutable COORDINATOR;
Expand All @@ -41,6 +46,9 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
// should only be relied on within the same transaction the request was made.
uint256 public override lastRequestId;

// Tracks the wrapped native balance on the contract. Incremented when a request is made.
uint256 public s_wrappedNativeBalance;

// Configuration fetched from VRFCoordinatorV2

// s_configured tracks whether this contract has been configured. If not configured, randomness
Expand Down Expand Up @@ -124,6 +132,18 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
s_link = LinkTokenInterface(link);
}

/**
* @notice set the wrapped native token to be used by this wrapper
* @param wrappedNative address of the wrapped native token
*/
function setWrappedNative(address wrappedNative) external onlyOwner {
// Disallow re-setting wrapped native
if (address(s_wrappedNative) != address(0)) {
revert WrappedNativeAlreadySet();
}
s_wrappedNative = IERC20(wrappedNative);
}

/**
* @notice set the link eth feed to be used by this wrapper
* @param linkEthFeed address of the link eth feed
Expand Down Expand Up @@ -357,15 +377,13 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
lastRequestId = requestId;
}

function requestRandomWordsInNative(
function requestRandomWordsInNativeInternal(
uint32 _callbackGasLimit,
uint16 _requestConfirmations,
uint32 _numWords
) external payable override returns (uint256 requestId) {
uint32 eip150Overhead = getEIP150Overhead(_callbackGasLimit);
uint256 price = calculateRequestPriceNativeInternal(_callbackGasLimit, tx.gasprice);
require(msg.value >= price, "fee too low");
) internal returns (uint256 requestId) {
require(_numWords <= s_maxNumWords, "numWords too high");
uint32 eip150Overhead = getEIP150Overhead(_callbackGasLimit);
VRFV2PlusClient.RandomWordsRequest memory req = VRFV2PlusClient.RandomWordsRequest({
keyHash: s_keyHash,
subId: SUBSCRIPTION_ID,
Expand All @@ -380,6 +398,44 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
callbackGasLimit: _callbackGasLimit,
requestGasPrice: tx.gasprice
});
}

function requestRandomWordsInWrappedNative(
uint32 _callbackGasLimit,
uint16 _requestConfirmations,
uint32 _numWords
) external payable returns (uint256 requestId) {
require(address(s_wrappedNative) != address(0), "wrapped native not set");
uint256 price = calculateRequestPriceNativeInternal(_callbackGasLimit, tx.gasprice);

// User is obligated to transfer wrapped native to this contract matching the estimated
// native price of the request.
uint256 amountPaid = s_wrappedNative.balanceOf(address(this)) - s_wrappedNativeBalance;
require(amountPaid >= price, "fee too low");

requestId = requestRandomWordsInNativeInternal(_callbackGasLimit, _requestConfirmations, _numWords);

// Update balance to be canonical.
s_wrappedNativeBalance += amountPaid;

return requestId;
}

function requestRandomWordsInNative(
uint32 _callbackGasLimit,
uint16 _requestConfirmations,
uint32 _numWords
) external payable override returns (uint256 requestId) {
uint256 price = calculateRequestPriceNativeInternal(_callbackGasLimit, tx.gasprice);
require(msg.value >= price, "fee too low");

requestId = requestRandomWordsInNativeInternal(_callbackGasLimit, _requestConfirmations, _numWords);

s_callbacks[requestId] = Callback({
callbackAddress: msg.sender,
callbackGasLimit: _callbackGasLimit,
requestGasPrice: tx.gasprice
});

return requestId;
}
Expand Down