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

RNG Fallback #1782

Draft
wants to merge 3 commits into
base: dev
Choose a base branch
from
Draft

RNG Fallback #1782

wants to merge 3 commits into from

Conversation

jaybuidl
Copy link
Member

@jaybuidl jaybuidl commented Dec 11, 2024

This PR is a redo of #966 as it has deviated too much from dev. It is based atop the feat/chainlink-vrf-as-rng2 branch (PR #1778).

This PR introduces a composite RNG called RNGWithFallback responsible for the fallback logic.

This PR breaks the storage layout of the SortitionModule so it cannot be upgraded and will require a full redeploy.

The RNGs are permissioned to prevent 3rd parties from using up the funds on the RNG oracle accounts with Chainlink or Randomizer.

The RNGs do not support concurrent requests, it is not necessary since only 1 consumer is allowed (the sortition module), with the notable exception of some governance function triggering a re-request, which invalidates the previous one.

This PR introduces several ABI changes:

  • RNG interface renamed IRNG
  • Removal of the _block parameter from the IRNG interface which is not necessary for VRFs, only for the BlockHashRNG which now tracks the block numbers internally

PR-Codex overview

This PR primarily focuses on refactoring the random number generation system by introducing an IRNG interface and implementing various RNG contracts, including ChainlinkRNG. It also updates the deployment scripts and tests accordingly.

Detailed summary

  • Deleted RNG.sol.
  • Added IRNG.sol interface with requestRandomness and receiveRandomness functions.
  • Implemented ChainlinkRNG and RandomizerRNG contracts using IRNG.
  • Updated IncrementalNG and BlockHashRNG to inherit from IRNG.
  • Modified SortitionModule to use IRNG instead of RNG.
  • Adjusted deployment scripts to accommodate new RNG implementations.
  • Updated tests to reflect changes in RNG function calls.

The following files were skipped due to too many changes: contracts/deployments/arbitrumSepolia/ChainlinkVRFCoordinator.json, contracts/deployments/arbitrumSepoliaDevnet/ChainlinkVRFCoordinator.json, yarn.lock, contracts/deployments/arbitrumSepoliaDevnet/ChainlinkRNG.json

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • New Features

    • Introduced Chainlink Random Number Generator (RNG) functionality across various blockchain networks.
    • Added a new contract for Chainlink RNG with comprehensive governance and request management features.
    • Implemented a mock contract for testing the Chainlink VRF Coordinator.
  • Bug Fixes

    • Improved error handling and event emissions in RNG contracts.
  • Documentation

    • Updated ABI and deployment details for Chainlink contracts.
  • Chores

    • Updated package dependencies to include Chainlink contracts.
    • Enhanced Prettier configuration for Solidity file formatting.

Copy link
Contributor

coderabbitai bot commented Dec 11, 2024

Walkthrough

This pull request introduces several changes related to the implementation of random number generation (RNG) in the Kleros arbitration system. It includes the addition of a Chainlink RNG deployment script and the restructuring of existing RNG contracts to utilize an interface (IRNG). The changes encompass new contract definitions, modifications to deployment scripts, and updates to test files, ensuring a robust and flexible RNG mechanism that incorporates fallback strategies for enhanced reliability.

Changes

File Change Summary
contracts/deploy/00-chainlink-rng.ts Introduced a deployment script for Chainlink RNG, defining a deployArbitration function with network-specific configurations and error handling.
contracts/deploy/00-home-chain-arbitration-neo.ts Updated deployment logic for Neo chain arbitration contracts, added RandomizerRNG, and simplified parameters for contract deployments.
contracts/deploy/00-home-chain-arbitration-university.ts Removed import for KlerosCore, clarified deployment logic for KlerosCoreUniversity, and updated comments for clarity.
contracts/deploy/00-home-chain-arbitration.ts Modified deployment script for arbitration system, updated parameters for RandomizerRNG, and introduced conditional logic for contract interactions.
contracts/deploy/00-rng.ts Revised deployment logic for RNG, updated variable declarations, and changed network evaluation for deployment skipping.
contracts/deploy/upgrade-sortition-module.ts Removed RNG_LOOKAHEAD constant from deployment arguments, simplifying the upgrade process.
contracts/deployments/arbitrum/ChainlinkVRFCoordinator.json Added new JSON file for Chainlink VRF Coordinator with contract address and ABI.
contracts/deployments/arbitrumSepolia/ChainlinkVRFCoordinator.json New file defining ABI for Chainlink VRF Coordinator on Arbitrum Sepolia, including functions, events, and error types.
contracts/deployments/arbitrumSepoliaDevnet/ChainlinkRNG.json New file for Chainlink RNG contract with ABI and deployment parameters.
contracts/deployments/arbitrumSepoliaDevnet/ChainlinkVRFCoordinator.json New file defining ABI for Chainlink VRF Coordinator on Arbitrum Sepolia Devnet, detailing functions and events.
contracts/package.json Added dependency for @chainlink/contracts and reinstated @openzeppelin/contracts.
contracts/src/arbitration/SortitionModule.sol Updated initialize function to use IRNG interface, removing _rngLookahead parameter.
contracts/src/arbitration/SortitionModuleBase.sol Transitioned from RNG to IRNG, simplifying random number generation logic.
contracts/src/arbitration/SortitionModuleNeo.sol Updated initialize function to use IRNG, removing _rngLookahead.
contracts/src/rng/BlockhashRNG.sol Changed inheritance from RNG to IRNG, updated request logic to remove block parameters.
contracts/src/rng/ChainlinkRNG.sol New contract implementing Chainlink's VRF, includes governance and random number request functionalities.
contracts/src/rng/IRNG.sol New interface defining methods for RNG functionality.
contracts/src/rng/IncrementalNG.sol Updated to implement IRNG, simplifying method signatures.
contracts/src/rng/RNGWithFallback.sol New contract providing RNG with fallback functionality, allowing for multiple RNG implementations.
contracts/src/rng/RandomizerRNG.sol Updated to inherit from IRNG, clarified roles for governor and consumer, and simplified request handling.
contracts/src/rng/mock/ChainlinkVRFCoordinatorMock.sol New mock contract for testing Chainlink VRF interactions.
contracts/test/rng/index.ts Updated tests for IncrementalNG and BlockHashRNG, added new tests for ChainlinkRNG.
cspell.json Added new words to the spell checker configuration.
prettier-config/index.js Added Prettier plugin for Solidity formatting.

