kleros-v2
kleros-v2 copied to clipboard
RNG: Chainlink VRF + Fallback mechanism
This PR implements the Chainlink VRF Mechanism using the Subscription Method.
Rationale Subscription Method vs Direct Funding
Cost Efficiency
The Subscription Method reduces the gas cost of using VRF by pre-funding the subscription account with LINK when the direct funding method needs to calculate the cost of the request and fund it before actually making the request.
It is particularly efficient when many requests are made, which is the case as a random number is generated whenever jurors are drawn.
Simplified Management
Using a subscription centralizes the management:
- A UI is provided to monitor the different requests made and their state.
- LINK tokens funding is directed toward a single contract rather than each consumer (in case of having multiple consumers, i.e. multiple functionality where random number generation is needed).
- The same applies to withdrawing. Withdrawing LINK tokens only has to be done from the subscription, not the consumers.
Scalability
One subscription can support up to 100 consuming contracts. It allows for potential future expansion, which may require random number generation.
Contracts
VRFConsumerV2.sol
VRF Consumer tailored to the SortitionModule.
It inherits from VRFConsumerBaseV2.sol, provided by Chainlink
Compared to the RandomizerRNG, only the SortitionModule can make a request, and the callback function calls sortitionModule.passPhase()
once the random number is ready.
Implementation doc: Chainlink - Get a random number
VRFSubscriptionManagerV2.sol
A contract allowing programmatic management of the VRF subscription.
Without this contract, the subscription must be managed through the Subscription Manager UI.
A subscription is created in the constructor.
Implementation doc: Chainlink - Programmatic Subscription
Mock Contracts
To locally test the contract, we need to emulate the Chainlink VRF Coordinator.
VRFCoordinatorV2Mock.sol
This coordinator is provided by Chainlink: VRFCoordinationV2Mock.sol
VRFSubscriptionManagerV2Mock
The mock coordinator doesn't use LINK tokens, and the interface is different from the coordinator on public networks. Therefore a Subscription Manager mock had to be done.
Implementation doc: Chainlink - Local testing using a Mock contract
Deployment
The deployment scripts which deployed the Randomizer are 00-rng.ts and 00-home-chain-arbitration.ts.
I updated them to also deploy the VRFConsumerV2 and the VRFSubscriptionManagerV2Mock on the different networks.
The deployment scripts don't change the SortitionModule rng source (SortitionModule.changeRandomNumberGenerator(address rngAddress, uint256 rngLookAhead)
), which is deployed with Randomizer as rng source.
Parameters
Most parameters are network-dependent (e.g. address of the vrf coordinator) but some have to be defined:
KeyHash
Gas lane: The maximum gas price you are willing to pay for a request in wei. Define this limit by specifying the appropriate keyHash in your request. The limits of each gas lane are important for handling gas price spikes when Chainlink VRF bumps the gas price to fulfill your request quickly.
Network | Available key hashes |
---|---|
Arbitrum One | 2 gwei, 30 gwei, 150 gwei |
Arbitrum Goerli | 50 gwei |
localhost | irrelevant |
I've set it to 30 gwei as it is the medium lane.
callbackGasLimit
Callback gas limit: Specifies the maximum amount of gas you are willing to spend on the callback request. Define this limit by specifying the callbackGasLimit value in your request.
The Randomizer sets a callbackGasLimit to 50 000, as the VRFConsumerV2 callback function makes an external call to sortitionModule.passPhase()
, I chose to set it at 100 000.
requestConfirmations
requestConfirmations
: How many confirmations the Chainlink node should wait before responding. The longer the node waits, the more secure the random value is.
The range on Arbitrum: 1 - 200. I've arbitrarily set it to 3.
numWords
How many random values to request. If you can use several random values in a single callback, you can reduce the amount of gas that you spend per random value. The total cost of the callback request depends on how your fulfillRandomWords() function processes and stores the received random values, so adjust your callbackGasLimit accordingly.
I've set it to 1, as only one random number is needed to draw jurors.
Public Networks
- Deploy VRFSubscriptionManagerV2
- Deploy VRFConsumerV2
- Add the deployed VRFConsumerV2 as a consumer of the subscription
Funds need to be added to the subscription.
Localhost
- Deploy VRFSubscriptionManagerV2
- Fund the subscription with 100 LINK (arbitrary amount)
- Deploy VRFConsumerV2
- Add the deployed VRFConsumerV2 as a consumer of the subscription
Hardhat Task - Credit LINK
To fund the subscription with LINK on public networks (Arbitrum One & Arbitrum Goerli), I wrote a hardhat task that transfers amountInWei
LINK tokens from the deployer to the VRFSubscriptionManagerV2, which then funds the subscription by calling VRFSubscriptionManagerV2.topUpSubscription(amountInWei)
.
The amount
passed as a parameter is "normal values" (e.g. 100 LINK), and not in wei to avoid errors. The amountInWei
is computed from it.
Tests
Local tests making use of the Randomizer are arbitration/draw.ts, arbitration/unstake.ts, and integrations/index.ts.
I duplicated the tests, the first running with the default rng source (Randomizer from deployment) and the copy changing the rng source to VRFConsumerV2 and accordingly using it. (Mock contracts: VRFCoordinator triggered manually in the test).
PR-Codex overview
This PR introduces a fallback mechanism for receiving randomness and updates Chainlink VRF interactions.
Detailed summary
- Added a
receiveRandomnessFallback
function to RNG contracts. - Updated RNG configuration in
deploy/upgrade-sortition-module.ts
. - Added Chainlink VRF functionality in
scripts/creditLink.ts
. - Modified tests to include Chainlink VRF interactions.
- Updated
SortitionModule.sol
withrngFallbackTimeout
parameter.
The following files were skipped due to too many changes:
contracts/src/arbitration/SortitionModule.sol
,contracts/test/arbitration/draw.ts
,contracts/src/rng/interfaces/VRFCoordinatorV2Interface.sol
,contracts/src/rng/mock/VRFSubscriptionManagerV2Mock.sol
,contracts/deploy/00-home-chain-arbitration.ts
,contracts/src/rng/VRFSubscriptionManagerV2.sol
,contracts/src/rng/VRFConsumerBaseV2.sol
,contracts/test/integration/index.ts
,contracts/src/rng/mock/VRFCoordinatorV2Mock.sol
,contracts/src/rng/VRFConsumerV2.sol
β¨ Ask PR-Codex anything about this PR by commenting with
/codex {your question}
Deploy Preview for kleros-v2-contracts ready!
Name | Link |
---|---|
Latest commit | 2149884ef61983cb4533e774fa0f90ba9f8fd236 |
Latest deploy log | https://app.netlify.com/sites/kleros-v2-contracts/deploys/64944bcf8e730e00084ade81 |
Deploy Preview | https://deploy-preview-966--kleros-v2-contracts.netlify.app |
Preview on mobile | Toggle QR Code...Use your smartphone camera to open QR code link. |
To edit notification comments on pull requests, go to your Netlify site settings.
Deploy Preview for kleros-v2 ready!
Name | Link |
---|---|
Latest commit | 4b69a12487750766398258e84a3fcee4ce8fa861 |
Latest deploy log | https://app.netlify.com/sites/kleros-v2/deploys/65f05e84db9c0c0008547c19 |
Deploy Preview | https://deploy-preview-966--kleros-v2.netlify.app |
Preview on mobile | Toggle QR Code...Use your smartphone camera to open QR code link. |
To edit notification comments on pull requests, go to your Netlify site configuration.
Kudos, SonarCloud Quality Gate passed!Β Β
0 Bugs
0 Vulnerabilities
0 Security Hotspots
7 Code Smells
No Coverage information
0.0% Duplication
Code Climate has analyzed commit 04286933 and detected 63 issues on this pull request.
Here's the issue category breakdown:
Category | Count |
---|---|
Complexity | 3 |
Duplication | 26 |
Style | 34 |
View more on Code Climate.
Kudos, SonarCloud Quality Gate passed!Β Β
0 Bugs
0 Vulnerabilities
0 Security Hotspots
5 Code Smells
No Coverage information
0.0% Duplication
RNG lookahead is removed since it's not needed with this fallback setup. It won't be used by ChainlinkRNG itself and is irrelevant for BlockhashRNG since rngFallback
will ensure that enough time has passed when it'll be used.
Deploy Preview for kleros-v2-university ready!
Name | Link |
---|---|
Latest commit | 4b69a12487750766398258e84a3fcee4ce8fa861 |
Latest deploy log | https://app.netlify.com/sites/kleros-v2-university/deploys/65f05e84b7db2800082bb53a |
Deploy Preview | https://deploy-preview-966--kleros-v2-university.netlify.app |
Preview on mobile | Toggle QR Code...Use your smartphone camera to open QR code link. |
To edit notification comments on pull requests, go to your Netlify site configuration.