Skip to content

Commit

Permalink
Random Values provider (immutable#166)
Browse files Browse the repository at this point in the history
Added Random Number Generation framework.
  • Loading branch information
drinkcoffee authored Feb 1, 2024
1 parent f415b6d commit f9da1fb
Show file tree
Hide file tree
Showing 37 changed files with 3,400 additions and 1,739 deletions.
31 changes: 26 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ jobs:
uses: actions/checkout@v3
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
- name: Install dependencies
run: yarn install --frozen-lockfile --network-concurrency 1
- name: Run tests
- name: Show Forge Version
run: forge --version
- name: Run tests and install dependancies
run: forge test -vvv
- name: Debug Info1
if: '!cancelled()'
run: pwd
hardhat-test:
name: Run Hardhat Tests
runs-on: ubuntu-latest
Expand All @@ -34,8 +37,9 @@ jobs:
run: yarn install --frozen-lockfile --network-concurrency 1
- name: Run Tests
run: yarn test
lint:
eslint:
name: Run eslint
continue-on-error: true
runs-on: ubuntu-latest
steps:
- name: Checkout Code
Expand All @@ -48,7 +52,24 @@ jobs:
- name: Install dependencies
run: yarn install --frozen-lockfile --network-concurrency 1
- name: Run eslint
run: yarn lint
continue-on-error: true
run: yarn run eslint
solhint:
name: Run solhint
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: lts/*
cache: 'yarn'
- name: Install dependencies
run: yarn install --frozen-lockfile --network-concurrency 1
- name: Run solhint
continue-on-error: true
run: yarn run solhint contracts/**/*.sol
publish:
name: Publish to NPM (dry run)
runs-on: ubuntu-latest
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ dist/

# Forge files
foundry-out/

# Apple Mac files
.DS_Store
18 changes: 18 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "lib/solidity-bits"]
path = lib/solidity-bits
url = https://github.com/estarriolvetch/solidity-bits
[submodule "lib/solidity-bytes-utils"]
path = lib/solidity-bytes-utils
url = https://github.com/GNSPS/solidity-bytes-utils
[submodule "lib/openzeppelin-contracts-4.9.3"]
path = lib/openzeppelin-contracts-4.9.3
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "lib/openzeppelin-contracts-upgradeable-4.9.3"]
path = lib/openzeppelin-contracts-upgradeable-4.9.3
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
[submodule "lib/immutable-seaport-1.5.0+im1.3"]
path = lib/immutable-seaport-1.5.0+im1.3
url = https://github.com/immutable/seaport
[submodule "lib/immutable-seaport-core-1.5.0+im1"]
path = lib/immutable-seaport-core-1.5.0+im1
url = https://github.com/immutable/seaport-core
59 changes: 53 additions & 6 deletions .solhint.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,56 @@
{
"extends": "solhint:recommended",
"plugins": ["prettier"],

"rules": {
"prettier/prettier": "error",
"compiler-version": ["error", "^0.8.0"],
"func-visibility": ["warn", { "ignoreConstructors": true }]
},
"plugins": ["prettier"]
"code-complexity": ["warn", 7],
"custom-errors": "error",
"explicit-types": ["error"],
"function-max-lines": ["off", 50],
"max-line-length": ["off", 120],
"max-states-count": ["off", 15],
"no-console": "error",
"no-empty-blocks": "warn",
"no-global-import": "warn",
"no-unused-import": "warn",
"no-unused-vars": "warn",
"one-contract-per-file": "warn",
"payable-fallback": "warn",
"reason-string": ["warn", {"maxLength": 32}],
"constructor-syntax": "warn",

"comprehensive-interface": "off",
"quotes": ["error", "double"],

"const-name-snakecase": "warn",
"foundry-test-functions": ["off", ["setUp"]],
"func-name-mixedcase": "warn",
"modifier-name-mixedcase": "warn",
"named-parameters-mapping": "warn",
"named-return-values": "off",
"private-vars-leading-underscore": ["off", {"strict": false}],
"use-forbidden-name": "warn",
"var-name-mixedcase": "warn",
"imports-on-top": "warn",
"visibility-modifier-order": "warn",

"avoid-call-value": "error",
"avoid-low-level-calls": "error",
"avoid-sha3": "error",
"avoid-suicide": "error",
"avoid-throw": "error",
"avoid-tx-origin": "error",
"check-send-result": "error",
"compiler-version": ["error", "0.8.19"],
"func-visibility": ["error", {"ignoreConstructors": true}],
"multiple-sends": "warn",
"no-complex-fallback": "warn",
"no-inline-assembly": "warn",
"not-rely-on-block-hash": "warn",
"not-rely-on-time": "warn",
"reentrancy": "warn",
"state-visibility": "warn",

"prettier/prettier": "error"
}
}

4 changes: 2 additions & 2 deletions contracts/allowlist/OperatorAllowlistUpgradeable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// SPDX-License-Identifier: Apache 2.0
pragma solidity 0.8.19;