Possibly related issues

  • RNG fallback mechanism #1283: The changes address the need for an RNG fallback mechanism to ensure continuous operation, as the new RNGWithFallback contract provides a structured approach to handle RNG failures.

Possibly related PRs

  • Neo config and keeper bot #1746: This PR relates to the deployment logic and contract interactions relevant to the Kleros arbitration system, similar to the changes made in this PR regarding the Chainlink RNG.

Suggested labels

Type: Feature🗿, Package: Contracts

Poem

🐇 In the land of code where randomness reigns,
A new RNG hops through digital plains.
With Chainlink's magic, numbers now flow,
Fallbacks in place, let the randomness grow!
So cheer for the changes, let the contracts sing,
For in Kleros' world, RNG's the king! 🎉


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Experiment)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

netlify bot commented Dec 11, 2024

Deploy Preview for kleros-v2-university ready!

Name Link
🔨 Latest commit ec3cd79
🔍 Latest deploy log https://app.netlify.com/sites/kleros-v2-university/deploys/67596274bba00c00083771ca
😎 Deploy Preview https://deploy-preview-1782--kleros-v2-university.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

netlify bot commented Dec 11, 2024

Deploy Preview for kleros-v2-testnet ready!

Name Link
🔨 Latest commit ec3cd79
🔍 Latest deploy log https://app.netlify.com/sites/kleros-v2-testnet/deploys/675962749cf927000854ecb1
😎 Deploy Preview https://deploy-preview-1782--kleros-v2-testnet.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

netlify bot commented Dec 11, 2024

Deploy Preview for kleros-v2-neo ready!

Name Link
🔨 Latest commit ec3cd79
🔍 Latest deploy log https://app.netlify.com/sites/kleros-v2-neo/deploys/67596274262eb30008dff6fc
😎 Deploy Preview https://deploy-preview-1782--kleros-v2-neo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

codeclimate bot commented Dec 11, 2024

Code Climate has analyzed commit ec3cd79 and detected 11 issues on this pull request.

Here's the issue category breakdown:

Category Count
Complexity 2
Duplication 6
Style 3

View more on Code Climate.

@jaybuidl jaybuidl linked an issue Dec 11, 2024 that may be closed by this pull request
Copy link

netlify bot commented Dec 11, 2024

Deploy Preview for kleros-v2-testnet-devtools ready!

Name Link
🔨 Latest commit ec3cd79
🔍 Latest deploy log https://app.netlify.com/sites/kleros-v2-testnet-devtools/deploys/6759627412e3420008f49ca5
😎 Deploy Preview https://deploy-preview-1782--kleros-v2-testnet-devtools.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

🧹 Outside diff range and nitpick comments (9)
prettier-config/index.js (1)

25-25: Consider pinning the plugin version

To ensure consistent formatting across different environments and prevent unexpected changes, consider importing the plugin with a specific version.

-  plugins: [require("prettier-plugin-solidity")],
+  plugins: [require("[email protected]")],
contracts/src/rng/RandomizerRNG.sol (1)

21-21: Specify visibility for lastRequestId variable

The variable lastRequestId does not have an explicit visibility modifier. In Solidity, it's best practice to explicitly declare the visibility of state variables to avoid confusion.

Apply this diff to specify the visibility:

-    uint256 lastRequestId; // The last request ID.
+    uint256 public lastRequestId; // The last request ID.
contracts/src/rng/IncrementalNG.sol (1)

11-11: Consider making the state variable private

The number variable could be made private since it's only used internally. This would prevent external contracts from directly accessing the current state.

-    uint256 public number;
+    uint256 private number;
contracts/deploy/00-chainlink-rng.ts (1)

15-29: Consider environment-based key hash configuration

Hardcoding key hashes in the deployment script makes updates difficult. Consider moving these to environment variables or a configuration file.

// config/chainlink.json
{
  "keyHashes": {
    "ARBITRUM_ONE": {
      "2": "0x9e9e...",
      // ...
    }
  }
}
contracts/deploy/00-home-chain-arbitration.ts (1)

Line range hint 113-119: Consider failing deployment on currency rate errors

Swallowing errors during currency rate configuration could lead to a partially initialized system. Consider either:

  1. Allowing the error to propagate to fail the deployment
  2. Adding a deployment flag to control whether currency rate errors should be fatal
-  try {
     await changeCurrencyRate(core, await pnk.getAddress(), true, 12225583, 12);
     await changeCurrencyRate(core, await dai.getAddress(), true, 60327783, 11);
     await changeCurrencyRate(core, await weth.getAddress(), true, 1, 1);
-  } catch (e) {
-    console.error("failed to change currency rates:", e);
-  }
contracts/src/rng/mock/ChainlinkVRFCoordinatorMock.sol (2)

35-56: Consider adding reentrancy protection

The low-level call to the consumer could be exploited for reentrancy attacks. Although this is a mock contract, it's good practice to maintain security patterns.

 function fulfillRandomWords(uint256 _requestId, address _consumer, uint256[] memory _words) public {
+    // Save and delete request before the external call to prevent reentrancy
+    VRFV2PlusClient.RandomWordsRequest memory req = requests[_requestId];
+    delete requests[_requestId];
+
     if (requests[_requestId].subId == 0) {
         revert("nonexistent request");
     }
-    VRFV2PlusClient.RandomWordsRequest memory req = requests[_requestId];

     // ... rest of the function ...

-    delete (requests[_requestId]);
     emit RandomWordsFulfilled(_requestId, success);
 }

