Skip to content

RNG Fallback #2054

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

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

RNG Fallback #2054

wants to merge 3 commits into from

Conversation

jaybuidl
Copy link
Member

@jaybuidl jaybuidl commented Jul 24, 2025

This PR is a redo of #966 and #1782 as they had deviated too much from dev. It was originally based atop the feat/chainlink-vrf-as-rng2 branch (PR #1778).

This PR introduces a RNGWithFallback responsible for the fallback logic.

We ensure that repeated calls to SM.passPhase() does not result in repeated calls to the default RNG or the fallback RNG as it would keep overwriting the requestID for VRF-based RNGs or the requestBlock for the BlockhashRNG.

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.

We rely on block.timestamp rather than block.number because it is a more reliable measure of the elapsed time on Arbitrum, as block production is sporadic depending on network conditions.

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 it internally

PR-Codex overview

This PR focuses on refactoring the random number generator (RNG) implementation in the Kleros arbitration system. It introduces a new interface IRNG, updates existing RNG contracts to use this interface, and modifies related deployment and testing code accordingly.

Detailed summary

  • Deleted contracts/src/rng/RNG.solcspell.json.
  • Introduced IRNG interface in contracts/src/rng/IRNG.sol.
  • Updated IncrementalNG, ChainlinkRNG, and RandomizerRNG to implement IRNG.
  • Changed method signatures in RNG contracts to remove block parameters.
  • Updated deployment scripts to remove RNG_LOOKAHEAD and adjust arguments.
  • Modified consumer and sortition module references in various contracts.
  • Removed lookahead logic from sortition module and tests.
  • Updated test cases to reflect changes in RNG request and response handling.
  • Adjusted logging statements for clarity in deployment scripts.

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

Summary by CodeRabbit

  • New Features

    • Introduced a unified random number generator interface (IRNG) and a fallback RNG contract for improved reliability.
    • Added explicit governance and consumer roles for RNG contracts with enhanced access control.
    • Provided user-facing deployment reminders for Chainlink RNG registration.
  • Refactor

    • Standardized RNG contract interfaces and removed deprecated timing parameters.
    • Updated contract and test logic to use timestamp-based randomness instead of block-based lookahead.
    • Renamed and simplified consumer roles and method names in RNG contracts for clarity.
  • Bug Fixes

    • Improved test reliability by removing redundant block mining and aligning test logic with new RNG mechanisms.
  • Documentation

    • Updated spell checker configuration to recognize new terminology.

@jaybuidl jaybuidl requested a review from a team as a code owner July 24, 2025 18:57
Copy link

netlify bot commented Jul 24, 2025

Deploy Preview for kleros-v2-testnet ready!

Name Link
🔨 Latest commit 937fb97
🔍 Latest deploy log https://app.netlify.com/projects/kleros-v2-testnet/deploys/6894b1bfdc2a9500084be4ad
😎 Deploy Preview https://deploy-preview-2054--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 project configuration.

Copy link

netlify bot commented Jul 24, 2025

Deploy Preview for kleros-v2-neo ready!

Name Link
🔨 Latest commit 937fb97
🔍 Latest deploy log https://app.netlify.com/projects/kleros-v2-neo/deploys/6894b1bf5597d10007ff1800
😎 Deploy Preview https://deploy-preview-2054--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 project configuration.

Copy link

netlify bot commented Jul 24, 2025

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

Name Link
🔨 Latest commit 937fb97
🔍 Latest deploy log https://app.netlify.com/projects/kleros-v2-testnet-devtools/deploys/6894b1c0b57b4c0008595c41
😎 Deploy Preview https://deploy-preview-2054--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 project configuration.

Copy link
Contributor

coderabbitai bot commented Jul 24, 2025

Walkthrough

This update refactors the random number generator (RNG) system throughout the codebase. It introduces a new IRNG interface, updates contracts to use IRNG instead of the deprecated RNG interface, removes block-based lookahead logic in favor of timestamp-based mechanisms, and updates deployment scripts and tests accordingly. Consumer roles and access control are clarified in RNG contracts.

Changes

Cohort / File(s) Change Summary
RNG Interface Migration
contracts/src/rng/IRNG.sol, contracts/src/rng/RNG.sol, contracts/src/rng/IncrementalNG.sol, contracts/src/rng/BlockhashRNG.sol, contracts/src/rng/ChainlinkRNG.sol, contracts/src/rng/RandomizerRNG.sol, contracts/src/rng/RNGWithFallback.sol
Introduces new IRNG interface; removes old RNG interface; updates all RNG contracts to implement IRNG; updates function signatures to remove block parameters; adds new fallback RNG contract.
Sortition Module Refactor
contracts/src/arbitration/SortitionModule.sol, contracts/src/arbitration/SortitionModuleBase.sol, contracts/src/arbitration/SortitionModuleNeo.sol
Updates import and usage to IRNG; removes rngLookahead parameter and related logic; updates initialization and RNG change functions accordingly.
Deployment Script Updates
contracts/deploy/00-home-chain-arbitration.ts, contracts/deploy/00-home-chain-arbitration-neo.ts, contracts/deploy/00-chainlink-rng.ts, contracts/deploy/00-rng.ts, contracts/deploy/change-sortition-module-rng.ts, contracts/deploy/00-home-chain-resolver.ts
Updates deployment logic to use IRNG and new constructor arguments; removes lookahead/block arguments; updates consumer/role assignment; minor logging and import cleanups.
Test Suite Refactor
contracts/test/arbitration/dispute-kit-gated.ts, contracts/test/arbitration/draw.ts, contracts/test/arbitration/staking-neo.ts, contracts/test/arbitration/staking.ts, contracts/test/foundry/KlerosCore.t.sol, contracts/test/integration/index.ts, contracts/test/rng/index.ts
Updates tests to match new IRNG interface; removes block mining/waiting for lookahead; updates contract deployment and interaction patterns; improves type usage in TypeScript tests.
Miscellaneous
cspell.json, contracts/test/proxy/index.ts
Adds "IRNG" to spell checker dictionary; minor import path clarification in proxy test.

Sequence Diagram(s)

sequenceDiagram
    participant Consumer as Consumer (e.g., SortitionModule)
    participant IRNG as IRNG Contract (e.g., BlockHashRNG)
    participant Governor as Governor

    Consumer->>IRNG: requestRandomness()
    Note right of IRNG: Records timestamp/request

    IRNG-->>Consumer: (after lookahead/timeout) receiveRandomness() → random number

    Governor->>IRNG: changeConsumer(address)
    IRNG-->>Governor: Consumer updated
Loading
sequenceDiagram
    participant Consumer as Consumer
    participant RNGWithFallback as RNGWithFallback
    participant IRNG as Primary IRNG

    Consumer->>RNGWithFallback: requestRandomness()
    RNGWithFallback->>IRNG: requestRandomness()

    Consumer->>RNGWithFallback: receiveRandomness()
    RNGWithFallback->>IRNG: receiveRandomness()
    alt IRNG returns valid number
        RNGWithFallback-->>Consumer: random number from IRNG
    else Timeout elapsed
        RNGWithFallback-->>Consumer: fallback to blockhash, emits RNGFallback
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

  • Shutterized Dispute Kit #1965: Adds and integrates the DisputeKitShutter contract, affecting arbitration modules and deployment, which overlap with the RNG and sortition module updates here.
  • Chainlink RNG #1778: Refactors deployment scripts and contract interactions for ChainlinkRNG, including method and argument changes that are continued or expanded in this PR.

Suggested labels

Type: Enhancement :sparkles:, Type: Bug :bug:

Suggested reviewers

  • unknownunknown1

Poem

A hop and a skip, a shuffle anew,
IRNG’s here—block numbers adieu!
No more lookahead, just time on the clock,
With fallback and consumer, the contracts now rock.
RNGs in a row, all neat and precise—
This bunny’s review says, “Code looks nice!” 🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/rng-fallback2

🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
  • 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 explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @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.

@jaybuidl jaybuidl mentioned this pull request Jul 24, 2025
@jaybuidl jaybuidl linked an issue Jul 24, 2025 that may be closed by this pull request
Copy link

netlify bot commented Jul 24, 2025

Deploy Preview for kleros-v2-university failed. Why did it fail? →

Name Link
🔨 Latest commit 937fb97
🔍 Latest deploy log https://app.netlify.com/projects/kleros-v2-university/deploys/6894b1bf55590c0008cae8fe

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: 0

🧹 Nitpick comments (3)
contracts/test/foundry/KlerosCore.t.sol (1)

276-278: Consider using consistent rngLookahead values across tests.

The test_initialize_events function uses rngLookahead = 20 while the main setUp uses 600. Consider using the same value for consistency, or add a comment explaining why a different value is needed for event testing.

-        rngLookahead = 20;
+        rngLookahead = 600; // Use consistent timing across tests
         rng = new BlockHashRNG(msg.sender, address(sortitionModule), rngLookahead);
contracts/test/rng/index.ts (1)

38-44: Consider using different addresses for governor and consumer in tests.

While using the same address for both roles works for testing, consider using different addresses to better simulate production scenarios and ensure role separation is properly tested.

-    const [deployer] = await ethers.getSigners();
+    const [deployer, consumer] = await ethers.getSigners();
     await deployments.delete("BlockHashRNG");
     await deployments.deploy("BlockHashRNG", {
       from: deployer.address,
-      args: [deployer.address, deployer.address, 10], // governor, consumer, lookaheadTime (seconds)
+      args: [deployer.address, consumer.address, 10], // governor, consumer, lookaheadTime (seconds)
     });
contracts/src/rng/RNGWithFallback.sol (1)

169-173: Document implications of emergencyReset.

While useful for recovery, emergencyReset could cause loss of pending randomness requests. Consider adding clear documentation about when this should be used and its implications.

 /// @dev Emergency reset the RNG.
 /// Useful for the governor to ensure that re-requesting a random number will not be blocked by a previous request.