import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import {AccessControlEnumerableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol";
import {UUPSUpgradeable} from "openzeppelin-contracts-upgradeable-4.9.3/proxy/utils/UUPSUpgradeable.sol";
import {AccessControlEnumerableUpgradeable} from "openzeppelin-contracts-upgradeable-4.9.3/access/AccessControlEnumerableUpgradeable.sol";

// Introspection
import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
Expand Down
62 changes: 62 additions & 0 deletions contracts/random/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Random Number Generation

This directory contains contracts that provide random number generation capability using on-chain and off-chain sources.

The reasons for using these contracts are that:

* Enables you to leverage a random number generation system designed by Immutable's cryptographers.
* Allows you to build your game against an API that won't change.
* The quality of the random numbers generated will improve as new capabilities are added to the platform. That is, the migration from ```block.hash``` to ```block.prevrandao``` when the BFT fork occurs will be seamless.
* For off-chain randomness, allows you to leverage the random number provider that Immutable has agreements with.

# Status

Contract audits:

| Description | Date |Version Audited | Link to Report |
|---------------------------|------------------|-----------------|----------------|
| Not audited | - | - | - |

Deployments:

| Location | Version Deployed | Address |
|---------------------------|------------------|---------|
| Immutable zkEVM Testnet | Not deployed | - |
| Immutable zkEVM Mainnet | Not deployed | - |

## Architecture

The Random Number Generation system on the immutable platform is shown in the diagram below.

![Random number genration](./random-architecture.png)

Game contracts extend ```RandomValues.sol```. This contract interacts with the ```RandomSeedProvider.sol``` contract to request and retreive random seed values.

There is one ```RandomSeedProvider.sol``` contract deployed per chain. Each game has its own instance of ```RandomValues.sol``` as this contract is integrated directly into the game contract.

The ```RandomSeedProvider.sol``` operates behind a transparent proxy, ```ERC1967Proxy.sol```, with the upgrade
logic included in the ```UUPSUpgradeable.sol``` contract that ```RandomSeedProvider.sol``` extends. Using an upgradeable pattern allows the random manager contract to be upgraded to extend its feature set and resolve issues.

The ```RandomSeedProvider.sol``` contract can be configured to use an off-chain random number source. This source is accessed via the ```IOffchainRandomSource.sol``` interface. To allow the flexibility to switch between off-chain random sources, there is an adaptor contract between the offchain random source contract and the random seed provider.

The architecture diagram shows a ChainLink VRF source and a Supra VRF source. This is purely to show the possibility of integrating with one off-chain service and then, at a later point choosing to switch to an alternative off-chain source. At present, there is no agreement to use any specific off-chain source.



## Process of Requesting a Random Number

The process for requesting a random number is shown below. Players do actions requiring a random number or a set of random numbers. They purchase, or commit to the random value(s), which is later revealed.

![Random number genration](./random-sequence.png)

The steps are:

* The game contract calls ```_requestRandomValueCreation```.
The ```_requestRandomValueCreation``` returns a value ```_randomRequestId```. This value is supplied later to fetch the random value once it has been generated. The function ```_requestRandomValueCreation``` executes a call to the ```RandomSeedProvider``` contract requesting a seed value be produced.
* The game contract calls ```_isRandomValueReady```, passing in the ```_randomRequestId```. This returns ```READY``` if the value is ready to be returned.
* The game contract calls ```_fetchRandomValues```, passing in the ```_randomRequestId```. The random seed is returned to the ```RandomValues``` contract, which then customises the value prior returning it to the game.


# Notes

Sequence diagram source [here](https://sequencediagram.org/index.html#initialData=C4S2BsFMAICUEMB2ATA9gW2gOQK7oEaQBO0A4pIsfKKogFB0AO8RoAxiM4sAOZGo5G0AMTgQPABa8ikCtABU80vHSRFTFu05Jg0AETLV0ADKoeINgDoAzqnB7o8a2RWQNrC9u76EKDADV4cBxIaxs7Byc4fzoKZHctLmkBIVFxKXxgmEUASXR0HGB4TJgALwBrAFF-AFkAHUQcxAAzIidgIhw2YBwZdWYPDiSfJDR0AGVZZAAFfgA3EGRicPtHZ1ga2JQGPhToafB4AE9iaEZetgknUMdoNr9MeG6QWjpDSABaAD5YfwAuaAAfRkAEcQtZgL4xoEsgBhGTUF6IAAUgOsIFKkAAlHRft8NgDQeDIaMMJNIMhkTjfgAeD4fAlA5o4cDNEDgVTcHLIAA0QNsFzc7zpDP+QPuY1gkDBoWA3K28ToiFQwBgqDmp3ePIJAHV4GBoM1UCR4NBMqg2OVoMBUGaYIx+MguhToMbHIhXc1mh9LvqPRKMNbbYRoEsxBqZMhLDt+IJoLCJJBLXdSZg5kEQtAQM4Ecgjm9XPixYDs1CAhnIFL4HnUQH0FKZRDudT-PiagDS6nycgqzWGoDmaz2Zy5bz+QIiGxsbj-CLGR0QgXVHOxbBKgBBAAiAE0FTG9u9Q5Bw8RnAB6O6QDVBHOpxzPV7vIsAgeQYCXMvoGHg2uphvE5sZzbAEeDfT9u2RftBzZDkKFHPk0QnKcWzndtxS7KYgJ+MVplPWggmzGA62gRA8EIEgGnwI5oB4Vw+UYQ4TiIPlRkvRtdFIghliXSAVxfOtv1CPcGBEoA).
Loading

0 comments on commit f9da1fb

Please sign in to comment.