111-158: Consider making configuration values adjustable

The hardcoded configuration values might not cover all test scenarios. Consider making these values configurable through constructor parameters or setter functions to support diverse testing requirements.

+    uint16 private minimumRequestConfirmations = 3;
+    uint32 private maxGasLimit = 2000000;
+
+    function setRequestConfig(
+        uint16 _minimumRequestConfirmations,
+        uint32 _maxGasLimit
+    ) external {
+        minimumRequestConfirmations = _minimumRequestConfirmations;
+        maxGasLimit = _maxGasLimit;
+    }

     function getRequestConfig() external view returns (uint16, uint32, bytes32[] memory) {
-        return (3, 2000000, new bytes32[](0));
+        return (minimumRequestConfirmations, maxGasLimit, new bytes32[](0));
     }
contracts/deployments/arbitrumSepoliaDevnet/ChainlinkRNG.json (2)

216-228: Add events for critical parameter changes

The contract should emit events when critical parameters like keyHash and subscriptionId are modified to facilitate off-chain tracking and monitoring.

Add events for parameter changes:

+event KeyHashChanged(bytes32 oldKeyHash, bytes32 newKeyHash);
+event SubscriptionIdChanged(uint256 oldSubId, uint256 newSubId);

 function changeKeyHash(bytes32 _keyHash) external onlyByGovernor {
+    emit KeyHashChanged(keyHash, _keyHash);
     keyHash = _keyHash;
 }

 function changeSubscriptionId(uint256 _subscriptionId) external onlyByGovernor {
+    emit SubscriptionIdChanged(subscriptionId, _subscriptionId);
     subscriptionId = _subscriptionId;
 }

Also applies to: 242-254


558-568: Enhance constructor documentation

The constructor documentation should include information about the recommended ranges or constraints for the parameters.

Add parameter constraints to the documentation:

 * @param _callbackGasLimit The limit for how much gas to use for the callback request to the contract's fulfillRandomWords() function.
+* @dev Recommended range: 100,000-300,000 based on operation complexity
 * @param _requestConfirmations How many confirmations the Chainlink node should wait before responding.
+* @dev Recommended range: 3-200 confirmations. Higher values increase security but also latency
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 8cde978 and ec3cd79.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (25)
  • contracts/deploy/00-chainlink-rng.ts (1 hunks)
  • contracts/deploy/00-home-chain-arbitration-neo.ts (5 hunks)
  • contracts/deploy/00-home-chain-arbitration-university.ts (3 hunks)
  • contracts/deploy/00-home-chain-arbitration.ts (5 hunks)
  • contracts/deploy/00-rng.ts (4 hunks)
  • contracts/deploy/upgrade-sortition-module.ts (0 hunks)
  • contracts/deployments/arbitrum/ChainlinkVRFCoordinator.json (1 hunks)
  • contracts/deployments/arbitrumSepolia/ChainlinkVRFCoordinator.json (1 hunks)
  • contracts/deployments/arbitrumSepoliaDevnet/ChainlinkRNG.json (1 hunks)
  • contracts/deployments/arbitrumSepoliaDevnet/ChainlinkVRFCoordinator.json (1 hunks)
  • contracts/package.json (1 hunks)
  • contracts/src/arbitration/SortitionModule.sol (1 hunks)
  • contracts/src/arbitration/SortitionModuleBase.sol (5 hunks)
  • contracts/src/arbitration/SortitionModuleNeo.sol (1 hunks)
  • contracts/src/rng/BlockhashRNG.sol (1 hunks)
  • contracts/src/rng/ChainlinkRNG.sol (1 hunks)
  • contracts/src/rng/IRNG.sol (1 hunks)
  • contracts/src/rng/IncrementalNG.sol (1 hunks)
  • contracts/src/rng/RNG.sol (0 hunks)
  • contracts/src/rng/RNGWithFallback.sol (1 hunks)
  • contracts/src/rng/RandomizerRNG.sol (6 hunks)
  • contracts/src/rng/mock/ChainlinkVRFCoordinatorMock.sol (1 hunks)
  • contracts/test/rng/index.ts (3 hunks)
  • cspell.json (2 hunks)
  • prettier-config/index.js (1 hunks)
💤 Files with no reviewable changes (2)
  • contracts/src/rng/RNG.sol
  • contracts/deploy/upgrade-sortition-module.ts
✅ Files skipped from review due to trivial changes (2)
  • cspell.json
  • contracts/deployments/arbitrum/ChainlinkVRFCoordinator.json
👮 Files not reviewed due to content moderation or server errors (3)
  • contracts/src/arbitration/SortitionModuleBase.sol
  • contracts/deployments/arbitrumSepolia/ChainlinkVRFCoordinator.json
  • contracts/deployments/arbitrumSepoliaDevnet/ChainlinkVRFCoordinator.json
🔇 Additional comments (22)
prettier-config/index.js (1)

25-25: Verify prettier-plugin-solidity installation

The plugin needs to be available as a dev dependency for the configuration to work.

✅ Verification successful

Plugin is properly installed and available

The prettier-plugin-solidity is correctly installed as a dependency in both prettier-config/package.json and contracts/package.json with version ^1.4.1. The plugin will be available when Prettier runs since it's properly declared in the dependencies.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if prettier-plugin-solidity is properly installed
# Expected: Find the plugin in package.json and node_modules

# Check package.json for the dependency
echo "Checking package.json for prettier-plugin-solidity..."
jq '.devDependencies["prettier-plugin-solidity"]' package.json

# Check if the plugin exists in node_modules
echo "Checking if plugin directory exists..."
fd -t d "prettier-plugin-solidity$" node_modules

Length of output: 424


Script:

#!/bin/bash
# Let's check if package.json exists and examine its dependencies section
echo "Checking if package.json exists and its content..."
if [ -f "package.json" ]; then
    cat package.json
