Skip to content

Commit

Permalink
Redesign VRFV2PlusWrapper to be migratable to new VRFCoordinators (#1…
Browse files Browse the repository at this point in the history
…0809)

* Removing dependency on ExtendedVRFCoordinatorV2Plus interface to make VRFV2PlusWrapper migratable to new VRFCoordinators

* Provide additional config params to VRFV2PlusWrapper from integration tests

---------

Co-authored-by: Sri Kidambi <[email protected]>
  • Loading branch information
kidambisrinivas and kidambisrinivas authored Sep 27, 2023
1 parent 7b1ae85 commit 0d475b6
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 66 deletions.
61 changes: 32 additions & 29 deletions contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,35 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
error LinkAlreadySet();
error FailedToTransferLink();

/* Storage Slot 1: BEGIN */
// s_keyHash is the key hash to use when requesting randomness. Fees are paid based on current gas
// fees, so this should be set to the highest gas lane on the network.
bytes32 s_keyHash;
/* Storage Slot 1: END */

/* Storage Slot 2: BEGIN */
uint256 public immutable SUBSCRIPTION_ID;
/* Storage Slot 2: END */

/* Storage Slot 3: BEGIN */
// 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;
/* Storage Slot 3: END */

/* Storage Slot 4: BEGIN */
// lastRequestId is the request ID of the most recent VRF V2 request made by this wrapper. This
// should only be relied on within the same transaction the request was made.
uint256 public override lastRequestId;
/* Storage Slot 4: END */

/* Storage Slot 5: BEGIN */
// s_fallbackWeiPerUnitLink is the backup LINK exchange rate used when the LINK/NATIVE feed is
// stale.
int256 private s_fallbackWeiPerUnitLink;
/* Storage Slot 5: END */

/* Storage Slot 6: BEGIN */
// s_stalenessSeconds is the number of seconds before we consider the feed price to be stale and
// fallback to fallbackWeiPerUnitLink.
uint32 private s_stalenessSeconds;
Expand All @@ -52,9 +63,9 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
uint32 private s_fulfillmentFlatFeeNativePPM;

LinkTokenInterface public s_link;
/* Storage Slot 6: END */

// Other configuration

/* Storage Slot 7: BEGIN */
// s_wrapperGasOverhead reflects the gas overhead of the wrapper's fulfillRandomWords
// function. The cost for this gas is passed to the user.
uint32 private s_wrapperGasOverhead;
Expand All @@ -76,7 +87,9 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
uint32 private s_coordinatorGasOverhead;

AggregatorV3Interface public s_linkNativeFeed;
/* Storage Slot 7: END */

/* Storage Slot 8: BEGIN */
// s_configured tracks whether this contract has been configured. If not configured, randomness
// requests cannot be made.
bool public s_configured;
Expand All @@ -91,8 +104,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume

// s_maxNumWords is the max number of words that can be requested in a single wrapped VRF request.
uint8 s_maxNumWords;

ExtendedVRFCoordinatorV2PlusInterface public immutable COORDINATOR;
/* Storage Slot 8: END */

struct Callback {
address callbackAddress;
Expand All @@ -103,21 +115,23 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
// GasPrice is unlikely to be more than 14 ETH on most chains
uint64 requestGasPrice;
}
/* Storage Slot 9: BEGIN */
mapping(uint256 => Callback) /* requestID */ /* callback */ public s_callbacks;

/* Storage Slot 9: END */

constructor(address _link, address _linkNativeFeed, address _coordinator) VRFConsumerBaseV2Plus(_coordinator) {
if (_link != address(0)) {
s_link = LinkTokenInterface(_link);
}
if (_linkNativeFeed != address(0)) {
s_linkNativeFeed = AggregatorV3Interface(_linkNativeFeed);
}
COORDINATOR = ExtendedVRFCoordinatorV2PlusInterface(_coordinator);

// Create this wrapper's subscription and add itself as a consumer.
uint256 subId = ExtendedVRFCoordinatorV2PlusInterface(_coordinator).createSubscription();
uint256 subId = s_vrfCoordinator.createSubscription();
SUBSCRIPTION_ID = subId;
ExtendedVRFCoordinatorV2PlusInterface(_coordinator).addConsumer(subId, address(this));
s_vrfCoordinator.addConsumer(subId, address(this));
}

