Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Random Values provider #166

Merged
merged 102 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
f2e29fd
Added initial code for random number generation
drinkcoffee Dec 18, 2023
8405ce9
Improve documentation
drinkcoffee Dec 19, 2023
fd3644b
forge install: openzeppelin-contracts-upgradeable
drinkcoffee Dec 19, 2023
33aff29
forge install: openzeppelin-contracts
drinkcoffee Dec 19, 2023
c2d6506
Added remappings
drinkcoffee Dec 19, 2023
cb56dbe
forge install: openzeppelin-contracts
drinkcoffee Dec 19, 2023
1ea3540
forge install: openzeppelin-contracts-upgradeable
drinkcoffee Dec 19, 2023
e03392a
forge install: seaport
drinkcoffee Dec 19, 2023
426407a
Remove incorrect version of seaport
drinkcoffee Dec 19, 2023
545f341
forge install: seaport
drinkcoffee Dec 19, 2023
015c4f2
Temporarily remove trading contracts
drinkcoffee Dec 19, 2023
acdca5a
forge install: solidity-bits
drinkcoffee Dec 19, 2023
4a3f1a0
forge install: solidity-bytes-utils
drinkcoffee Dec 19, 2023
f11f239
Fixed compilation issues
drinkcoffee Dec 19, 2023
d10d6ba
Initial doc
drinkcoffee Dec 19, 2023
87952c8
Update docs
drinkcoffee Dec 19, 2023
8c03abf
Separated use of RANDAO
drinkcoffee Dec 20, 2023
b6a7956
Re-add trading
drinkcoffee Dec 21, 2023
73b8569
forge install: seaport-core
drinkcoffee Dec 21, 2023
9a57a6f
Rework seaport installs
drinkcoffee Dec 21, 2023
ff3b4b1
forge install: seaport-core
drinkcoffee Dec 21, 2023
f6b2a98
Fix import path
drinkcoffee Dec 21, 2023
3678fe9
forge install: seaport-types
drinkcoffee Dec 21, 2023
5e21128
Lib issue
drinkcoffee Dec 21, 2023
db07799
forge install: seaport-types
drinkcoffee Dec 21, 2023
8bc1cf2
Remove old seaport
drinkcoffee Dec 21, 2023
61adf8f
forge install: seaport
drinkcoffee Dec 21, 2023
e3a117c
Switch seaport version
drinkcoffee Dec 21, 2023
db8e31e
forge install: seaport
drinkcoffee Dec 21, 2023
cbb5ded
Switch to RandomSeedProvider
drinkcoffee Dec 21, 2023
8d4b47a
forge install: seaport
drinkcoffee Dec 21, 2023
14d6ae4
Rework seaport version
drinkcoffee Dec 21, 2023
b58eed2
Added seaport
drinkcoffee Dec 21, 2023
57710bb
Remove seaport
drinkcoffee Dec 21, 2023
0519516
Remove seaport
drinkcoffee Dec 21, 2023
236c518
Remove seaport lib directory
drinkcoffee Dec 21, 2023
1c30b08
Re-designed based on integration with chainlink
drinkcoffee Dec 22, 2023
aa82b49
Initial test plan
drinkcoffee Dec 22, 2023
2034b99
Revised documentation. Added allow listing
drinkcoffee Jan 10, 2024
b245fd7
Initial tests
drinkcoffee Jan 10, 2024
7515b9f
Add more tests
drinkcoffee Jan 10, 2024
f0bc1f1
Compiling
drinkcoffee Jan 11, 2024
3c29314
Fixed most of the build process for hardhat
drinkcoffee Jan 11, 2024
02f8980
Added more tests
drinkcoffee Jan 11, 2024
b0b8de3
Add more tests
drinkcoffee Jan 11, 2024
fbab874
Add more tests
drinkcoffee Jan 12, 2024
f875646
Rename tests
drinkcoffee Jan 12, 2024
e963736
Improve documentation
drinkcoffee Jan 12, 2024
26b4991
Clean compile on hardhat and forge.
drinkcoffee Jan 15, 2024
d3db1ae
Added more tests
drinkcoffee Jan 15, 2024
f231404
Improve test coverage
drinkcoffee Jan 15, 2024
f286c00
Emit events when adding offchain consumers
drinkcoffee Jan 15, 2024
68db3d5
RandomSeedProvider and RandomValues: 100% coverage
drinkcoffee Jan 15, 2024
6a3f5bf
Remove coverage report
drinkcoffee Jan 15, 2024
58eca56
Improve documentation
drinkcoffee Jan 16, 2024
36ec087
Improve documentation
drinkcoffee Jan 16, 2024
e17ea3d
Added initial version of Supra source adaptor
drinkcoffee Jan 16, 2024
a0aadd7
Add initial chainlink tests
drinkcoffee Jan 17, 2024
6110ec2
Run prettier
drinkcoffee Jan 18, 2024
c4c87c8
Fix test failure
drinkcoffee Jan 18, 2024
aaabda0
Add more tests
drinkcoffee Jan 18, 2024
7300f87
Completed chainlink tests
drinkcoffee Jan 19, 2024
e246a89
Switch to UUPS and added upgrade tests
drinkcoffee Jan 19, 2024
27eec2e
Added tests for supra adaptor
drinkcoffee Jan 19, 2024
5db497d
Improve documentation
drinkcoffee Jan 19, 2024
3356fce
Revert prettier changes across repo
drinkcoffee Jan 19, 2024
e1caa1b
Merged main
drinkcoffee Jan 19, 2024
19eb7a7
Revert prettier changes
drinkcoffee Jan 19, 2024
a43fad6
Remove package lock file
drinkcoffee Jan 22, 2024
c6ca3da
Fixed yarn merge issue
drinkcoffee Jan 22, 2024
61abd47
Ensure source used checking if a value is ready is the source supplie…
drinkcoffee Jan 22, 2024
f70d093
Remove chainlink package and instead include just the file needed
drinkcoffee Jan 22, 2024
d219997
Show version during forge test. Remove yarn install
drinkcoffee Jan 23, 2024
fcc02d1
Add more debug to github actions
drinkcoffee Jan 23, 2024
7626c5a
Add more debug to github actions
drinkcoffee Jan 23, 2024
5049c56
Fixed yaml format error
drinkcoffee Jan 23, 2024
b8628b4
Add more debug
drinkcoffee Jan 23, 2024
476ec56
Fixed capitalisation of directory name
drinkcoffee Jan 23, 2024
2b754da
Separate eslint and solhint
drinkcoffee Jan 23, 2024
11a9c13
Fix yarn scripts
drinkcoffee Jan 23, 2024
5f5bfdc
Fix so that eslint and solhint will now run in github actions
drinkcoffee Jan 23, 2024
9813597
Fix linter issues
drinkcoffee Jan 23, 2024
f33554f
Linter errors no longer show failure on github actions
drinkcoffee Jan 23, 2024
5076a2d
Improve readability
drinkcoffee Jan 23, 2024
3c80c72
Fixed documentation reflect the change from transparent upgrade proxy…
drinkcoffee Jan 24, 2024
89f3dda
Fix typos and improve documentation
drinkcoffee Jan 24, 2024
d39e5e9
Improved documentation
drinkcoffee Jan 24, 2024
6fe6f29
Switch to using block.hash rather than block.number for initial rando…
drinkcoffee Jan 24, 2024
cd5d9ba
Fix call to blockhash
drinkcoffee Jan 24, 2024
9dd9310
Fixed tests for initial seed values
drinkcoffee Jan 24, 2024
c895236
Merge branch 'main' into random
drinkcoffee Jan 24, 2024
7893007
Fixed subscription typo
drinkcoffee Jan 24, 2024
ce60b7a
Removed extra hashing for _fetchRandomValue
drinkcoffee Jan 24, 2024
e3775c6
Switch to Australian spelling of fulfilment for all random number rel…
drinkcoffee Jan 24, 2024
7a252e9
Fix slither issue: make VRF coordinator an immutable variable
drinkcoffee Jan 25, 2024
956c7ac
Set the initial version to the constant defining VERSION 0. This also…
drinkcoffee Jan 25, 2024
b26db2f
Resolve slither issues
drinkcoffee Jan 25, 2024
7c55aa0
Change RandomValues API to specify number of random numbers to be ret…
drinkcoffee Jan 31, 2024
f4876bd
Added explicit mapping for seaport types
drinkcoffee Jan 31, 2024
ae015c4
Update contracts/random/README.md
drinkcoffee Feb 1, 2024
5d95ea3
Update contracts/random/RandomSeedProvider.sol
drinkcoffee Feb 1, 2024
86e43a3
Switch naming from traditional to onchain in situations when the gene…
drinkcoffee Feb 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Comment on lines +4 to +9
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we be scrutinizing these deps?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Those are brought in by the ERC1155, ERC 721Permit, and ERC721Psi code. I have brought those in so that the forge build would work.