else
    echo "package.json not found"
fi

# Let's also check if there are any other package.json files in the repository
echo -e "\nSearching for all package.json files..."
fd "package.json$"

Length of output: 2874


Script:

#!/bin/bash
# Let's check the prettier-config package.json and its dependencies
echo "Checking prettier-config/package.json..."
cat prettier-config/package.json

# Also check if the plugin is mentioned in any other workspace package.json files
echo -e "\nChecking for prettier-plugin-solidity in other package.json files..."
rg "prettier-plugin-solidity" --type json

Length of output: 1003

contracts/src/rng/RNGWithFallback.sol (1)

86-109: Ensure secure governor address updates

When changing the governor via changeGovernor, it's crucial to validate the new address to prevent assigning an unintended or malicious address.

Run the following script to check for proper governor address assignment:

✅ Verification successful

Governor address update is properly secured

The changeGovernor function already implements the necessary security check by validating that the new governor address is not zero (require(_newGovernor != address(0), "Invalid governor")), and the function is protected by the onlyByGovernor modifier which ensures only the current governor can execute this change.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the governor address is not zero and is correctly updated.

# Search for instances where governor is set. Expect validations against zero address.
rg -A 2 'function changeGovernor' contracts/src/rng/RNGWithFallback.sol

Length of output: 247

contracts/src/rng/ChainlinkRNG.sol (1)

159-162: Confirm secure access control in fulfillRandomWords

While fulfillRandomWords relies on inherited access control, it's important to ensure that only the Chainlink VRF Coordinator can invoke it.

Run the following script to verify access control inheritance:

✅ Verification successful

Access control for fulfillRandomWords is properly implemented

The function is correctly protected through multiple security layers:

  1. It's declared as internal override, meaning it can only be called from within the contract or inherited contracts
  2. The contract inherits from VRFConsumerBaseV2Plus, which implements the core access control in rawFulfillRandomWords
  3. The implementation matches Chainlink's VRF v2.5 security model where only the verified VRF Coordinator can call this function
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Confirm that fulfillRandomWords is correctly protected.

# Expect: fulfillRandomWords is declared internal and cannot be called externally.
ast-grep --pattern 'function fulfillRandomWords$_(uint256 $_, uint256[] calldata $_) internal override' contracts/src/rng/ChainlinkRNG.sol

Length of output: 140


Script:

#!/bin/bash
# Let's try a broader pattern to catch the function declaration
ast-grep --pattern 'function fulfillRandomWords' contracts/src/rng/ChainlinkRNG.sol

# Also get the full context of the contract to understand inheritance
cat contracts/src/rng/ChainlinkRNG.sol

Length of output: 7893

contracts/src/rng/IRNG.sol (1)

10-12: ⚠️ Potential issue

Add view modifier to receiveRandomness

The receiveRandomness function should be marked as view since it does not modify state.

Apply this diff:

     /// @dev Receive the random number.
     /// @return randomNumber Random Number. If the number is not ready or has not been required 0 instead.
-    function receiveRandomness() external returns (uint256 randomNumber);
+    function receiveRandomness() external view returns (uint256 randomNumber);

Likely invalid or redundant comment.

contracts/src/rng/IncrementalNG.sol (1)

25-27: Verify unchecked arithmetic safety

The unchecked increment is safe here since:

  1. It's used for generating sequential numbers
  2. Even if it overflows, it would continue the sequence from 0
contracts/src/arbitration/SortitionModule.sol (2)

40-42: Storage layout changes require redeployment

The removal of _rngLookahead parameter and change from RNG to IRNG affects storage layout. As mentioned in PR objectives, this requires redeployment of the module.

✅ Verification successful

Based on the code analysis, I can now generate the final response:

Storage layout changes require redeployment - Confirmed

The removal of _rngLookahead parameter and change from RNG to IRNG affects storage layout as evidenced by:

  1. The rngLookahead storage variable is marked as deprecated with a warning comment: // uint256 public rngLookahead; // Deprecated - WARNING: it breaks the storage layout of the contract, beta cannot be upgraded!
  2. The base contract's storage layout has been modified by removing this variable.
  3. The initialization function signature has been changed to remove this parameter.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify storage layout changes

# Check storage layout in current implementation
ast-grep --pattern 'contract SortitionModuleBase {
  $$$
  IRNG $_;
  $$$
}'

# Check for any remaining references to RNG interface
rg "RNG[^I]" --type sol

Length of output: 132


Script:

#!/bin/bash
# Let's try a different approach to verify storage layout changes

# Check for RNG-related storage variables and inheritance
ast-grep --pattern 'contract SortitionModule$_? {
  $$$
}'

# Look for storage variables in base contracts
ast-grep --pattern 'contract SortitionModuleBase {
  $$$
}'

# Search for RNG-related code with proper file extension
rg "RNG[^I]" -t solidity

# Check inheritance chain
rg "contract SortitionModule.*is.*" -t solidity

Length of output: 265


Script:

#!/bin/bash
# Let's try without file type filtering since ripgrep doesn't recognize solidity extension

# Find all Solidity files first
fd "\.sol$" contracts/src/

# Then use these patterns on all files
rg "contract SortitionModule.*is.*"
rg "RNG[^I]"

# Look for storage-related changes in git diff
git diff origin/main -- contracts/src/arbitration/SortitionModule.sol

Length of output: 86560


Script:

#!/bin/bash
# Let's check the file content directly to verify storage layout changes

# Check the current file content
cat contracts/src/arbitration/SortitionModule.sol

# Check the base contract content
cat contracts/src/arbitration/SortitionModuleBase.sol

# Check the interface definition
cat contracts/src/arbitration/interfaces/ISortitionModule.sol

Length of output: 35127


Line range hint 48-52: Verify upgrade safety

The UUPS upgrade pattern is correctly implemented with governor-only access. However, ensure that all contracts in the inheritance chain are upgrade-safe.