/**
Expand Down Expand Up @@ -169,7 +183,11 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
uint32 _coordinatorGasOverhead,
uint8 _wrapperPremiumPercentage,
bytes32 _keyHash,
uint8 _maxNumWords
uint8 _maxNumWords,
uint32 stalenessSeconds,
int256 fallbackWeiPerUnitLink,
uint32 fulfillmentFlatFeeLinkPPM,
uint32 fulfillmentFlatFeeNativePPM
) external onlyOwner {
s_wrapperGasOverhead = _wrapperGasOverhead;
s_coordinatorGasOverhead = _coordinatorGasOverhead;
Expand All @@ -179,9 +197,10 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
s_configured = true;

// Get other configuration from coordinator
(, , s_stalenessSeconds, ) = COORDINATOR.s_config();
s_fallbackWeiPerUnitLink = COORDINATOR.s_fallbackWeiPerUnitLink();
(s_fulfillmentFlatFeeLinkPPM, s_fulfillmentFlatFeeNativePPM) = COORDINATOR.s_feeConfig();
s_stalenessSeconds = stalenessSeconds;
s_fallbackWeiPerUnitLink = fallbackWeiPerUnitLink;
s_fulfillmentFlatFeeLinkPPM = fulfillmentFlatFeeLinkPPM;
s_fulfillmentFlatFeeNativePPM = fulfillmentFlatFeeNativePPM;
}

/**
Expand Down Expand Up @@ -356,7 +375,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
numWords: numWords,
extraArgs: "" // empty extraArgs defaults to link payment
});
uint256 requestId = COORDINATOR.requestRandomWords(req);
uint256 requestId = s_vrfCoordinator.requestRandomWords(req);
s_callbacks[requestId] = Callback({
callbackAddress: _sender,
callbackGasLimit: callbackGasLimit,
Expand All @@ -382,7 +401,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
numWords: _numWords,
extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: true}))
});
requestId = COORDINATOR.requestRandomWords(req);
requestId = s_vrfCoordinator.requestRandomWords(req);
s_callbacks[requestId] = Callback({
callbackAddress: msg.sender,
callbackGasLimit: _callbackGasLimit,
Expand Down Expand Up @@ -510,19 +529,3 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
_;
}
}

interface ExtendedVRFCoordinatorV2PlusInterface is IVRFCoordinatorV2Plus {
function s_config()
external
view
returns (
uint16 minimumRequestConfirmations,
uint32 maxGasLimit,
uint32 stalenessSeconds,
uint32 gasAfterPaymentCalculation
);

function s_fallbackWeiPerUnitLink() external view returns (int256);

function s_feeConfig() external view returns (uint32 fulfillmentFlatFeeLinkPPM, uint32 fulfillmentFlatFeeNativePPM);
}
6 changes: 5 additions & 1 deletion contracts/test/v0.8/foundry/vrf/VRFV2Wrapper.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ contract VRFV2PlusWrapperTest is BaseTest {
coordinatorGasOverhead, // coordinator gas overhead
0, // premium percentage
vrfKeyHash, // keyHash
10 // max number of words
10, // max number of words,
1, // stalenessSeconds
50000000000000000, // fallbackWeiPerUnitLink
0, // fulfillmentFlatFeeLinkPPM
0 // fulfillmentFlatFeeNativePPM
);
(
,
Expand Down
42 changes: 9 additions & 33 deletions core/gethwrappers/generated/vrfv2plus_wrapper/vrfv2plus_wrapper.go

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,6 @@ vrfv2plus_client: ../../contracts/solc/v0.8.6/VRFV2PlusClient.abi ../../contract
vrfv2plus_consumer_example: ../../contracts/solc/v0.8.6/VRFV2PlusConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusConsumerExample.bin 2c480a6d7955d33a00690fdd943486d95802e48a03f3cc243df314448e4ddb2c
vrfv2plus_malicious_migrator: ../../contracts/solc/v0.8.6/VRFV2PlusMaliciousMigrator.abi ../../contracts/solc/v0.8.6/VRFV2PlusMaliciousMigrator.bin e5ae923d5fdfa916303cd7150b8474ccd912e14bafe950c6431f6ec94821f642
vrfv2plus_reverting_example: ../../contracts/solc/v0.8.6/VRFV2PlusRevertingExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusRevertingExample.bin 34743ac1dd5e2c9d210b2bd721ebd4dff3c29c548f05582538690dde07773589
vrfv2plus_wrapper: ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.bin 47d42936e0e6a073ffcb2d5b766c5882cdfbb81462f58edb0bbdacfb3dd6ed32
vrfv2plus_wrapper: ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.bin af73d5757129d4de1d287716ecdc560427904bc2a68b7dace4e6b5ac02539a31
vrfv2plus_wrapper_consumer_example: ../../contracts/solc/v0.8.6/VRFV2PlusWrapperConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapperConsumerExample.bin d4ddf86da21b87c013f551b2563ab68712ea9d4724894664d5778f6b124f4e78
vrfv2plus_wrapper_load_test_consumer: ../../contracts/solc/v0.8.6/VRFV2PlusWrapperLoadTestConsumer.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapperLoadTestConsumer.bin 4e8dcc8f60568aa09cc1adc800a56161f46642edc77768c3efab222a30a0e5ae
5 changes: 5 additions & 0 deletions integration-tests/actions/vrfv2plus/vrfv2plus_steps.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
"github.com/smartcontractkit/chainlink/integration-tests/docker/test_env"
"github.com/smartcontractkit/chainlink/integration-tests/types/config/node"
"github.com/smartcontractkit/chainlink/v2/core/assets"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_upgraded_version"
chainlinkutils "github.com/smartcontractkit/chainlink/v2/core/utils"
Expand Down Expand Up @@ -379,6 +380,10 @@ func SetupVRFV2PlusWrapperEnvironment(
vrfv2plus_constants.WrapperPremiumPercentage,
keyHash,
vrfv2plus_constants.WrapperMaxNumberOfWords,
vrfv2plus_constants.StalenessSeconds,
assets.GWei(50_000_000).ToInt(),
vrfv2plus_constants.VRFCoordinatorV2_5FeeConfig.FulfillmentFlatFeeLinkPPM,
vrfv2plus_constants.VRFCoordinatorV2_5FeeConfig.FulfillmentFlatFeeNativePPM,
)
if err != nil {
return nil, nil, err
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/contracts/contract_vrf_models.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ type VRFCoordinatorV2PlusUpgradedVersion interface {

type VRFV2PlusWrapper interface {
Address() string
SetConfig(wrapperGasOverhead uint32, coordinatorGasOverhead uint32, wrapperPremiumPercentage uint8, keyHash [32]byte, maxNumWords uint8) error
SetConfig(wrapperGasOverhead uint32, coordinatorGasOverhead uint32, wrapperPremiumPercentage uint8, keyHash [32]byte, maxNumWords uint8, stalenessSeconds uint32, fallbackWeiPerUnitLink *big.Int, fulfillmentFlatFeeLinkPPM uint32, fulfillmentFlatFeeNativePPM uint32) error
GetSubID(ctx context.Context) (*big.Int, error)
}

Expand Down
15 changes: 14 additions & 1 deletion integration-tests/contracts/ethereum_vrfv2plus_contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,16 @@ func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) Address() string {
return v.address.Hex()
}

func (v *EthereumVRFV2PlusWrapper) SetConfig(wrapperGasOverhead uint32, coordinatorGasOverhead uint32, wrapperPremiumPercentage uint8, keyHash [32]byte, maxNumWords uint8) error {
func (v *EthereumVRFV2PlusWrapper) SetConfig(wrapperGasOverhead uint32,
coordinatorGasOverhead uint32,
wrapperPremiumPercentage uint8,
keyHash [32]byte,
maxNumWords uint8,
stalenessSeconds uint32,
fallbackWeiPerUnitLink *big.Int,
fulfillmentFlatFeeLinkPPM uint32,
fulfillmentFlatFeeNativePPM uint32,
) error {
opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
if err != nil {
return err
Expand All @@ -757,6 +766,10 @@ func (v *EthereumVRFV2PlusWrapper) SetConfig(wrapperGasOverhead uint32, coordina
wrapperPremiumPercentage,
keyHash,
maxNumWords,
stalenessSeconds,
fallbackWeiPerUnitLink,
fulfillmentFlatFeeLinkPPM,
fulfillmentFlatFeeNativePPM,
)
if err != nil {
return err
Expand Down

0 comments on commit 0d475b6

Please sign in to comment.