+/// WARNING: This will clear any pending randomness requests, potentially causing loss of randomness.
+/// Only use in emergency situations when the RNG is stuck.
 function emergencyReset() external onlyByGovernor {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f4ed9a0 and 00a4cc5.

📒 Files selected for processing (26)
  • contracts/deploy/00-chainlink-rng.ts (1 hunks)
  • contracts/deploy/00-home-chain-arbitration-neo.ts (3 hunks)
  • contracts/deploy/00-home-chain-arbitration.ts (2 hunks)
  • contracts/deploy/00-home-chain-resolver.ts (0 hunks)
  • contracts/deploy/00-rng.ts (2 hunks)
  • contracts/deploy/change-sortition-module-rng.ts (1 hunks)
  • contracts/src/arbitration/SortitionModule.sol (2 hunks)
  • contracts/src/arbitration/SortitionModuleBase.sol (5 hunks)
  • contracts/src/arbitration/SortitionModuleNeo.sol (2 hunks)
  • contracts/src/rng/BlockhashRNG.sol (1 hunks)
  • contracts/src/rng/ChainlinkRNG.sol (8 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/test/arbitration/dispute-kit-gated.ts (1 hunks)
  • contracts/test/arbitration/draw.ts (1 hunks)
  • contracts/test/arbitration/staking-neo.ts (2 hunks)
  • contracts/test/arbitration/staking.ts (3 hunks)
  • contracts/test/foundry/KlerosCore.t.sol (34 hunks)
  • contracts/test/integration/index.ts (1 hunks)
  • contracts/test/proxy/index.ts (1 hunks)
  • contracts/test/rng/index.ts (5 hunks)
  • contracts/test/utils/getActualAddress.ts (1 hunks)
  • cspell.json (1 hunks)
💤 Files with no reviewable changes (2)
  • contracts/deploy/00-home-chain-resolver.ts
  • contracts/src/rng/RNG.sol
🧰 Additional context used
🧠 Learnings (24)
📓 Common learnings
Learnt from: jaybuidl
PR: kleros/kleros-v2#1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the `contracts/src/rng/ChainlinkRNG.sol` contract, the `requestRandomness` function is restricted to being called only by the `SortitionModule`, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.
contracts/deploy/00-chainlink-rng.ts (1)

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

contracts/test/utils/getActualAddress.ts (8)

Learnt from: jaybuidl
PR: #1620
File: contracts/test/arbitration/draw.ts:84-84
Timestamp: 2024-11-05T11:32:11.238Z
Learning: In TypeScript code using ethers.js version 6, contract.target should be used instead of contract.address to access a contract's address.

Learnt from: Harman-singh-waraich
PR: #1687
File: web/src/context/AtlasProvider.tsx:225-244
Timestamp: 2024-10-15T16:18:32.543Z
Learning: In web/src/context/AtlasProvider.tsx, the atlasUri variable comes from environment variables and does not change, so it does not need to be included in dependency arrays.

Learnt from: Harman-singh-waraich
PR: #1744
File: web/src/hooks/useGenesisBlock.ts:9-31
Timestamp: 2024-11-19T05:31:48.701Z
Learning: In useGenesisBlock.ts, within the useEffect hook, the conditions (isKlerosUniversity, isKlerosNeo, isTestnetDeployment) are mutually exclusive, so multiple imports won't execute simultaneously, and race conditions are not a concern.

Learnt from: Harman-singh-waraich
PR: #1727
File: web/src/utils/atlas/updateEmail.ts:34-37
Timestamp: 2024-10-28T12:20:19.884Z
Learning: In web/src/utils/atlas/updateEmail.ts, the error coming from the GraphQLError array already has the necessary structure, so additional specificity in error handling is unnecessary.

Learnt from: jaybuidl
PR: #1964
File: contracts/scripts/shutter.ts:3-3
Timestamp: 2025-04-30T22:12:25.476Z
Learning: In Node.js, importing the crypto module as import crypto from "crypto" is a valid approach when using methods like crypto.randomBytes(). This import style works fine and doesn't need to be changed to a destructured import when these methods are used.

Learnt from: Harman-singh-waraich
PR: #1703
File: kleros-sdk/src/dataMappings/utils/actionTypes.ts:1-1
Timestamp: 2024-10-22T09:38:20.093Z
Learning: In the TypeScript file kleros-sdk/src/dataMappings/utils/actionTypes.ts, the Abi type is parsed later in the action functions, so importing Abi from viem in this file is unnecessary.

Learnt from: Harman-singh-waraich
PR: #1703
File: kleros-sdk/src/sdk.ts:1-3
Timestamp: 2024-10-22T10:23:15.789Z
Learning: In kleros-sdk/src/sdk.ts, the PublicClient type is used and should not be flagged as unused.

Learnt from: Harman-singh-waraich
PR: #1703
File: kleros-sdk/src/requests/gqlClient.ts:18-18
Timestamp: 2024-10-24T08:16:02.749Z
Learning: In this TypeScript project, when a file (such as kleros-sdk/src/requests/gqlClient.ts) exports only a single entity, it's acceptable to use default exports instead of named exports.

contracts/test/arbitration/staking-neo.ts (9)

Learnt from: jaybuidl
PR: #1620
File: contracts/test/arbitration/draw.ts:84-84
Timestamp: 2024-11-05T11:32:11.238Z
Learning: In TypeScript code using ethers.js version 6, contract.target should be used instead of contract.address to access a contract's address.

Learnt from: jaybuidl
PR: #1746
File: contracts/config/courts.v2.mainnet-neo.json:167-170
Timestamp: 2024-11-19T16:31:08.965Z
Learning: In contracts/config/courts.v2.mainnet-neo.json, the minStake parameter is denominated in PNK, not ETH.

Learnt from: Harman-singh-waraich
PR: #1744
File: web/src/hooks/useGenesisBlock.ts:9-31
Timestamp: 2024-11-19T05:31:48.701Z
Learning: In useGenesisBlock.ts, within the useEffect hook, the conditions (isKlerosUniversity, isKlerosNeo, isTestnetDeployment) are mutually exclusive, so multiple imports won't execute simultaneously, and race conditions are not a concern.

Learnt from: jaybuidl
PR: #1746
File: contracts/config/courts.v2.mainnet-neo.json:3-5
Timestamp: 2024-11-19T17:18:39.007Z
Learning: In contracts/config/courts.v2.mainnet-neo.json, the General Court (id: 1) intentionally references itself as its parent ("parent": 1). This self-reference is acceptable and should not be flagged as an issue in future reviews.

Learnt from: Harman-singh-waraich
PR: #1703
File: kleros-sdk/src/sdk.ts:1-3
Timestamp: 2024-10-22T10:23:15.789Z
Learning: In kleros-sdk/src/sdk.ts, the PublicClient type is used and should not be flagged as unused.

Learnt from: Harman-singh-waraich
PR: #1703
File: kleros-sdk/src/requests/gqlClient.ts:18-18
Timestamp: 2024-10-24T08:16:02.749Z
Learning: In this TypeScript project, when a file (such as kleros-sdk/src/requests/gqlClient.ts) exports only a single entity, it's acceptable to use default exports instead of named exports.

Learnt from: Harman-singh-waraich
PR: #1846
File: prettier-config/index.js:26-26
Timestamp: 2025-01-23T08:14:47.397Z
Learning: The prettier-plugin-solidity plugin is installed in the kleros-v2 repository, even though it's not visible in the sandbox environment's node_modules (which is expected as node_modules is not committed to the repository).

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the SortitionModule can call requestRandomness, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

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

Learnt from: Harman-singh-waraich
PR: #1703
File: kleros-sdk/src/utils/getDispute.ts:38-40
Timestamp: 2024-10-21T10:32:16.970Z
Learning: The variables 'arbitrableChainID' and 'externalDisputeID' are required by the context to have uppercase 'ID', so they should remain unchanged even if the corresponding source properties use 'Id'.

Learnt from: jaybuidl
PR: #1746
File: contracts/config/courts.v2.mainnet-neo.json:3-5
Timestamp: 2024-11-19T17:18:39.007Z
Learning: In contracts/config/courts.v2.mainnet-neo.json, the General Court (id: 1) intentionally references itself as its parent ("parent": 1). This self-reference is acceptable and should not be flagged as an issue in future reviews.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Learnt from: Harman-singh-waraich
PR: #1744
File: web/src/hooks/useGenesisBlock.ts:9-31
Timestamp: 2024-11-19T05:31:48.701Z
Learning: In useGenesisBlock.ts, within the useEffect hook, the conditions (isKlerosUniversity, isKlerosNeo, isTestnetDeployment) are mutually exclusive, so multiple imports won't execute simultaneously, and race conditions are not a concern.

Learnt from: Harman-singh-waraich
PR: #1703
File: web/src/hooks/queries/usePopulatedDisputeData.ts:58-61
Timestamp: 2024-10-14T13:58:25.708Z
Learning: In web/src/hooks/queries/usePopulatedDisputeData.ts, the query and subsequent logic only execute when disputeData.dispute?.arbitrableChainId and disputeData.dispute?.externalDisputeId are defined, so initialContext properties based on these values are safe to use without additional null checks.

Learnt from: tractorss
PR: #1982
File: web/src/pages/Resolver/Landing/index.tsx:62-62
Timestamp: 2025-05-15T06:50:40.859Z
Learning: In the Landing component, it's safe to pass dispute?.dispute?.arbitrated.id as 0x${string} to usePopulatedDisputeData without additional null checks because the hook internally handles undefined parameters through its isEnabled flag and won't execute the query unless all required data is available.

Learnt from: jaybuidl
PR: #1746
File: contracts/config/courts.v2.mainnet-neo.json:167-170
Timestamp: 2024-11-19T16:31:08.965Z
Learning: In contracts/config/courts.v2.mainnet-neo.json, the minStake parameter is denominated in PNK, not ETH.

contracts/deploy/change-sortition-module-rng.ts (3)

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the SortitionModule can call requestRandomness, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

Learnt from: jaybuidl
PR: #1582
File: web-devtools/src/app/(main)/ruler/RulingModes.tsx:233-233
Timestamp: 2024-10-09T10:19:11.816Z
Learning: In 'web-devtools/src/app/(main)/ruler/RulingModes.tsx', the label 'Random Preset' is correct and should not be changed to 'Automatic Random'.

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

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the SortitionModule can call requestRandomness, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

Learnt from: Harman-singh-waraich
PR: #1744
File: web/src/hooks/useGenesisBlock.ts:9-31
Timestamp: 2024-11-19T05:31:48.701Z
Learning: In useGenesisBlock.ts, within the useEffect hook, the conditions (isKlerosUniversity, isKlerosNeo, isTestnetDeployment) are mutually exclusive, so multiple imports won't execute simultaneously, and race conditions are not a concern.

contracts/test/arbitration/staking.ts (6)

Learnt from: jaybuidl
PR: #1620
File: contracts/test/arbitration/draw.ts:84-84
Timestamp: 2024-11-05T11:32:11.238Z
Learning: In TypeScript code using ethers.js version 6, contract.target should be used instead of contract.address to access a contract's address.

Learnt from: jaybuidl
PR: #1746
File: contracts/config/courts.v2.mainnet-neo.json:167-170
Timestamp: 2024-11-19T16:31:08.965Z
Learning: In contracts/config/courts.v2.mainnet-neo.json, the minStake parameter is denominated in PNK, not ETH.

Learnt from: Harman-singh-waraich
PR: #1744
File: web/src/hooks/useGenesisBlock.ts:9-31
Timestamp: 2024-11-19T05:31:48.701Z
Learning: In useGenesisBlock.ts, within the useEffect hook, the conditions (isKlerosUniversity, isKlerosNeo, isTestnetDeployment) are mutually exclusive, so multiple imports won't execute simultaneously, and race conditions are not a concern.

Learnt from: Harman-singh-waraich
PR: #1703
File: kleros-sdk/src/requests/gqlClient.ts:18-18
Timestamp: 2024-10-24T08:16:02.749Z
Learning: In this TypeScript project, when a file (such as kleros-sdk/src/requests/gqlClient.ts) exports only a single entity, it's acceptable to use default exports instead of named exports.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Learnt from: Harman-singh-waraich
PR: #1846
File: prettier-config/index.js:26-26
Timestamp: 2025-01-23T08:14:47.397Z
Learning: The prettier-plugin-solidity plugin is installed in the kleros-v2 repository, even though it's not visible in the sandbox environment's node_modules (which is expected as node_modules is not committed to the repository).

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

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Learnt from: Harman-singh-waraich
PR: #1744
File: web/src/hooks/useGenesisBlock.ts:9-31
Timestamp: 2024-11-19T05:31:48.701Z
Learning: In useGenesisBlock.ts, within the useEffect hook, the conditions (isKlerosUniversity, isKlerosNeo, isTestnetDeployment) are mutually exclusive, so multiple imports won't execute simultaneously, and race conditions are not a concern.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the SortitionModule can call requestRandomness, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

contracts/test/arbitration/dispute-kit-gated.ts (5)

Learnt from: Harman-singh-waraich
PR: #1703
File: web/src/hooks/queries/usePopulatedDisputeData.ts:58-61
Timestamp: 2024-10-14T13:58:25.708Z
Learning: In web/src/hooks/queries/usePopulatedDisputeData.ts, the query and subsequent logic only execute when disputeData.dispute?.arbitrableChainId and disputeData.dispute?.externalDisputeId are defined, so initialContext properties based on these values are safe to use without additional null checks.

Learnt from: Harman-singh-waraich
PR: #1744
File: web/src/hooks/useGenesisBlock.ts:9-31
Timestamp: 2024-11-19T05:31:48.701Z
Learning: In useGenesisBlock.ts, within the useEffect hook, the conditions (isKlerosUniversity, isKlerosNeo, isTestnetDeployment) are mutually exclusive, so multiple imports won't execute simultaneously, and race conditions are not a concern.

Learnt from: Harman-singh-waraich
PR: #1716
File: web-devtools/src/app/(main)/dispute-template/CustomContextInputs.tsx:29-42
Timestamp: 2024-10-28T05:55:12.728Z
Learning: In the CustomContextInputs component located at web-devtools/src/app/(main)/dispute-template/CustomContextInputs.tsx, the DisputeRequestParams array is used to exclude certain variables from the custom input since they are already provided in a preceding component. Therefore, converting it to a type is unnecessary.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the SortitionModule can call requestRandomness, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

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

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the SortitionModule can call requestRandomness, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

Learnt from: Harman-singh-waraich
PR: #1744
File: web/src/hooks/useGenesisBlock.ts:9-31
Timestamp: 2024-11-19T05:31:48.701Z
Learning: In useGenesisBlock.ts, within the useEffect hook, the conditions (isKlerosUniversity, isKlerosNeo, isTestnetDeployment) are mutually exclusive, so multiple imports won't execute simultaneously, and race conditions are not a concern.

contracts/test/proxy/index.ts (3)

Learnt from: Harman-singh-waraich
PR: #1703
File: kleros-sdk/src/dataMappings/utils/actionTypes.ts:1-1
Timestamp: 2024-10-22T09:38:20.093Z
Learning: In the TypeScript file kleros-sdk/src/dataMappings/utils/actionTypes.ts, the Abi type is parsed later in the action functions, so importing Abi from viem in this file is unnecessary.

Learnt from: jaybuidl
PR: #1620
File: contracts/test/arbitration/draw.ts:84-84
Timestamp: 2024-11-05T11:32:11.238Z
Learning: In TypeScript code using ethers.js version 6, contract.target should be used instead of contract.address to access a contract's address.

Learnt from: Harman-singh-waraich
PR: #1703
File: kleros-sdk/src/requests/gqlClient.ts:18-18
Timestamp: 2024-10-24T08:16:02.749Z
Learning: In this TypeScript project, when a file (such as kleros-sdk/src/requests/gqlClient.ts) exports only a single entity, it's acceptable to use default exports instead of named exports.

contracts/test/integration/index.ts (7)

Learnt from: Harman-singh-waraich
PR: #1744
File: web/src/hooks/useGenesisBlock.ts:9-31
Timestamp: 2024-11-19T05:31:48.701Z
Learning: In useGenesisBlock.ts, within the useEffect hook, the conditions (isKlerosUniversity, isKlerosNeo, isTestnetDeployment) are mutually exclusive, so multiple imports won't execute simultaneously, and race conditions are not a concern.

Learnt from: Harman-singh-waraich
PR: #1703
File: kleros-sdk/src/sdk.ts:1-3
Timestamp: 2024-10-22T10:23:15.789Z
Learning: In kleros-sdk/src/sdk.ts, the PublicClient type is used and should not be flagged as unused.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Learnt from: Harman-singh-waraich
PR: #1703
File: kleros-sdk/src/requests/gqlClient.ts:18-18
Timestamp: 2024-10-24T08:16:02.749Z
Learning: In this TypeScript project, when a file (such as kleros-sdk/src/requests/gqlClient.ts) exports only a single entity, it's acceptable to use default exports instead of named exports.

Learnt from: jaybuidl
PR: #1964
File: contracts/scripts/shutter.ts:3-3
Timestamp: 2025-04-30T22:12:25.476Z
Learning: In Node.js, importing the crypto module as import crypto from "crypto" is a valid approach when using methods like crypto.randomBytes(). This import style works fine and doesn't need to be changed to a destructured import when these methods are used.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the SortitionModule can call requestRandomness, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

Learnt from: Harman-singh-waraich
PR: #1739
File: web/src/pages/Home/TopJurors/JurorCard/Coherency.tsx:22-26
Timestamp: 2024-11-07T10:48:16.774Z
Learning: In the Coherency component (web/src/pages/Home/TopJurors/JurorCard/Coherency.tsx), totalResolvedVotes is always greater than or equal to totalCoherentVotes. When both are zero, 0/0 results in NaN, which is acceptable in this context.

contracts/test/arbitration/draw.ts (6)

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Learnt from: jaybuidl
PR: #1582
File: web-devtools/src/app/(main)/ruler/RulingModes.tsx:233-233
Timestamp: 2024-10-09T10:19:11.816Z
Learning: In 'web-devtools/src/app/(main)/ruler/RulingModes.tsx', the label 'Random Preset' is correct and should not be changed to 'Automatic Random'.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the SortitionModule can call requestRandomness, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

Learnt from: jaybuidl
PR: #1746
File: contracts/config/courts.v2.mainnet-neo.json:167-170
Timestamp: 2024-11-19T16:31:08.965Z
Learning: In contracts/config/courts.v2.mainnet-neo.json, the minStake parameter is denominated in PNK, not ETH.

Learnt from: jaybuidl
PR: #1746
File: contracts/config/courts.v2.mainnet-neo.json:167-170
Timestamp: 2024-11-19T16:31:08.965Z
Learning: In the court hierarchy, child courts' minStake must be greater than or equal to their parent court's minStake.

Learnt from: Harman-singh-waraich
PR: #1744
File: web/src/hooks/useGenesisBlock.ts:9-31
Timestamp: 2024-11-19T05:31:48.701Z
Learning: In useGenesisBlock.ts, within the useEffect hook, the conditions (isKlerosUniversity, isKlerosNeo, isTestnetDeployment) are mutually exclusive, so multiple imports won't execute simultaneously, and race conditions are not a concern.

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

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the SortitionModule can call requestRandomness, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

contracts/src/arbitration/SortitionModuleBase.sol (2)

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the SortitionModule can call requestRandomness, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

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

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the SortitionModule can call requestRandomness, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

contracts/src/arbitration/SortitionModule.sol (2)

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the SortitionModule can call requestRandomness, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

contracts/test/foundry/KlerosCore.t.sol (3)

Learnt from: Harman-singh-waraich
PR: #1744
File: web/src/hooks/useGenesisBlock.ts:9-31
Timestamp: 2024-11-19T05:31:48.701Z
Learning: In useGenesisBlock.ts, within the useEffect hook, the conditions (isKlerosUniversity, isKlerosNeo, isTestnetDeployment) are mutually exclusive, so multiple imports won't execute simultaneously, and race conditions are not a concern.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the SortitionModule can call requestRandomness, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

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

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the SortitionModule can call requestRandomness, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

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

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the SortitionModule can call requestRandomness, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

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

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

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

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the SortitionModule can call requestRandomness, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

contracts/test/rng/index.ts (4)

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the contracts/src/rng/ChainlinkRNG.sol contract, the requestRandomness function is restricted to being called only by the SortitionModule, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Learnt from: jaybuidl
PR: #1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the SortitionModule can call requestRandomness, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

Learnt from: Harman-singh-waraich
PR: #1744
File: web/src/hooks/useGenesisBlock.ts:9-31
Timestamp: 2024-11-19T05:31:48.701Z
Learning: In useGenesisBlock.ts, within the useEffect hook, the conditions (isKlerosUniversity, isKlerosNeo, isTestnetDeployment) are mutually exclusive, so multiple imports won't execute simultaneously, and race conditions are not a concern.

Learnt from: Harman-singh-waraich
PR: #1744
File: web/src/hooks/queries/useHomePageBlockQuery.ts:71-71
Timestamp: 2024-11-19T05:29:56.238Z
Learning: In web/src/hooks/queries/useHomePageBlockQuery.ts, the non-null assertions on blockNumber! and genesisBlock! within queryFn are safe because isEnabled ensures that queryFn only runs when either blockNumber or genesisBlock is defined.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (15)
  • GitHub Check: Redirect rules - kleros-v2-testnet-devtools
  • GitHub Check: Redirect rules - kleros-v2-neo
  • GitHub Check: Header rules - kleros-v2-testnet-devtools
  • GitHub Check: Redirect rules - kleros-v2-testnet
  • GitHub Check: Redirect rules - kleros-v2-testnet
  • GitHub Check: Header rules - kleros-v2-neo
  • GitHub Check: Pages changed - kleros-v2-testnet-devtools
  • GitHub Check: Header rules - kleros-v2-testnet
  • GitHub Check: Header rules - kleros-v2-testnet
  • GitHub Check: Pages changed - kleros-v2-neo
  • GitHub Check: Pages changed - kleros-v2-testnet
  • GitHub Check: Pages changed - kleros-v2-testnet
  • GitHub Check: SonarCloud
  • GitHub Check: Analyze (javascript)
  • GitHub Check: contracts-testing
🔇 Additional comments (63)
contracts/test/proxy/index.ts (1)

7-8: Avoid deep-linking into typechain-types – prefer barrel exports for stability

Pointing directly to ../../typechain-types/src/proxy/mock/by-rewrite/UpgradedByRewrite.sol makes the test depend on the internal folder structure generated by TypeChain.
A future refactor (e.g. changing outDir, renaming the solidity file, or upgrading TypeChain) will break this path silently while the re-exported barrel ../../typechain-types would stay intact.

Two low-friction options:

-import { UpgradedByRewrite as UpgradedByRewriteV1 } from "../../typechain-types/src/proxy/mock/by-rewrite/UpgradedByRewrite.sol";
+import type { UpgradedByRewrite as UpgradedByRewriteV1 } from "../../typechain-types";

or add a manual re-export in typechain-types/index.ts during code-gen to expose the duplicate names cleanly (e.g. UpgradedByRewriteV1, UpgradedByRewriteV2).

Either keeps the import resilient and removes the brittle deep path.
[ suggest_optional_refactor ]

cspell.json (1)

38-38: LGTM! Necessary addition for the RNG interface refactoring.

Adding "IRNG" to the spell checker dictionary is correct and necessary to support the interface rename from RNG to IRNG throughout the codebase.

contracts/deploy/00-chainlink-rng.ts (1)

74-74: Good addition! Helpful deployment guidance.

Adding the console message with the Chainlink VRF registration link provides useful post-deployment guidance for users.

contracts/test/utils/getActualAddress.ts (1)

11-11: LGTM! Updated to modern import assertion syntax.

The change from assert: { type: "json" } to with: { type: "json" } aligns with the current JavaScript/TypeScript standard for import assertions.

contracts/test/arbitration/dispute-kit-gated.ts (2)

64-64: LGTM! Correctly updated for simplified RNG interface.

The method call now correctly passes only the RNG address, reflecting the removal of the RNG lookahead parameter from the interface.


141-144: LGTM! Simplified block mining logic.

The removal of the RNG lookahead-based block mining loop and replacement with single block mining correctly reflects the interface changes where timing is now based on timestamps rather than block lookahead.

contracts/test/arbitration/staking-neo.ts (2)

59-65: LGTM! Improved TypeScript type safety.

Using generic type parameters with ethers.getContract<T>() is cleaner and provides better type safety than explicit type assertions.


108-108: LGTM! Correctly simplified block mining logic.

The change from mining multiple blocks based on RNG lookahead to mining a single block correctly reflects the removal of the lookahead parameter from the RNG interface.

contracts/test/arbitration/draw.ts (2)

84-84: LGTM: Simplified RNG configuration call

The removal of the second argument from changeRandomNumberGenerator correctly aligns with the new IRNG interface that eliminates the lookahead parameter.


177-177: LGTM: Simplified phase transition logic

The removal of the block mining loop that previously handled RNG lookahead is correct. The new IRNG interface no longer requires block-based timing, making this simplification appropriate.

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

1-13: LGTM: Well-designed RNG interface

The new IRNG interface is clean and simplified compared to the previous RNG interface. The removal of block-based parameters and the clear function signatures align well with the PR objectives. The documentation is appropriate and the interface follows Solidity best practices.

contracts/deploy/change-sortition-module-rng.ts (2)

26-27: LGTM: Updated to use new consumer role method

The change from changeSortitionModule to changeConsumer correctly reflects the refactoring of RNG contracts where the authorized role was renamed from sortitionModule to consumer.


29-30: LGTM: Simplified RNG configuration

The removal of the second argument from changeRandomNumberGenerator is consistent with the elimination of the lookahead parameter in the new IRNG interface.

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

10-10: LGTM: Transition to time-based lookahead

The change from RNG_LOOKAHEAD (block-based) to RNG_LOOKAHEAD_TIME (time-based) with a 30-minute value aligns with the RNG refactoring that moves away from block-based timing mechanisms.


34-38: LGTM: Updated BlockHashRNG constructor arguments

The constructor arguments correctly reflect the new BlockHashRNG interface that takes a governor, consumer, and time-based lookahead parameter instead of the previous block-based approach.


42-42: LGTM: Simplified sortition module configuration

The single-argument call to changeRandomNumberGenerator is consistent with the removal of the lookahead parameter from the sortition module interface.

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

55-55: LGTM: Updated SortitionModule constructor

The removal of the RNG lookahead parameter from the SortitionModule constructor correctly aligns with the interface changes that eliminate block-based timing dependencies.


88-93: LGTM: Improved RNG consumer management

The change to use changeConsumer instead of changeSortitionModule is correct, and the conditional check before calling the method is a good optimization that avoids unnecessary transactions.

contracts/test/integration/index.ts (1)

206-208: LGTM! Improved type safety with explicit parameter typing.

The explicit typing of the function parameter enhances type safety and makes the expected structure clear, which is a good practice in TypeScript.

contracts/src/arbitration/SortitionModule.sol (3)

5-5: LGTM! Interface abstraction improvement.

The change from concrete RNG type to IRNG interface provides better abstraction and aligns with the PR's objective to introduce a composite RNG with fallback logic.


32-32: LGTM! Parameter updated to match new interface.

The change from RNG to IRNG parameter and removal of _rngLookahead aligns with the PR objectives to use the new IRNG interface and remove block-based lookahead logic.


34-34: LGTM! Base initializer call updated correctly.

The removal of _rngLookahead parameter from the base initializer call is consistent with the function signature changes and the broader refactor to remove block-based RNG timing.

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

13-13: LGTM! Cleanup of unused deployment method.

Removing the unused execute method from the destructured deployments object improves code clarity by only importing what's needed.


52-52: LGTM! Deployment arguments updated to match contract changes.

The removal of RNG_LOOKAHEAD parameter from the SortitionModuleNeo deployment arguments correctly aligns with the contract's updated initialize() function signature.


86-91: LGTM! RNG linkage updated to use consumer pattern.

The changes from changeSortitionModule/sortitionModule() to changeConsumer/consumer() correctly implement the new RNG consumer role pattern mentioned in the PR objectives.

contracts/test/arbitration/staking.ts (3)

30-34: LGTM! Improved TypeScript contract retrieval with generics.

Using TypeScript generics instead of type casting provides better type safety and is more idiomatic. This is a good improvement over the previous as ContractType approach.


57-57: LGTM! Block mining simplified after RNG lookahead removal.

The single evm_mine call replaces the previous lookahead-based block mining logic, correctly reflecting the shift from block-based to time-based randomness readiness.


394-395: LGTM! Consistent simplification of block mining logic.

The single block mine after phase transition maintains consistency with the updated RNG timing model throughout the test suite.

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

5-5: LGTM! Import statement updated consistently with interface refactor.

The change to import IRNG interface instead of concrete RNG type follows the same pattern as SortitionModule.sol and supports the overall interface abstraction effort.


42-42: LGTM! Parameter signature updated consistently with base module.

The change from RNG to IRNG parameter and removal of _rngLookahead maintains consistency with SortitionModule.sol while preserving the Neo-specific parameters.


46-46: LGTM! Base initializer call updated to match interface changes.

The removal of _rngLookahead parameter from the base initializer call is consistent with the updated SortitionModuleBase interface and follows the same pattern as SortitionModule.sol.

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

4-4: LGTM! Interface import updated correctly.

The import has been properly updated to use the new IRNG interface.


6-9: LGTM! Contract declaration and comments updated appropriately.

The contract now correctly implements the IRNG interface instead of inheriting from the deprecated RNG class. The comments have been updated to reflect the simplified interface.


17-19: LGTM! Function signature simplified correctly.

The requestRandomness() function signature has been properly simplified by removing the unused _block parameter, aligning with the new IRNG interface. The no-op implementation remains appropriate for this testing contract.


23-27: LGTM! Function signature simplified correctly.

The receiveRandomness() function signature has been properly simplified by removing the unused _block parameter. The incremental logic remains intact and appropriate for testing purposes.

contracts/src/arbitration/SortitionModuleBase.sol (5)

10-10: LGTM! Import updated to new IRNG interface.

The import has been correctly updated to use the new IRNG interface.


54-54: LGTM! Storage variable type updated correctly.

The rng storage variable has been properly updated to use the IRNG interface type.


105-105: LGTM! Constructor parameter updated correctly.

The constructor parameter has been properly updated to accept an IRNG instance instead of the deprecated RNG type.


152-159: LGTM! Function updated with simplified RNG interface.

The changeRandomNumberGenerator function has been correctly updated:

  • Parameter type changed to IRNG
  • Function name and comments updated appropriately
  • Call to requestRandomness() simplified by removing the block parameter

The logic maintains the same behavior while using the simplified interface.


172-172: LGTM! RNG method calls simplified correctly.

The calls to requestRandomness() and receiveRandomness() have been properly simplified by removing the block parameters, aligning with the new IRNG interface. This removes the unnecessary block-based timing complexity while maintaining the same phase transition logic.

Also applies to: 175-175

contracts/test/foundry/KlerosCore.t.sol (6)

55-55: Comment accurately reflects the time-based approach.

The comment update from block-based to time-based properly documents the semantic change in the RNG lookahead mechanism.


95-96: Significant increase in RNG lookahead time.

The rngLookahead value has been increased from 20 to 600 seconds (10 minutes), which is a more realistic timing for RNG operations. This aligns with the shift to timestamp-based randomness and should provide adequate time for RNG fulfillment in production-like scenarios.


106-111: Simplified SortitionModule initialization.

The removal of rngLookahead from the SortitionModule initialization parameters correctly reflects the architectural change where RNG timing is now managed at the RNG contract level rather than the consumer level.


116-117: Proper RNG consumer linkage with governor privileges.

The explicit changeConsumer call with governor privileges correctly implements the new RNG permission model, ensuring only authorized consumers can request randomness.


287-298: Consistent RNG initialization pattern in event tests.

The initialization sequence correctly follows the new pattern: first initialize the SortitionModule, then link it as the RNG consumer with governor privileges.


1006-1006: Consistent implementation of timestamp-based RNG readiness.

All instances of vm.roll(block.number + rngLookahead + 1) have been correctly replaced with vm.warp(block.timestamp + rngLookahead), implementing the shift from block-based to timestamp-based RNG mechanics throughout the test suite.

Also applies to: 1053-1053, 1080-1080, 1136-1136, 1424-1424, 1483-1483, 1526-1526, 1636-1636, 1661-1661, 1772-1772, 1799-1799, 1840-1840, 1889-1889, 1979-1979, 2023-2023, 2119-2119, 2197-2197, 2231-2231, 2243-2243, 2349-2349, 2424-2424, 2470-2470, 2525-2525, 2615-2615, 2669-2669, 2708-2708, 2762-2762, 2805-2805, 2899-2899

contracts/test/rng/index.ts (3)

24-30: LGTM! Test correctly updated for new IRNG interface.

The removal of numeric arguments from receiveRandomness calls aligns with the simplified IRNG interface.


96-109: LGTM! ChainlinkRNG tests properly updated.

Good use of the shared abiCoder instance and correct removal of unused parameters.


155-202: LGTM! RandomizerRNG tests correctly updated.

Tests properly handle the simplified interface and maintain good coverage for both single and multiple request scenarios.

contracts/src/rng/RandomizerRNG.sol (3)

5-10: LGTM! Correct interface migration to IRNG.

The contract properly implements the new IRNG interface as part of the broader RNG refactoring.


16-16: LGTM! Consumer role properly implemented.

The migration from sortitionModule to consumer is complete and consistent throughout the contract, maintaining proper access control.

Also applies to: 44-47, 54-62, 74-78


102-107: LGTM! Randomness functions correctly simplified.

The removal of block parameters aligns with the IRNG interface. The lack of concurrent request handling is acceptable as confirmed by previous learnings that only the SortitionModule (now consumer) calls these functions without concurrent requests.

Also applies to: 124-126

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

8-12: LGTM! Proper interface implementation and consistent event naming.

The contract correctly implements IRNG while maintaining Chainlink VRF integration through VRFConsumerBaseV2Plus inheritance. Event parameter naming is consistent.

Also applies to: 32-38


18-18: LGTM! Consumer role properly implemented with correct access control.

The migration from sortitionModule to consumer is complete and maintains proper authorization checks.

Also applies to: 49-52, 94-98


135-153: LGTM! VRF v2.5 integration with native ETH payment.

The implementation correctly uses Chainlink VRF v2.5 with native ETH payment enabled. The lack of concurrent request handling aligns with the design constraint that only one consumer makes requests.

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

13-50: LGTM! Well-structured contract with appropriate L2 considerations.

Good use of immutable for lookaheadTime and clear role separation. The timestamp-based approach is appropriate for L2 environments with sporadic block production.


109-119: LGTM! Useful view functions for checking randomness readiness.

The view functions properly handle the case where no request has been made and provide clear information about when randomness will be available.


79-101: Ignore blockhash and timestamp‐collision concerns

The two raised issues don’t apply here:

  • Using blockhash(block.number - 1) always returns the hash of the immediately previous block, which is guaranteed to be within the last 256 blocks, so it will never be 0 due to the EVM’s 256-block limit.
  • The contract only tracks a single outstanding request via requestTimestamp (overwritten on each call) and restricts calls to the designated consumer, so you cannot have concurrent requests mapping to the same key—no collision risk.

No changes needed.

Likely an incorrect or invalid review comment.

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

42-49: LGTM! Proper initialization with input validation.

Good validation of the default RNG address and proper initialization of the RNG array.


147-158: Missing validation in removeLastRngFallback.

The function doesn't check if the RNG being removed has any pending requests or if it's currently being used. This could lead to failed randomness retrieval.

Consider adding validation to ensure safe removal.

 function removeLastRngFallback() external onlyByGovernor {
     require(rngs.length > 1, "No fallback RNG");
+    require(currentRngIndex < rngs.length - 1, "Cannot remove active RNG");
⛔ Skipped due to learnings
Learnt from: jaybuidl
PR: kleros/kleros-v2#1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the `contracts/src/rng/ChainlinkRNG.sol` contract, the `requestRandomness` function is restricted to being called only by the `SortitionModule`, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.
Learnt from: jaybuidl
PR: kleros/kleros-v2#1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the `SortitionModule` can call `requestRandomness`, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

129-136: Risk in changeDefaultRng when taking over pending requests.

Calling _requestRandomness(DEFAULT_RNG) during RNG change could fail if the new RNG is not ready or properly configured, potentially leaving the contract in an inconsistent state.

Consider adding try-catch or validation before attempting to take over requests.

⛔ Skipped due to learnings
Learnt from: jaybuidl
PR: kleros/kleros-v2#1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the `contracts/src/rng/ChainlinkRNG.sol` contract, the `requestRandomness` function is restricted to being called only by the `SortitionModule`, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.
Learnt from: jaybuidl
PR: kleros/kleros-v2#1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the `SortitionModule` can call `requestRandomness`, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

84-109: Issues with fallback mechanism in receiveRandomness.

Several concerns:

  1. Makes external calls without reentrancy protection
  2. When falling back, immediately calls _requestRandomness which might fail if the next RNG requires specific conditions
  3. No validation that the fallback RNG is operational before switching

Consider adding more robust error handling and validation of RNG availability.

⛔ Skipped due to learnings
Learnt from: jaybuidl
PR: kleros/kleros-v2#1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the `contracts/src/rng/ChainlinkRNG.sol` contract, the `requestRandomness` function is restricted to being called only by the `SortitionModule`, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.
Learnt from: jaybuidl
PR: kleros/kleros-v2#1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the `SortitionModule` can call `requestRandomness`, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

70-80: Potential reentrancy vulnerability in requestRandomness.

The contract updates state variables before making an external call to rngs[_rngIndex].requestRandomness(). A malicious RNG could potentially call back into this contract.

Consider using reentrancy guards or following checks-effects-interactions pattern more strictly.

+import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

-contract RNGWithFallback is IRNG {
+contract RNGWithFallback is IRNG, ReentrancyGuard {

-    function requestRandomness() external override onlyByConsumer {
+    function requestRandomness() external override onlyByConsumer nonReentrant {

-    function receiveRandomness() external override onlyByConsumer returns (uint256 randomNumber) {
+    function receiveRandomness() external override onlyByConsumer nonReentrant returns (uint256 randomNumber) {
⛔ Skipped due to learnings
Learnt from: jaybuidl
PR: kleros/kleros-v2#1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the `contracts/src/rng/ChainlinkRNG.sol` contract, the `requestRandomness` function is restricted to being called only by the `SortitionModule`, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.
Learnt from: jaybuidl
PR: kleros/kleros-v2#1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the `SortitionModule` can call `requestRandomness`, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jul 24, 2025
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: 5

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5db2a51 and 8d9d2cb.

📒 Files selected for processing (26)
  • contracts/deploy/00-chainlink-rng.ts (1 hunks)
  • contracts/deploy/00-home-chain-arbitration-neo.ts (3 hunks)
  • contracts/deploy/00-home-chain-arbitration.ts (2 hunks)
  • contracts/deploy/00-home-chain-resolver.ts (0 hunks)
  • contracts/deploy/00-rng.ts (2 hunks)
  • contracts/deploy/change-sortition-module-rng.ts (1 hunks)
  • contracts/src/arbitration/KlerosCoreNeo.sol (3 hunks)
  • contracts/src/arbitration/SortitionModule.sol (2 hunks)
  • contracts/src/arbitration/SortitionModuleBase.sol (5 hunks)
  • contracts/src/arbitration/SortitionModuleNeo.sol (2 hunks)
  • contracts/src/rng/BlockhashRNG.sol (1 hunks)
  • contracts/src/rng/ChainlinkRNG.sol (8 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/test/arbitration/dispute-kit-gated.ts (1 hunks)
  • contracts/test/arbitration/draw.ts (1 hunks)
  • contracts/test/arbitration/staking-neo.ts (2 hunks)
  • contracts/test/arbitration/staking.ts (3 hunks)
  • contracts/test/foundry/KlerosCore.t.sol (35 hunks)
  • contracts/test/integration/index.ts (1 hunks)
  • contracts/test/proxy/index.ts (1 hunks)
  • contracts/test/rng/index.ts (5 hunks)
  • cspell.json (1 hunks)
💤 Files with no reviewable changes (2)
  • contracts/deploy/00-home-chain-resolver.ts
  • contracts/src/rng/RNG.sol
✅ Files skipped from review due to trivial changes (5)
  • contracts/deploy/00-chainlink-rng.ts
  • contracts/src/rng/IRNG.sol
  • contracts/test/proxy/index.ts
  • contracts/test/rng/index.ts
  • contracts/src/arbitration/KlerosCoreNeo.sol
🚧 Files skipped from review as they are similar to previous changes (17)
  • cspell.json
  • contracts/test/arbitration/dispute-kit-gated.ts
  • contracts/deploy/change-sortition-module-rng.ts
  • contracts/deploy/00-rng.ts
  • contracts/deploy/00-home-chain-arbitration.ts
  • contracts/test/integration/index.ts
  • contracts/test/arbitration/draw.ts
  • contracts/test/arbitration/staking.ts
  • contracts/test/arbitration/staking-neo.ts
  • contracts/src/rng/IncrementalNG.sol
  • contracts/deploy/00-home-chain-arbitration-neo.ts
  • contracts/src/arbitration/SortitionModuleBase.sol
  • contracts/test/foundry/KlerosCore.t.sol
  • contracts/src/arbitration/SortitionModuleNeo.sol
  • contracts/src/arbitration/SortitionModule.sol
  • contracts/src/rng/RandomizerRNG.sol
  • contracts/src/rng/ChainlinkRNG.sol
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: jaybuidl
PR: kleros/kleros-v2#1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the `contracts/src/rng/ChainlinkRNG.sol` contract, the `requestRandomness` function is restricted to being called only by the `SortitionModule`, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.
📚 Learning: in the `contracts/src/rng/chainlinkrng.sol` contract, the `requestrandomness` function is restricted...
Learnt from: jaybuidl
PR: kleros/kleros-v2#1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the `contracts/src/rng/ChainlinkRNG.sol` contract, the `requestRandomness` function is restricted to being called only by the `SortitionModule`, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Applied to files:

  • contracts/src/rng/BlockhashRNG.sol
  • contracts/src/rng/RNGWithFallback.sol
📚 Learning: only the `sortitionmodule` can call `requestrandomness`, and it doesn't send concurrent requests, so...
Learnt from: jaybuidl
PR: kleros/kleros-v2#1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the `SortitionModule` can call `requestRandomness`, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

Applied to files:

  • contracts/src/rng/BlockhashRNG.sol
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (14)
  • GitHub Check: Redirect rules - kleros-v2-university
  • GitHub Check: Header rules - kleros-v2-university
  • GitHub Check: Pages changed - kleros-v2-university
  • GitHub Check: Redirect rules - kleros-v2-testnet
  • GitHub Check: Redirect rules - kleros-v2-neo
  • GitHub Check: Redirect rules - kleros-v2-testnet
  • GitHub Check: Header rules - kleros-v2-neo
  • GitHub Check: Header rules - kleros-v2-testnet
  • GitHub Check: Header rules - kleros-v2-testnet
  • GitHub Check: Pages changed - kleros-v2-neo
  • GitHub Check: Pages changed - kleros-v2-testnet
  • GitHub Check: Analyze (javascript)
  • GitHub Check: contracts-testing
  • GitHub Check: Pages changed - kleros-v2-testnet
🔇 Additional comments (12)
contracts/src/rng/BlockhashRNG.sol (7)

5-5: LGTM: Import aligns with new interface pattern.

The import of IRNG.sol correctly replaces the previous RNG interface inheritance.


10-22: Excellent storage design for L2 compatibility.

The transition from block-based to timestamp-based randomness is well-architected:

  • Clear separation of governor/consumer roles
  • lookaheadTime as immutable provides gas efficiency
  • Random number caching via mapping enables future retrieval beyond blockhash window
  • L2 compatibility rationale is well-documented

28-36: Proper access control implementation.

The modifiers correctly implement role-based access control with clear error messages and standard Solidity patterns.


72-75: LGTM: Simple and effective request implementation.

The function correctly implements the timestamp-based approach for L2 compatibility. Overwriting previous requests is acceptable given the single-consumer model.


77-101: Excellent implementation with comprehensive edge case handling.

The function properly handles all scenarios:

  • Early validation for missing requests and timing constraints
  • Efficient caching mechanism to preserve randomness beyond blockhash window
  • Correct use of blockhash(block.number - 1) for randomness generation
  • Graceful degradation returning 0 when randomness unavailable

The timestamp-based approach with caching elegantly solves L2 block production irregularities.


107-112: LGTM: Clear readiness check implementation.

The function correctly mirrors the timing logic from receiveRandomness and provides useful external visibility.


114-119: LGTM: Consistent timestamp calculation.

The function provides consistent timing information that aligns with the core randomness logic.

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

1-11: LGTM!

The contract structure, imports, and interface implementation are well-organized and follow Solidity best practices.


13-17: LGTM!

The state variables are well-designed with appropriate visibility and immutability where needed. Making rng immutable is a good security practice.


23-24: LGTM!

The events are well-designed for monitoring fallback occurrences and governance changes.


47-55: LGTM!

The access control modifiers are implemented correctly with clear error messages.


62-65: Add request state validation.

The function should validate that no request is already pending to prevent overwriting requestTimestamp and align with the PR objective of preventing repeated calls.

 function requestRandomness() external override onlyByConsumer {
+    require(requestTimestamp == 0, "Request already pending");
     requestTimestamp = block.timestamp;
     rng.requestRandomness();
 }
⛔ Skipped due to learnings
Learnt from: jaybuidl
PR: kleros/kleros-v2#1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the `contracts/src/rng/ChainlinkRNG.sol` contract, the `requestRandomness` function is restricted to being called only by the `SortitionModule`, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.
Learnt from: jaybuidl
PR: kleros/kleros-v2#1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the `SortitionModule` can call `requestRandomness`, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

Comment on lines +42 to +50
/// @dev Constructor.
/// @param _governor The Governor of the contract.
/// @param _consumer The address that can request random numbers.
/// @param _lookaheadTime The time lookahead in seconds for the random number.
constructor(address _governor, address _consumer, uint256 _lookaheadTime) {
governor = _governor;
consumer = _consumer;
lookaheadTime = _lookaheadTime;
}
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 input validation to constructor.

The constructor lacks validation for critical parameters which could lead to deployment issues.

Apply this diff to add proper validation:

 constructor(address _governor, address _consumer, uint256 _lookaheadTime) {
+    require(_governor != address(0), "Governor cannot be zero address");
+    require(_consumer != address(0), "Consumer cannot be zero address");
+    require(_lookaheadTime > 0, "Lookahead time must be positive");
     governor = _governor;
     consumer = _consumer;
     lookaheadTime = _lookaheadTime;
 }
📝 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
/// @dev Constructor.
/// @param _governor The Governor of the contract.
/// @param _consumer The address that can request random numbers.
/// @param _lookaheadTime The time lookahead in seconds for the random number.
constructor(address _governor, address _consumer, uint256 _lookaheadTime) {
governor = _governor;
consumer = _consumer;
lookaheadTime = _lookaheadTime;
}
/// @dev Constructor.
/// @param _governor The Governor of the contract.
/// @param _consumer The address that can request random numbers.
/// @param _lookaheadTime The time lookahead in seconds for the random number.
constructor(address _governor, address _consumer, uint256 _lookaheadTime) {
require(_governor != address(0), "Governor cannot be zero address");
require(_consumer != address(0), "Consumer cannot be zero address");
require(_lookaheadTime > 0, "Lookahead time must be positive");
governor = _governor;
consumer = _consumer;
lookaheadTime = _lookaheadTime;
}
🤖 Prompt for AI Agents
In contracts/src/rng/BlockhashRNG.sol around lines 42 to 50, the constructor
parameters _governor, _consumer, and _lookaheadTime lack validation. Add require
statements to ensure _governor and _consumer are not the zero address and
_lookaheadTime is greater than zero before assigning them to state variables.
This prevents invalid inputs during deployment.

Comment on lines +56 to +66
/// @dev Changes the governor of the contract.
/// @param _governor The new governor.
function changeGovernor(address _governor) external onlyByGovernor {
governor = _governor;
}

/// @dev Changes the consumer of the RNG.
/// @param _consumer The new consumer.
function changeConsumer(address _consumer) external onlyByGovernor {
consumer = _consumer;
}
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 address validation to governance functions.

The governance functions lack input validation which could result in accidentally setting invalid addresses.

Apply this diff to add validation:

 function changeGovernor(address _governor) external onlyByGovernor {
+    require(_governor != address(0), "Governor cannot be zero address");
     governor = _governor;
 }

 function changeConsumer(address _consumer) external onlyByGovernor {
+    require(_consumer != address(0), "Consumer cannot be zero address");
     consumer = _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
/// @dev Changes the governor of the contract.
/// @param _governor The new governor.
function changeGovernor(address _governor) external onlyByGovernor {
governor = _governor;
}
/// @dev Changes the consumer of the RNG.
/// @param _consumer The new consumer.
function changeConsumer(address _consumer) external onlyByGovernor {
consumer = _consumer;
}
/// @dev Changes the governor of the contract.
/// @param _governor The new governor.
function changeGovernor(address _governor) external onlyByGovernor {
require(_governor != address(0), "Governor cannot be zero address");
governor = _governor;
}
/// @dev Changes the consumer of the RNG.
/// @param _consumer The new consumer.
function changeConsumer(address _consumer) external onlyByGovernor {
require(_consumer != address(0), "Consumer cannot be zero address");
consumer = _consumer;
}
🤖 Prompt for AI Agents
In contracts/src/rng/BlockhashRNG.sol around lines 56 to 66, the changeGovernor
and changeConsumer functions do not validate the input addresses, which risks
setting invalid addresses. Add a require statement in each function to check
that the new address is not the zero address before assigning it to governor or
consumer. This ensures only valid addresses are set.

Comment on lines +34 to +41
constructor(address _governor, address _consumer, uint256 _fallbackTimeoutSeconds, IRNG _rng) {
require(address(_rng) != address(0), "Invalid default RNG");

governor = _governor;
consumer = _consumer;
fallbackTimeoutSeconds = _fallbackTimeoutSeconds;
rng = _rng;
}
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 validation for governor and consumer addresses.

The constructor validates the RNG address but missing validation for governor and consumer addresses could lead to deployment with invalid addresses, potentially bricking governance functions.

 constructor(address _governor, address _consumer, uint256 _fallbackTimeoutSeconds, IRNG _rng) {
+    require(_governor != address(0), "Invalid governor");
+    require(_consumer != address(0), "Invalid consumer");
     require(address(_rng) != address(0), "Invalid default RNG");
📝 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
constructor(address _governor, address _consumer, uint256 _fallbackTimeoutSeconds, IRNG _rng) {
require(address(_rng) != address(0), "Invalid default RNG");
governor = _governor;
consumer = _consumer;
fallbackTimeoutSeconds = _fallbackTimeoutSeconds;
rng = _rng;
}
constructor(address _governor, address _consumer, uint256 _fallbackTimeoutSeconds, IRNG _rng) {
require(_governor != address(0), "Invalid governor");
require(_consumer != address(0), "Invalid consumer");
require(address(_rng) != address(0), "Invalid default RNG");
governor = _governor;
consumer = _consumer;
fallbackTimeoutSeconds = _fallbackTimeoutSeconds;
rng = _rng;
}
🤖 Prompt for AI Agents
In contracts/src/rng/RNGWithFallback.sol around lines 34 to 41, the constructor
validates the RNG address but lacks validation for the governor and consumer
addresses. Add require statements to check that both _governor and _consumer are
not the zero address to prevent deployment with invalid addresses that could
break governance functionality.

Comment on lines +69 to +82
function receiveRandomness() external override onlyByConsumer returns (uint256 randomNumber) {
// Try to get random number from the RNG contract
randomNumber = rng.receiveRandomness();

// If we got a valid number, clear the request
if (randomNumber != 0) {
return randomNumber;
} else if (block.timestamp > requestTimestamp + fallbackTimeoutSeconds) {
// If the timeout is exceeded, try the fallback
randomNumber = uint256(blockhash(block.number - 1));
emit RNGFallback();
}
return randomNumber;
}
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

Fix multiple logical issues in fallback logic.

Several issues need addressing:

  1. Missing request validation: Function doesn't validate that a request was made
  2. Incomplete request state management: requestTimestamp is never cleared after successful/failed attempts
  3. Questionable zero handling: Returns 0 when RNG returns 0 but timeout hasn't elapsed - this may be unintended behavior
 function receiveRandomness() external override onlyByConsumer returns (uint256 randomNumber) {
+    require(requestTimestamp != 0, "No request pending");
+    
     // Try to get random number from the RNG contract
     randomNumber = rng.receiveRandomness();

     // If we got a valid number, clear the request
     if (randomNumber != 0) {
+        requestTimestamp = 0;
         return randomNumber;
     } else if (block.timestamp > requestTimestamp + fallbackTimeoutSeconds) {
         // If the timeout is exceeded, try the fallback
         randomNumber = uint256(blockhash(block.number - 1));
+        requestTimestamp = 0;
         emit RNGFallback();
+        return randomNumber;
     }
-    return randomNumber;
+    
+    // If RNG returns 0 but timeout not exceeded, revert to avoid ambiguity
+    revert("RNG returned invalid value, timeout not exceeded");
 }
📝 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
function receiveRandomness() external override onlyByConsumer returns (uint256 randomNumber) {
// Try to get random number from the RNG contract
randomNumber = rng.receiveRandomness();
// If we got a valid number, clear the request
if (randomNumber != 0) {
return randomNumber;
} else if (block.timestamp > requestTimestamp + fallbackTimeoutSeconds) {
// If the timeout is exceeded, try the fallback
randomNumber = uint256(blockhash(block.number - 1));
emit RNGFallback();
}
return randomNumber;
}
function receiveRandomness() external override onlyByConsumer returns (uint256 randomNumber) {
require(requestTimestamp != 0, "No request pending");
// Try to get random number from the RNG contract
randomNumber = rng.receiveRandomness();
// If we got a valid number, clear the request
if (randomNumber != 0) {
requestTimestamp = 0;
return randomNumber;
} else if (block.timestamp > requestTimestamp + fallbackTimeoutSeconds) {
// If the timeout is exceeded, try the fallback
randomNumber = uint256(blockhash(block.number - 1));
requestTimestamp = 0;
emit RNGFallback();
return randomNumber;
}
// If RNG returns 0 but timeout not exceeded, revert to avoid ambiguity
revert("RNG returned invalid value, timeout not exceeded");
}
🤖 Prompt for AI Agents
In contracts/src/rng/RNGWithFallback.sol lines 69 to 82, the receiveRandomness
function lacks validation to ensure a randomness request exists before
proceeding, does not clear the requestTimestamp after handling a request, and
returns 0 prematurely if the RNG returns 0 before the fallback timeout. Fix this
by adding a check that a requestTimestamp is set before continuing, clear
requestTimestamp after successfully receiving randomness or after fallback
usage, and modify the logic to avoid returning 0 immediately when RNG returns 0
but the timeout has not yet elapsed, instead wait until timeout to use fallback
or return a proper indication.

Comment on lines +90 to +105
function changeGovernor(address _newGovernor) external onlyByGovernor {
governor = _newGovernor;
}

/// @dev Change the consumer
/// @param _consumer Address of the new consumer
function changeConsumer(address _consumer) external onlyByGovernor {
consumer = _consumer;
}

/// @dev Change the fallback timeout
/// @param _fallbackTimeoutSeconds New timeout in seconds
function changeFallbackTimeout(uint256 _fallbackTimeoutSeconds) external onlyByGovernor {
fallbackTimeoutSeconds = _fallbackTimeoutSeconds;
emit FallbackTimeoutChanged(_fallbackTimeoutSeconds);
}
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 validation to governance functions.

The governance functions should validate input parameters to prevent invalid states.

 function changeGovernor(address _newGovernor) external onlyByGovernor {
+    require(_newGovernor != address(0), "Invalid governor");
     governor = _newGovernor;
 }

 function changeConsumer(address _consumer) external onlyByGovernor {
+    require(_consumer != address(0), "Invalid consumer");
     consumer = _consumer;
 }

 function changeFallbackTimeout(uint256 _fallbackTimeoutSeconds) external onlyByGovernor {
+    require(_fallbackTimeoutSeconds > 0, "Invalid timeout");
     fallbackTimeoutSeconds = _fallbackTimeoutSeconds;
     emit FallbackTimeoutChanged(_fallbackTimeoutSeconds);
 }
📝 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
function changeGovernor(address _newGovernor) external onlyByGovernor {
governor = _newGovernor;
}
/// @dev Change the consumer
/// @param _consumer Address of the new consumer
function changeConsumer(address _consumer) external onlyByGovernor {
consumer = _consumer;
}
/// @dev Change the fallback timeout
/// @param _fallbackTimeoutSeconds New timeout in seconds
function changeFallbackTimeout(uint256 _fallbackTimeoutSeconds) external onlyByGovernor {
fallbackTimeoutSeconds = _fallbackTimeoutSeconds;
emit FallbackTimeoutChanged(_fallbackTimeoutSeconds);
}
function changeGovernor(address _newGovernor) external onlyByGovernor {
require(_newGovernor != address(0), "Invalid governor");
governor = _newGovernor;
}
/// @dev Change the consumer
/// @param _consumer Address of the new consumer
function changeConsumer(address _consumer) external onlyByGovernor {
require(_consumer != address(0), "Invalid consumer");
consumer = _consumer;
}
/// @dev Change the fallback timeout
/// @param _fallbackTimeoutSeconds New timeout in seconds
function changeFallbackTimeout(uint256 _fallbackTimeoutSeconds) external onlyByGovernor {
require(_fallbackTimeoutSeconds > 0, "Invalid timeout");
fallbackTimeoutSeconds = _fallbackTimeoutSeconds;
emit FallbackTimeoutChanged(_fallbackTimeoutSeconds);
}
🤖 Prompt for AI Agents
In contracts/src/rng/RNGWithFallback.sol around lines 90 to 105, the governance
functions changeGovernor, changeConsumer, and changeFallbackTimeout lack input
validation. Add checks to ensure the new governor and consumer addresses are not
zero addresses, and validate that the fallbackTimeoutSeconds is a reasonable
positive value before updating the state variables. This prevents invalid or
harmful contract states.

@unknownunknown1
Copy link
Contributor

Updated the RNG contracts according to my own feedback
I ended up making only partial changes because implementing them fully ended up being problematic:

  • BlockhashRNG contract was remained untouched, only a couple of clarifying comments was added
  • I attempted to implement an upper bound for the timestamp. The idea was to reset requestTimestamp when that bound was exceeded. The problem with this is that when you reset the timestamp RNG returns 0 and passes it to SortitionModule, which makes it revert, thus unless we want to change the logic in SM (which I don't think is warranted) it's not possible to change storage during unsuccessful random number reception. I considered implementing the upper bound using the logic similar to the one used in BeaconRNG but it only seemed to add unnecessary complications.
  • For the aforementioned issue the fallback contract was greatly simplified. That issue was present in the previous version too, but wasn't spotted during the first review. So since it's not possible to change storage when receiveRandomness fails I implemented an immediate fallback based on BlockhashRNG logic
  • Recent changes were causing stack-too-deep error during Foundry compilation, which this PR fixes

@jaybuidl jaybuidl force-pushed the feat/rng-fallback2 branch from 8d9d2cb to 937fb97 Compare August 7, 2025 14:01
Copy link

sonarqubecloud bot commented Aug 7, 2025

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: 1

♻️ Duplicate comments (5)
contracts/src/rng/RNGWithFallback.sol (3)

34-41: Add validation for governor and consumer addresses.

The constructor validates the RNG address but lacks validation for governor and consumer addresses, which could lead to deployment with invalid addresses and break governance functionality.

 constructor(address _governor, address _consumer, uint256 _fallbackTimeoutSeconds, IRNG _rng) {
+    require(_governor != address(0), "Invalid governor");
+    require(_consumer != address(0), "Invalid consumer");
     require(address(_rng) != address(0), "Invalid default RNG");

69-82: Fix critical logical issues in fallback mechanism.

Multiple critical issues exist:

  1. No validation that a request was made (requestTimestamp could be 0)
  2. requestTimestamp is never cleared, preventing future requests
  3. Returns 0 when RNG returns 0 but timeout hasn't elapsed, which may cause consumer to revert
 function receiveRandomness() external override onlyByConsumer returns (uint256 randomNumber) {
+    require(requestTimestamp != 0, "No request pending");
+    
     // Try to get random number from the RNG contract
     randomNumber = rng.receiveRandomness();

     // If we got a valid number, clear the request
     if (randomNumber != 0) {
+        requestTimestamp = 0;
         return randomNumber;
     } else if (block.timestamp > requestTimestamp + fallbackTimeoutSeconds) {
         // If the timeout is exceeded, try the fallback
         randomNumber = uint256(blockhash(block.number - 1));
+        requestTimestamp = 0;
         emit RNGFallback();
+        return randomNumber;
     }
-    return randomNumber;
+    
+    // If RNG returns 0 but timeout not exceeded, revert to avoid ambiguity
+    revert("RNG returned invalid value, timeout not exceeded");
 }

90-105: Add input validation to governance functions.

The governance functions lack validation for critical parameters, which could result in invalid contract states.

 function changeGovernor(address _newGovernor) external onlyByGovernor {
+    require(_newGovernor != address(0), "Invalid governor");
     governor = _newGovernor;
 }

 function changeConsumer(address _consumer) external onlyByGovernor {
+    require(_consumer != address(0), "Invalid consumer");
     consumer = _consumer;
 }

 function changeFallbackTimeout(uint256 _fallbackTimeoutSeconds) external onlyByGovernor {
+    require(_fallbackTimeoutSeconds > 0, "Invalid timeout");
     fallbackTimeoutSeconds = _fallbackTimeoutSeconds;
     emit FallbackTimeoutChanged(_fallbackTimeoutSeconds);
 }
contracts/src/rng/BlockhashRNG.sol (2)

42-50: Add input validation to constructor.

The constructor lacks validation for critical parameters which could lead to deployment issues, as previously identified.

Apply this diff to add proper validation:

 constructor(address _governor, address _consumer, uint256 _lookaheadTime) {
+    require(_governor != address(0), "Governor cannot be zero address");
+    require(_consumer != address(0), "Consumer cannot be zero address");
+    require(_lookaheadTime > 0, "Lookahead time must be positive");
     governor = _governor;
     consumer = _consumer;
     lookaheadTime = _lookaheadTime;
 }

56-66: Add address validation to governance functions.

The governance functions lack input validation which could result in accidentally setting invalid addresses, as previously identified.

Apply this diff to add validation:

 function changeGovernor(address _governor) external onlyByGovernor {
+    require(_governor != address(0), "Governor cannot be zero address");
     governor = _governor;
 }

 function changeConsumer(address _consumer) external onlyByGovernor {
+    require(_consumer != address(0), "Consumer cannot be zero address");
     consumer = _consumer;
 }
🧹 Nitpick comments (1)
contracts/src/rng/RNGWithFallback.sol (1)

78-78: Consider blockhash availability limitation.

Using blockhash(block.number - 1) may return 0 if the block is more than 256 blocks old, which could happen if the fallback timeout is very long on chains with fast block times.

Consider adding a check or using an alternative fallback mechanism:

-        randomNumber = uint256(blockhash(block.number - 1));
+        randomNumber = uint256(blockhash(block.number - 1));
+        if (randomNumber == 0) {
+            // Fallback to a combination of block properties if blockhash unavailable
+            randomNumber = uint256(keccak256(abi.encodePacked(block.timestamp, block.difficulty, block.coinbase)));
+        }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8d9d2cb and 937fb97.

📒 Files selected for processing (25)
  • contracts/deploy/00-chainlink-rng.ts (1 hunks)
  • contracts/deploy/00-home-chain-arbitration-neo.ts (2 hunks)
  • contracts/deploy/00-home-chain-arbitration.ts (2 hunks)
  • contracts/deploy/00-home-chain-resolver.ts (0 hunks)
  • contracts/deploy/00-rng.ts (2 hunks)
  • contracts/deploy/change-sortition-module-rng.ts (1 hunks)
  • contracts/src/arbitration/SortitionModule.sol (2 hunks)
  • contracts/src/arbitration/SortitionModuleBase.sol (5 hunks)
  • contracts/src/arbitration/SortitionModuleNeo.sol (2 hunks)
  • contracts/src/rng/BlockhashRNG.sol (1 hunks)
  • contracts/src/rng/ChainlinkRNG.sol (8 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/test/arbitration/dispute-kit-gated.ts (1 hunks)
  • contracts/test/arbitration/draw.ts (1 hunks)
  • contracts/test/arbitration/staking-neo.ts (2 hunks)
  • contracts/test/arbitration/staking.ts (3 hunks)
  • contracts/test/foundry/KlerosCore.t.sol (35 hunks)
  • contracts/test/integration/index.ts (1 hunks)
  • contracts/test/proxy/index.ts (1 hunks)
  • contracts/test/rng/index.ts (5 hunks)
  • cspell.json (1 hunks)
💤 Files with no reviewable changes (2)
  • contracts/deploy/00-home-chain-resolver.ts
  • contracts/src/rng/RNG.sol
✅ Files skipped from review due to trivial changes (2)
  • contracts/test/proxy/index.ts
  • contracts/deploy/00-chainlink-rng.ts
🚧 Files skipped from review as they are similar to previous changes (19)
  • cspell.json
  • contracts/test/arbitration/staking-neo.ts
  • contracts/src/arbitration/SortitionModuleNeo.sol
  • contracts/src/rng/IRNG.sol
  • contracts/test/arbitration/draw.ts
  • contracts/src/rng/RandomizerRNG.sol
  • contracts/deploy/00-home-chain-arbitration-neo.ts
  • contracts/deploy/00-rng.ts
  • contracts/src/rng/IncrementalNG.sol
  • contracts/test/arbitration/dispute-kit-gated.ts
  • contracts/src/arbitration/SortitionModule.sol
  • contracts/test/foundry/KlerosCore.t.sol
  • contracts/test/arbitration/staking.ts
  • contracts/src/rng/ChainlinkRNG.sol
  • contracts/test/integration/index.ts
  • contracts/deploy/00-home-chain-arbitration.ts
  • contracts/deploy/change-sortition-module-rng.ts
  • contracts/src/arbitration/SortitionModuleBase.sol
  • contracts/test/rng/index.ts
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: jaybuidl
PR: kleros/kleros-v2#1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the `contracts/src/rng/ChainlinkRNG.sol` contract, the `requestRandomness` function is restricted to being called only by the `SortitionModule`, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.
📚 Learning: in the `contracts/src/rng/chainlinkrng.sol` contract, the `requestrandomness` function is restricted...
Learnt from: jaybuidl
PR: kleros/kleros-v2#1778
File: contracts/src/rng/ChainlinkRNG.sol:135-153
Timestamp: 2024-12-07T11:39:10.927Z
Learning: In the `contracts/src/rng/ChainlinkRNG.sol` contract, the `requestRandomness` function is restricted to being called only by the `SortitionModule`, which does not send concurrent requests. Therefore, it's acceptable not to handle multiple random number requests concurrently in this context.

Applied to files:

  • contracts/src/rng/BlockhashRNG.sol
  • contracts/src/rng/RNGWithFallback.sol
📚 Learning: only the `sortitionmodule` can call `requestrandomness`, and it doesn't send concurrent requests, so...
Learnt from: jaybuidl
PR: kleros/kleros-v2#1778
File: contracts/src/rng/RandomizerRNG.sol:21-21
Timestamp: 2024-12-07T11:41:15.835Z
Learning: Only the `SortitionModule` can call `requestRandomness`, and it doesn't send concurrent requests, so handling multiple concurrent random number requests is unnecessary in this context.

Applied to files:

  • contracts/src/rng/BlockhashRNG.sol
  • contracts/src/rng/RNGWithFallback.sol
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: contracts-testing
  • GitHub Check: SonarCloud
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (6)
contracts/src/rng/BlockhashRNG.sol (6)

5-5: LGTM! Correct implementation of new IRNG interface.

The import of IRNG and contract declaration correctly implement the new standardized interface, aligning with the broader RNG system refactor described in the PR objectives.

Also applies to: 13-13


18-22: Well-designed storage structure for timestamp-based randomness.

The storage variables correctly implement the new timestamp-based approach with appropriate access controls and caching mechanism. Using immutable for lookaheadTime is a good gas optimization.


28-36: LGTM! Proper access control implementation.

The modifiers correctly implement role-based access control with clear error messages, following standard Solidity patterns.


73-75: LGTM! Correct implementation of timestamp-based randomness request.

The function correctly implements the new IRNG interface and timestamp-based approach by recording the current block timestamp to initiate the lookahead period.


79-101: LGTM! Well-implemented timestamp-based randomness retrieval with appropriate caching.

The function correctly implements the new timing mechanism with proper checks for request status and time passage. The use of blockhash(block.number - 1) is correct since blockhash(block.number) would always return 0. The caching strategy appropriately handles zero values by not caching them, allowing retry attempts if randomness is temporarily unavailable.


109-119: LGTM! Useful view functions with proper edge case handling.

Both functions correctly implement their intended logic and properly handle the edge case where no request has been made. These functions provide valuable information for external callers to determine randomness readiness.

Comment on lines +62 to +65
function requestRandomness() external override onlyByConsumer {
requestTimestamp = block.timestamp;
rng.requestRandomness();
}
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 validation to prevent duplicate requests.

The function doesn't check if a previous request is still pending, which could lead to overwriting the requestTimestamp and losing track of the original request timing.

 function requestRandomness() external override onlyByConsumer {
+    require(requestTimestamp == 0, "Request already pending");
     requestTimestamp = block.timestamp;
     rng.requestRandomness();
 }
📝 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
function requestRandomness() external override onlyByConsumer {
requestTimestamp = block.timestamp;
rng.requestRandomness();
}
function requestRandomness() external override onlyByConsumer {
require(requestTimestamp == 0, "Request already pending");
requestTimestamp = block.timestamp;
rng.requestRandomness();
}
🤖 Prompt for AI Agents
In contracts/src/rng/RNGWithFallback.sol around lines 62 to 65, the
requestRandomness function lacks validation to prevent duplicate requests. Add a
check at the start of the function to ensure no previous request is still
pending, for example by verifying if requestTimestamp is zero or if the previous
request has been fulfilled. If a request is pending, revert the transaction to
avoid overwriting requestTimestamp and losing the original request timing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RNG fallback mechanism
2 participants