contracts/deploy/00-rng.ts (2)

44-44: Verify network check logic change

The deployment skip condition has been modified to use isMainnet. Ensure this doesn't accidentally enable deployments on unintended networks.

✅ Verification successful

Let me analyze the network validation logic further by checking the implementation of these utility functions.


Network validation logic is safe and correctly implemented

The change to use isMainnet is actually more restrictive than the previous validation. The isMainnet function checks for the presence of a "production" tag, which means deployments will only run on networks explicitly tagged as production environments. This is safer than the previous approach that was using HomeChains enum check, as it adds an additional layer of protection against accidental deployments.

Key validation points:

  • isMainnet relies on explicit production tags rather than chain IDs
  • The skip condition in the RNG deployment will prevent deployment on any network tagged as production
  • Other deployment scripts use complementary validation with HomeChains enum for additional safety
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check network validation

# Look for network validation patterns
rg "isMainnet|HomeChains" --type ts

Length of output: 6938


Script:

#!/bin/bash
# Check the implementation of isSkipped and related network validation functions
cat contracts/deploy/utils/index.ts

Length of output: 1080


18-19: Verify SortitionModule deployment prerequisite

The script assumes SortitionModuleNeo is already deployed. Ensure deployment dependencies are properly ordered.

contracts/src/rng/BlockhashRNG.sol (2)

13-15: ⚠️ Potential issue

Storage layout changes require careful migration

The contract's storage layout has changed significantly with the introduction of new state variables:

  • lookahead (immutable)
  • requestBlock
  • randomNumbers mapping

This change makes the contract incompatible with upgrades and requires redeployment, as mentioned in the PR objectives.


23-24: ⚠️ Potential issue

Potential race condition in requestRandomness

The function overwrites requestBlock without checking if there's an existing pending request. This could lead to a race condition if governance functions trigger a re-request.

contracts/src/arbitration/SortitionModuleNeo.sol (1)

50-54: ⚠️ Potential issue

Storage layout changes require redeployment

The change from RNG to IRNG type and removal of _rngLookahead parameter alters the storage layout, making this contract incompatible with upgrades.

Let's verify the storage layout changes:

contracts/deploy/00-home-chain-arbitration-university.ts (2)

56-56: LGTM: Safe placeholder usage

Using ZeroAddress as a placeholder is acceptable here since the comment indicates that KlerosCore is configured later.


Line range hint 66-73: Improved core change handling with validation

Good improvement to check the current core before making changes, avoiding unnecessary transactions.

contracts/package.json (1)

107-109: Verify dependency versions for security

New dependencies added:

  • @chainlink/contracts@^1.3.0
  • @openzeppelin/contracts@^5.1.0

Let's check for known vulnerabilities:

✅ Verification successful

Based on the results from the verification scripts, I can now generate a final response:

Dependencies appear to be properly integrated and used

The verification shows:

  1. Chainlink contracts are used appropriately for VRF (Verifiable Random Function) implementation in ChainlinkRNG.sol
  2. OpenZeppelin contracts are widely used across the codebase in a standard way
  3. No immediate security concerns are visible in the implementation

The dependencies are:

  • @chainlink/contracts@^1.3.0 - Used for VRF functionality
  • @openzeppelin/contracts@^5.1.0 - Used for standard contract patterns
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for known vulnerabilities in new dependencies

# Check npm for known vulnerabilities
npm audit --json @chainlink/contracts@^1.3.0 @openzeppelin/contracts@^5.1.0 | jq '.vulnerabilities'

# Check GitHub security advisories
gh api graphql -f query='
{
  securityVulnerabilities(first: 5, ecosystem: NPM, package: "chainlink__contracts") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
      firstPatchedVersion {
        identifier
      }
    }
  }
}'

Length of output: 811


Script:

#!/bin/bash
# Let's try a different approach to check the dependencies

# First, let's check if these packages are actually used in the codebase
echo "=== Checking @chainlink/contracts usage ==="
rg -l "@chainlink/contracts" --type-add 'sol:*.sol'

echo -e "\n=== Checking @openzeppelin/contracts usage ==="
rg -l "@openzeppelin/contracts" --type-add 'sol:*.sol'

# Let's also check the package versions in the lock file if it exists
echo -e "\n=== Checking package-lock.json ==="
if [ -f "contracts/package-lock.json" ]; then
    cat contracts/package-lock.json | jq '.packages["@chainlink/contracts"], .packages["@openzeppelin/contracts"]'
fi

# Let's check if there's a yarn.lock
echo -e "\n=== Checking yarn.lock ==="
if [ -f "contracts/yarn.lock" ]; then
    cat contracts/yarn.lock | grep -A 5 "@chainlink/contracts"
    echo "---"
    cat contracts/yarn.lock | grep -A 5 "@openzeppelin/contracts"
fi

Length of output: 4908


Script:

#!/bin/bash
# Let's examine the actual usage of these dependencies in the code

echo "=== Checking Chainlink contracts usage patterns ==="
rg -C 2 "VRFCoordinator" --type-add 'sol:*.sol' contracts/

echo -e "\n=== Checking OpenZeppelin contracts usage patterns ==="
# Look for common OZ patterns
rg -l "import.*@openzeppelin/contracts/(access|token|utils|security)/" --type-add 'sol:*.sol' contracts/

# Check specific versions in use
echo -e "\n=== Checking current dependency versions ==="
if [ -f "contracts/package.json" ]; then
    jq '.dependencies | select(has("@chainlink/contracts") or has("@openzeppelin/contracts"))' contracts/package.json
fi

# Let's also check the commit history for any recent security-related changes
echo -e "\n=== Checking recent security-related commits ==="
git log --oneline -n 10 contracts/package.json

Length of output: 66699

contracts/deploy/00-home-chain-arbitration.ts (2)

104-110: LGTM! Efficient configuration update