Both of them have been around for a long time. However, we aren't bringing in a specific version.

I think we should address improvements related to them in a separate PR.

[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 Expand Up @@ -40,13 +40,13 @@
bytes32 public constant UPGRADE_ROLE = bytes32("UPGRADE_ROLE");

/// @notice Mapping of Allowlisted addresses
mapping(address => bool) private addressAllowlist;

Check warning on line 43 in contracts/allowlist/OperatorAllowlistUpgradeable.sol

View workflow job for this annotation

GitHub Actions / Run solhint

Main key parameter in mapping addressAllowlist is not named

Check warning on line 43 in contracts/allowlist/OperatorAllowlistUpgradeable.sol

View workflow job for this annotation

GitHub Actions / Run solhint

Value parameter in mapping addressAllowlist is not named

/// @notice Mapping of Allowlisted implementation addresses
mapping(address => bool) private addressImplementationAllowlist;

Check warning on line 46 in contracts/allowlist/OperatorAllowlistUpgradeable.sol

View workflow job for this annotation

GitHub Actions / Run solhint

Main key parameter in mapping addressImplementationAllowlist is not named

Check warning on line 46 in contracts/allowlist/OperatorAllowlistUpgradeable.sol

View workflow job for this annotation

GitHub Actions / Run solhint

Value parameter in mapping addressImplementationAllowlist is not named

/// @notice Mapping of Allowlisted bytecodes
mapping(bytes32 => bool) private bytecodeAllowlist;

Check warning on line 49 in contracts/allowlist/OperatorAllowlistUpgradeable.sol

View workflow job for this annotation

GitHub Actions / Run solhint

Main key parameter in mapping bytecodeAllowlist is not named

Check warning on line 49 in contracts/allowlist/OperatorAllowlistUpgradeable.sol

View workflow job for this annotation

GitHub Actions / Run solhint

Value parameter in mapping bytecodeAllowlist is not named

/// ===== Initializer =====

Expand Down Expand Up @@ -98,7 +98,7 @@
function addWalletToAllowlist(address walletAddr) external onlyRole(REGISTRAR_ROLE) {
// get bytecode of wallet
bytes32 codeHash;
assembly {

Check warning on line 101 in contracts/allowlist/OperatorAllowlistUpgradeable.sol

View workflow job for this annotation

GitHub Actions / Run solhint

Avoid to use inline assembly. It is acceptable only in rare cases
codeHash := extcodehash(walletAddr)
}
bytecodeAllowlist[codeHash] = true;
Expand All @@ -117,7 +117,7 @@
function removeWalletFromAllowlist(address walletAddr) external onlyRole(REGISTRAR_ROLE) {
// get bytecode of wallet
bytes32 codeHash;
assembly {

Check warning on line 120 in contracts/allowlist/OperatorAllowlistUpgradeable.sol

View workflow job for this annotation

GitHub Actions / Run solhint

Avoid to use inline assembly. It is acceptable only in rare cases
codeHash := extcodehash(walletAddr)
}
delete bytecodeAllowlist[codeHash];
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
Loading