The conditional update of the RNG's consumer prevents unnecessary transactions and gas costs by checking the current state before making changes.


39-41: Verify initialization sequence for RandomizerRNG

The deployment uses ZeroAddress as a placeholder for SortitionModule, which is configured later. This is a safe approach, but we should verify that the contract cannot be used before proper initialization.

✅ Verification successful

Initialization sequence for RandomizerRNG is properly secured

The contract has adequate safeguards for initialization and usage:

  • The initialize function properly sets the consumer address during initialization
  • The onlyByConsumer modifier ensures only the authorized consumer can request randomness
  • The consumer can only be changed by the governor through changeConsumer
  • The requestRandomness function is protected by onlyByConsumer modifier
  • The callback function is protected by checking the sender is the randomizer contract
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if RandomizerRNG has safeguards against usage before initialization
ast-grep --pattern 'function $FUNC($$$) {
  $$$
  require($CONSUMER != address(0), $$$);
  $$$
}'

Length of output: 99


Script:

#!/bin/bash
# Let's first find the RandomizerRNG contract implementation
fd -e sol -e vy "RandomizerRNG"

# Then examine its content for zero address checks and initialization patterns
rg -l "RandomizerRNG" --type sol

Length of output: 128


Script:

#!/bin/bash
# Search for require statements and modifiers in RandomizerRNG
rg "require\(" -A 2 -B 2 --type sol

Length of output: 65


Script:

#!/bin/bash
# Look for initialization or setup functions
ast-grep --pattern 'function set$_($$$) {
  $$$
}'

Length of output: 52


Script:

#!/bin/bash
# Search for constructor implementation
ast-grep --pattern 'constructor($$$) {
  $$$
}'

Length of output: 49


Script:

#!/bin/bash
# Let's examine the RandomizerRNG contract content directly
cat contracts/src/rng/RandomizerRNG.sol

Length of output: 5380


Script:

#!/bin/bash
# Search for require statements without file type specification
rg "require\(" -A 2 -B 2

Length of output: 66851


Script:

#!/bin/bash
# Look for functions that might use the consumer address
rg "consumer" -A 2 -B 2 contracts/src/rng/RandomizerRNG.sol

Length of output: 1011

contracts/deploy/00-home-chain-arbitration-neo.ts (1)

98-104: Same issues as in home-chain-arbitration.ts

This file contains the same patterns as 00-home-chain-arbitration.ts:

  1. The RNG consumer configuration pattern is correct
  2. The error handling for currency rates should be improved

Also applies to: 107-112

contracts/src/rng/mock/ChainlinkVRFCoordinatorMock.sol (2)

1-30: LGTM! Well-structured mock implementation

The contract properly implements the VRF coordinator interface with appropriate storage and events.


58-73: LGTM! Clean implementation

The request handling is straightforward and appropriate for testing purposes.

contracts/deployments/arbitrumSepoliaDevnet/ChainlinkRNG.json (2)

490-491: Review the callback gas limit configuration

The callback gas limit is set to 100,000 which might be insufficient for complex operations in the fulfillRandomWords function, especially if the consumer contract performs significant computation or storage operations.

Consider:

  1. Analyzing gas usage in test environments
  2. Implementing a safety margin (e.g., 200,000-300,000) to handle varying gas costs
  3. Documenting the gas requirement analysis
✅ Verification successful

Callback gas limit of 100,000 is sufficient for this implementation

The current callback gas limit of 100,000 is adequate for the ChainlinkRNG contract's fulfillRandomWords implementation because:

  1. The function performs minimal operations:

    • A single storage write to randomNumbers[_requestId]
    • Emitting a single event with two parameters
  2. The implementation has no complex computations, loops, or external calls that would require significant gas.

  3. Similar storage operations typically consume around 20,000-25,000 gas, and event emissions around 2,000-3,000 gas, leaving a comfortable safety margin for the VRF callback.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check typical gas usage patterns for VRF callbacks

# Search for fulfillRandomWords implementations to analyze complexity
ast-grep --pattern 'function fulfillRandomWords($_, $_) {
  $$$
}'

# Look for storage operations in fulfillRandomWords
rg -A 5 "fulfillRandomWords.*{" 

Length of output: 208


Script:

#!/bin/bash
# Let's try a different approach to analyze the VRF callback implementation

# Search for fulfillRandomWords function implementation
ast-grep --pattern 'function fulfillRandomWords'

# Search for VRF-related files and contracts
fd -e sol -e json . | xargs rg -l "fulfillRandomWords"

# Check for gas-related configurations in source files
rg -i "callbackgas|gaslimit" -A 3

Length of output: 68149


Script:

#!/bin/bash
# Let's analyze the fulfillRandomWords implementation in ChainlinkRNG contract

# Search for fulfillRandomWords implementation
rg -p "function fulfillRandomWords.*\{" contracts/src/rng/ChainlinkRNG.sol -A 10

# Check for storage operations in the implementation
rg -p "randomNumbers\[.*\].*=" contracts/src/rng/ChainlinkRNG.sol

# Look for any gas-related comments or documentation
rg -p "gas|Gas" contracts/src/rng/ChainlinkRNG.sol

Length of output: 1771


484-491: Verify the governor configuration

The governor and sortitionModule are set to the same address in the constructor arguments, which might indicate a misconfiguration.

Comment on lines 124 to 129
/// @param _id The ID of the request.
/// @param _value The random value answering the request.
function randomizerCallback(uint256 _id, bytes32 _value) external {
require(msg.sender == address(randomizer), "Randomizer only");
randomNumbers[_id] = uint256(_value);
emit RequestFulfilled(_id, uint256(_value));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Validate request IDs in randomizerCallback function

The randomizerCallback function does not check if the _id corresponds to an active request. This could lead to unexpected behavior if unsolicited callbacks are received.

Apply this diff to add validation:

     function randomizerCallback(uint256 _id, bytes32 _value) external {
         require(msg.sender == address(randomizer), "Randomizer only");
+        require(randomNumbers[_id] == 0, "Random number already stored");
         randomNumbers[_id] = uint256(_value);
         emit RequestFulfilled(_id, uint256(_value));
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/// @param _id The ID of the request.
/// @param _value The random value answering the request.
function randomizerCallback(uint256 _id, bytes32 _value) external {
require(msg.sender == address(randomizer), "Randomizer only");
randomNumbers[_id] = uint256(_value);
emit RequestFulfilled(_id, uint256(_value));
/// @param _id The ID of the request.
/// @param _value The random value answering the request.
function randomizerCallback(uint256 _id, bytes32 _value) external {
require(msg.sender == address(randomizer), "Randomizer only");
require(randomNumbers[_id] == 0, "Random number already stored");
randomNumbers[_id] = uint256(_value);
emit RequestFulfilled(_id, uint256(_value));

Comment on lines 116 to 121
/// @dev Request a random number. Consumer only.
function requestRandomness() external override onlyByConsumer {
uint256 requestId = randomizer.request(callbackGasLimit);
lastRequestId = requestId;
emit RequestSent(requestId);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Handle multiple pending randomness requests to prevent overwriting

If requestRandomness is called multiple times before previous requests are fulfilled, lastRequestId will be overwritten. This means only the latest request ID is tracked, potentially causing loss of previous random numbers.

Consider modifying the contract to handle multiple pending requests. You can map request IDs to their corresponding consumers or track multiple request IDs.

Apply this diff to store multiple request IDs:

-    uint256 lastRequestId; // The last request ID.
+    uint256[] public requestIds; // Array of request IDs.

     mapping(uint256 requestId => uint256 number) public randomNumbers; // randomNumbers[requestID] is the random number for this request id, 0 otherwise.

     function requestRandomness() external override onlyByConsumer {
         uint256 requestId = randomizer.request(callbackGasLimit);
-        lastRequestId = requestId;
+        requestIds.push(requestId);
         emit RequestSent(requestId);
     }

     function receiveRandomness() external view override returns (uint256 randomNumber) {
-        randomNumber = randomNumbers[lastRequestId];
+        if (requestIds.length > 0) {
+            uint256 lastRequestId = requestIds[requestIds.length - 1];
+            randomNumber = randomNumbers[lastRequestId];
+        } else {
+            randomNumber = 0;
+        }
     }

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +62 to +65
function requestRandomness() external override {
require(!isRequesting, "Request already in progress");
_requestRandomness();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add access control to requestRandomness function

The requestRandomness function is publicly accessible and can be called by anyone. If it's intended that only a specific consumer should request randomness, consider adding access control to this function.

Apply this diff to restrict access:

+    address public consumer; // The address that can request random numbers.

+    modifier onlyByConsumer() {
+        require(msg.sender == consumer, "Consumer only");
+        _;
+    }

     /// @dev Request a random number from the default RNG
-    function requestRandomness() external override {
+    function requestRandomness() external override onlyByConsumer {
         require(!isRequesting, "Request already in progress");
         _requestRandomness();
     }

+    /// @dev Changes the consumer of the RNG.
+    /// @param _consumer The new consumer.
+    function changeConsumer(address _consumer) external onlyByGovernor {
+        require(_consumer != address(0), "Invalid consumer");
+        consumer = _consumer;
+    }

Committable suggestion skipped: line range outside the PR's diff.


contract IncrementalNG is RNG {
contract IncrementalNG is IRNG {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Consider adding access control to RNG operations

While this is a fallback RNG, according to PR objectives, RNGs should be permissioned to prevent unauthorized access. Consider adding access control to requestRandomness and receiveRandomness.

 contract IncrementalNG is IRNG {
+    address public consumer;
+    error UnauthorizedConsumer();
+
+    modifier onlyConsumer() {
+        if (msg.sender != consumer) revert UnauthorizedConsumer();
+        _;
+    }
+
+    constructor(uint256 _start, address _consumer) {
+        number = _start;
+        consumer = _consumer;
+    }
+
-    function requestRandomness() external override {
+    function requestRandomness() external override onlyConsumer {
         // nop
     }

-    function receiveRandomness() external override returns (uint256 randomNumber) {
+    function receiveRandomness() external override onlyConsumer returns (uint256 randomNumber) {

Also applies to: 18-18, 24-24

@@ -24,7 +26,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)

const rng1 = await deployUpgradable(deployments, "RandomizerRNG", {
from: deployer,
args: [randomizerOracle.address, deployer],
args: [deployer, sortitionModule.target, randomizerOracle.address],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Based on the search results, I can now generate the final response since I have found the RandomizerRNG contract implementation which shows that it has both governor and consumer as separate addresses in its storage:

Constructor arguments need to be updated to match contract state

The deployment script passes deployer as both the owner and consumer, but the contract has separate storage variables for these roles. The constructor should receive distinct addresses for:

  • governor: The address that can withdraw funds and manage the contract
  • consumer: The address that can request random numbers
🔗 Analysis chain

Verify RandomizerRNG constructor arguments

The deployment passes deployer as both the owner and the consumer (via constructor). Ensure this aligns with the permissioning requirements.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check RandomizerRNG constructor

# Look for RandomizerRNG constructor
ast-grep --pattern 'contract RandomizerRNG {
  $$$
  constructor($$$) {
    $$$
  }
  $$$
}'

Length of output: 94


Script:

#!/bin/bash
# Search for RandomizerRNG contract and constructor implementation
rg -U "contract RandomizerRNG.*?constructor.*?\{.*?\}" -A 10

Length of output: 65599


Script:

#!/bin/bash
# Search for RandomizerRNG.sol file
fd -e sol -x cat {} | grep -A 20 "contract RandomizerRNG"

Length of output: 1970

Comment on lines +35 to 40
it("Should return a non-zero number for a block number", async () => {
const tx = await rng.receiveRandomness();
const trace = await network.provider.send("debug_traceTransaction", [tx.hash]);
const [rn] = abiCoder.decode(["uint"], ethers.getBytes(`${trace.returnValue}`));
expect(rn).to.not.equal(0);
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Insufficient test coverage for BlockHashRNG

The test only verifies non-zero return but doesn't cover:

  1. Fallback mechanism
  2. Multiple requests
  3. Error cases
  4. Lookahead parameter validation

Consider adding these test cases:

it("should use fallback when block is too old", async () => {
  await rng.requestRandomness();
  // Mine 257 blocks to force fallback
  await network.provider.send("hardhat_mine", ["0x101"]);
  const tx = await rng.receiveRandomness();
  // Verify fallback event and mechanism
});

it("should respect lookahead parameter", async () => {
  await rng.requestRandomness();
  // Verify can't receive before lookahead blocks
});

Comment on lines 56 to 69
it("Should return a non-zero random number", async () => {
const requestId = 1;
const expectedRn = BigInt(
ethers.keccak256(ethers.AbiCoder.defaultAbiCoder().encode(["uint256", "uint256"], [requestId, 0]))
);

let tx = await rng.requestRandomness();
await expect(tx).to.emit(rng, "RequestSent").withArgs(requestId);

tx = await vrfCoordinator.fulfillRandomWords(requestId, rng.target, []);
await expect(tx).to.emit(rng, "RequestFulfilled").withArgs(requestId, expectedRn);

const rn = await rng.receiveRandomness();
expect(rn).to.equal(expectedRn);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance ChainlinkRNG test coverage

While the basic happy path is tested, consider adding:

  1. Error handling for coordinator failures
  2. Multiple request scenarios
  3. Request ID collision handling
it("should handle coordinator failures", async () => {
  const requestId = 1;
  await rng.requestRandomness();
  await expect(
    vrfCoordinator.fulfillRandomWords(requestId, rng.target, [])
  ).to.be.revertedWith("specific error message");
});

Comment on lines 59 to 61
deployer,
deployer, // For testing only, it should be the SortitionModule
ChainlinkVRFCoordinator.target,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Security concern: Deployer address used as consumer

The script uses the deployer address as both the owner and consumer (commented as "For testing only"). This could be dangerous if deployed to production.

-      deployer,
-      deployer, // For testing only, it should be the SortitionModule
+      deployer, // owner
+      process.env.SORTITION_MODULE_ADDRESS || deployer, // consumer
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
deployer,
deployer, // For testing only, it should be the SortitionModule
ChainlinkVRFCoordinator.target,
deployer, // owner
process.env.SORTITION_MODULE_ADDRESS || deployer, // consumer
ChainlinkVRFCoordinator.target,

Comment on lines 53 to 54
const requestConfirmations = 200; // between 1 and 200 L2 blocks
const callbackGasLimit = 100000;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Based on the gathered information, I can now generate the final response:

Gas configuration values need adjustment for L2 networks

The current configuration needs to be modified:

  • requestConfirmations = 200 is set to the maximum allowed value, which may cause unnecessary delays on L2s where blocks are produced faster
  • callbackGasLimit = 100000 appears low for the callback which stores random numbers and emits events

Recommendations:

  • For Arbitrum, reduce requestConfirmations to ~20-50 blocks since L2 blocks are produced more frequently
  • Increase callbackGasLimit to at least 200,000 to ensure sufficient gas for storage operations and event emissions
🔗 Analysis chain

Verify gas limit configuration

The hardcoded values for requestConfirmations and callbackGasLimit need validation:

  1. Is 200 blocks appropriate for all networks?
  2. Is 100,000 gas sufficient for the callback?
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for VRF callback implementations to estimate gas usage
ast-grep --pattern 'function fulfillRandomWords($_, $_) {
  $$$
}'

Length of output: 68


Script:

#!/bin/bash
# Search for VRF callback implementations with ripgrep
rg -U "function fulfillRandomWords.*?\{.*?\}" -A 20

# Search for any gas limit configurations across the codebase
rg -i "gasLimit|gaslimit" -A 2

# Search for requestConfirmations across the codebase
rg "requestConfirmations" -A 2

Length of output: 65968


Script:

#!/bin/bash
# Search for VRF callback implementations in Solidity files
rg -t sol "fulfillRandomWords.*?\{" -A 10

# Search for any VRF configuration documentation or comments
rg -i "vrf.*config|chain.*vrf" -A 2

# Search for any test files that might show gas usage patterns
rg -t ts "ChainlinkRNG" -A 5

Length of output: 63104

Comment on lines 203 to 254
{
"inputs": [
{
"internalType": "address",
"name": "_governor",
"type": "address"
}
],
"name": "changeGovernor",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "_keyHash",
"type": "bytes32"
}
],
"name": "changeKeyHash",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint16",
"name": "_requestConfirmations",
"type": "uint16"
}
],
"name": "changeRequestConfirmations",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_sortitionModule",
"type": "address"
}
],
"name": "changeSortitionModule",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add zero-address validation in setter functions

The changeSortitionModule and related setter functions lack zero-address validation, which could lead to contract lockout if misconfigured.

Add zero-address checks similar to other functions:

 function changeSortitionModule(address _sortitionModule) external onlyByGovernor {
+    if (_sortitionModule == address(0)) revert ZeroAddress();
     sortitionModule = _sortitionModule;
 }

Committable suggestion skipped: line range outside the PR's diff.

@jaybuidl jaybuidl changed the base branch from dev to feat/chainlink-vrf-as-rng2 December 11, 2024 11:41
@jaybuidl jaybuidl removed a link to an issue Dec 12, 2024
@jaybuidl jaybuidl force-pushed the feat/chainlink-vrf-as-rng2 branch 2 times, most recently from 770d1c0 to 9e0f05b Compare December 13, 2024 19:02
Base automatically changed from feat/chainlink-vrf-as-rng2 to dev December 13, 2024 21:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant