chore: move to vacp2p/foundry-template
This commit is contained in:
parent
a3193cec3d
commit
0d03e850dd
|
@ -0,0 +1,19 @@
|
|||
# EditorConfig http://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# All files
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.sol]
|
||||
indent_size = 4
|
||||
|
||||
[*.tree]
|
||||
indent_size = 1
|
15
.env.example
15
.env.example
|
@ -1,4 +1,11 @@
|
|||
ETHERSCAN_API_KEY=<YOUR_ETHERSCAN_KEY>
|
||||
SEPOLIA_URL=https://eth-sepolia.alchemyapi.io/v2/<YOUR ALCHEMY KEY>
|
||||
POLYGON_ZKEVM_TESTNET_URL=https://rpc.public.zkevm-test.net
|
||||
PRIVATE_KEY=<YOUR_PRIVATE_KEY>
|
||||
export API_KEY_ALCHEMY="YOUR_API_KEY_ALCHEMY"
|
||||
export API_KEY_ARBISCAN="YOUR_API_KEY_ARBISCAN"
|
||||
export API_KEY_BSCSCAN="YOUR_API_KEY_BSCSCAN"
|
||||
export API_KEY_ETHERSCAN="YOUR_API_KEY_ETHERSCAN"
|
||||
export API_KEY_GNOSISSCAN="YOUR_API_KEY_GNOSISSCAN"
|
||||
export API_KEY_INFURA="YOUR_API_KEY_INFURA"
|
||||
export API_KEY_OPTIMISTIC_ETHERSCAN="YOUR_API_KEY_OPTIMISTIC_ETHERSCAN"
|
||||
export API_KEY_POLYGONSCAN="YOUR_API_KEY_POLYGONSCAN"
|
||||
export API_KEY_SNOWTRACE="YOUR_API_KEY_SNOWTRACE"
|
||||
export MNEMONIC="YOUR_MNEMONIC"
|
||||
export FOUNDRY_PROFILE="default"
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
FooTest:test_Example() (gas: 8662)
|
|
@ -0,0 +1 @@
|
|||
lib/** linguist-vendored
|
|
@ -0,0 +1,13 @@
|
|||
## Description
|
||||
|
||||
Describe the changes made in your pull request here.
|
||||
|
||||
## Checklist
|
||||
|
||||
Ensure you completed **all of the steps** below before submitting your pull request:
|
||||
|
||||
- [ ] Added natspec comments?
|
||||
- [ ] Ran `forge snapshot`?
|
||||
- [ ] Ran `pnpm lint`?
|
||||
- [ ] Ran `forge test`?
|
||||
- [ ] Ran `pnpm verify`?
|
|
@ -0,0 +1,36 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# https://gist.github.com/vncsna/64825d5609c146e80de8b1fd623011ca
|
||||
set -euo pipefail
|
||||
|
||||
# Define the input vars
|
||||
GITHUB_REPOSITORY=${1?Error: Please pass username/repo, e.g. prb/foundry-template}
|
||||
GITHUB_REPOSITORY_OWNER=${2?Error: Please pass username, e.g. prb}
|
||||
GITHUB_REPOSITORY_DESCRIPTION=${3:-""} # If null then replace with empty string
|
||||
|
||||
echo "GITHUB_REPOSITORY: $GITHUB_REPOSITORY"
|
||||
echo "GITHUB_REPOSITORY_OWNER: $GITHUB_REPOSITORY_OWNER"
|
||||
echo "GITHUB_REPOSITORY_DESCRIPTION: $GITHUB_REPOSITORY_DESCRIPTION"
|
||||
|
||||
# jq is like sed for JSON data
|
||||
JQ_OUTPUT=`jq \
|
||||
--arg NAME "@$GITHUB_REPOSITORY" \
|
||||
--arg AUTHOR_NAME "$GITHUB_REPOSITORY_OWNER" \
|
||||
--arg URL "https://github.com/$GITHUB_REPOSITORY_OWNER" \
|
||||
--arg DESCRIPTION "$GITHUB_REPOSITORY_DESCRIPTION" \
|
||||
'.name = $NAME | .description = $DESCRIPTION | .author |= ( .name = $AUTHOR_NAME | .url = $URL )' \
|
||||
package.json
|
||||
`
|
||||
|
||||
# Overwrite package.json
|
||||
echo "$JQ_OUTPUT" > package.json
|
||||
|
||||
# Make sed command compatible in both Mac and Linux environments
|
||||
# Reference: https://stackoverflow.com/a/38595160/8696958
|
||||
sedi () {
|
||||
sed --version >/dev/null 2>&1 && sed -i -- "$@" || sed -i "" "$@"
|
||||
}
|
||||
|
||||
# Rename instances of "vacp2p/foundry-template" to the new repo name in README.md for badges only
|
||||
sedi "/gha/ s|vacp2p/foundry-template|"${GITHUB_REPOSITORY}"|;" "README.md"
|
||||
sedi "/gha-badge/ s|vacp2p/foundry-template|"${GITHUB_REPOSITORY}"|;" "README.md"
|
|
@ -1,60 +1,167 @@
|
|||
name: CI
|
||||
name: "CI"
|
||||
|
||||
env:
|
||||
API_KEY_ALCHEMY: ${{ secrets.API_KEY_ALCHEMY }}
|
||||
FOUNDRY_PROFILE: "ci"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "**.sol"
|
||||
- "scripts/**.ts"
|
||||
- "test/**.ts"
|
||||
- "hardhat.config.ts"
|
||||
- "package.json"
|
||||
- ".github/workflows/ci.yml"
|
||||
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "**.sol"
|
||||
- "scripts/**.ts"
|
||||
- "test/**.ts"
|
||||
- "hardhat.config.ts"
|
||||
- "package.json"
|
||||
- ".github/workflows/ci.yml"
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: "ubuntu-latest"
|
||||
steps:
|
||||
- name: "Check out the repo"
|
||||
uses: "actions/checkout@v3"
|
||||
with:
|
||||
submodules: "recursive"
|
||||
|
||||
- name: "Install Foundry"
|
||||
uses: "foundry-rs/foundry-toolchain@v1"
|
||||
|
||||
- name: "Install Pnpm"
|
||||
uses: "pnpm/action-setup@v2"
|
||||
with:
|
||||
version: "8"
|
||||
|
||||
- name: "Install Node.js"
|
||||
uses: "actions/setup-node@v3"
|
||||
with:
|
||||
cache: "pnpm"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: "Install the Node.js dependencies"
|
||||
run: "pnpm install"
|
||||
|
||||
- name: "Lint the contracts"
|
||||
run: "pnpm lint"
|
||||
|
||||
- name: "Add lint summary"
|
||||
run: |
|
||||
echo "## Lint result" >> $GITHUB_STEP_SUMMARY
|
||||
echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
build:
|
||||
runs-on: "ubuntu-latest"
|
||||
steps:
|
||||
- name: "Check out the repo"
|
||||
uses: "actions/checkout@v3"
|
||||
with:
|
||||
submodules: "recursive"
|
||||
|
||||
- name: "Install Foundry"
|
||||
uses: "foundry-rs/foundry-toolchain@v1"
|
||||
|
||||
- name: "Build the contracts and print their size"
|
||||
run: "forge build --sizes"
|
||||
|
||||
- name: "Add build summary"
|
||||
run: |
|
||||
echo "## Build result" >> $GITHUB_STEP_SUMMARY
|
||||
echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
test:
|
||||
needs: ["lint", "build"]
|
||||
runs-on: "ubuntu-latest"
|
||||
steps:
|
||||
- name: "Check out the repo"
|
||||
uses: "actions/checkout@v3"
|
||||
with:
|
||||
submodules: "recursive"
|
||||
|
||||
- name: "Install Foundry"
|
||||
uses: "foundry-rs/foundry-toolchain@v1"
|
||||
|
||||
- name: "Show the Foundry config"
|
||||
run: "forge config"
|
||||
|
||||
- name: "Generate a fuzz seed that changes weekly to avoid burning through RPC allowance"
|
||||
run: >
|
||||
echo "FOUNDRY_FUZZ_SEED=$(
|
||||
echo $(($EPOCHSECONDS - $EPOCHSECONDS % 604800))
|
||||
)" >> $GITHUB_ENV
|
||||
|
||||
- name: "Run the tests"
|
||||
run: "forge test"
|
||||
|
||||
- name: "Add test summary"
|
||||
run: |
|
||||
echo "## Tests result" >> $GITHUB_STEP_SUMMARY
|
||||
echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
coverage:
|
||||
needs: ["lint", "build"]
|
||||
runs-on: "ubuntu-latest"
|
||||
steps:
|
||||
- name: "Check out the repo"
|
||||
uses: "actions/checkout@v3"
|
||||
with:
|
||||
submodules: "recursive"
|
||||
|
||||
- name: "Install Foundry"
|
||||
uses: "foundry-rs/foundry-toolchain@v1"
|
||||
|
||||
- name: "Generate the coverage report using the unit and the integration tests"
|
||||
run: 'forge coverage --match-path "test/**/*.sol" --report lcov'
|
||||
|
||||
- name: "Upload coverage report to Codecov"
|
||||
uses: "codecov/codecov-action@v3"
|
||||
with:
|
||||
files: "./lcov.info"
|
||||
|
||||
- name: "Add coverage summary"
|
||||
run: |
|
||||
echo "## Coverage result" >> $GITHUB_STEP_SUMMARY
|
||||
echo "✅ Uploaded to Codecov" >> $GITHUB_STEP_SUMMARY
|
||||
verify:
|
||||
needs: ["lint", "build"]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Foundry
|
||||
uses: foundry-rs/foundry-toolchain@v1
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@v2
|
||||
with: { python-version: 3.9 }
|
||||
|
||||
- name: Install Java
|
||||
uses: actions/setup-java@v1
|
||||
with: { java-version: "11", java-package: jre }
|
||||
|
||||
- name: Install Certora CLI
|
||||
run: pip3 install certora-cli==5.0.5
|
||||
|
||||
- name: Install Solidity
|
||||
run: |
|
||||
wget https://github.com/ethereum/solidity/releases/download/v0.8.20/solc-static-linux
|
||||
chmod +x solc-static-linux
|
||||
sudo mv solc-static-linux /usr/local/bin/solc
|
||||
|
||||
- name: "Install Pnpm"
|
||||
uses: "pnpm/action-setup@v2"
|
||||
with:
|
||||
version: nightly
|
||||
version: "8"
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
- name: "Install Node.js"
|
||||
uses: "actions/setup-node@v3"
|
||||
with:
|
||||
node-version: 16
|
||||
cache: "yarn"
|
||||
- id: dependencies
|
||||
run: yarn install
|
||||
cache: "pnpm"
|
||||
node-version: "lts/*"
|
||||
|
||||
- id: lint
|
||||
run: yarn lint
|
||||
- name: "Install the Node.js dependencies"
|
||||
run: "pnpm install"
|
||||
|
||||
- id: test
|
||||
run: yarn test:verbose
|
||||
- name: Verify rules
|
||||
run: "pnpm verify"
|
||||
env:
|
||||
CERTORAKEY: ${{ secrets.CERTORAKEY }}
|
||||
|
||||
- id: coverage
|
||||
run: yarn coverage
|
||||
|
||||
- id: upload-coverage
|
||||
# run only in pull requests
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: zgosalvez/github-actions-report-lcov@v1
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
coverage-files: lcov.info
|
||||
artifact-name: code-coverage-report
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: 16
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
name: "Create"
|
||||
|
||||
# The workflow will run only when the "Use this template" button is used
|
||||
on:
|
||||
create:
|
||||
|
||||
jobs:
|
||||
create:
|
||||
# We only run this action when the repository isn't the template repository. References:
|
||||
# - https://docs.github.com/en/actions/learn-github-actions/contexts
|
||||
# - https://docs.github.com/en/actions/learn-github-actions/expressions
|
||||
if: ${{ !github.event.repository.is_template }}
|
||||
permissions: "write-all"
|
||||
runs-on: "ubuntu-latest"
|
||||
steps:
|
||||
- name: "Check out the repo"
|
||||
uses: "actions/checkout@v3"
|
||||
|
||||
- name: "Update package.json"
|
||||
env:
|
||||
GITHUB_REPOSITORY_DESCRIPTION: ${{ github.event.repository.description }}
|
||||
run:
|
||||
./.github/scripts/rename.sh "$GITHUB_REPOSITORY" "$GITHUB_REPOSITORY_OWNER" "$GITHUB_REPOSITORY_DESCRIPTION"
|
||||
|
||||
- name: "Add rename summary"
|
||||
run: |
|
||||
echo "## Commit result" >> $GITHUB_STEP_SUMMARY
|
||||
echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: "Remove files not needed in the user's copy of the template"
|
||||
run: |
|
||||
rm -f "./.github/FUNDING.yml"
|
||||
rm -f "./.github/scripts/rename.sh"
|
||||
rm -f "./.github/workflows/create.yml"
|
||||
|
||||
- name: "Add remove summary"
|
||||
run: |
|
||||
echo "## Remove result" >> $GITHUB_STEP_SUMMARY
|
||||
echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: "Update commit"
|
||||
uses: "stefanzweifel/git-auto-commit-action@v4"
|
||||
with:
|
||||
commit_message: "feat: initial commit"
|
||||
commit_options: "--amend"
|
||||
push_options: "--force"
|
||||
skip_fetch: true
|
||||
|
||||
- name: "Add commit summary"
|
||||
run: |
|
||||
echo "## Commit result" >> $GITHUB_STEP_SUMMARY
|
||||
echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
|
|
@ -1,14 +1,19 @@
|
|||
node_modules
|
||||
.env
|
||||
coverage
|
||||
coverage.json
|
||||
typechain
|
||||
|
||||
#Hardhat files
|
||||
# directories
|
||||
cache
|
||||
artifacts
|
||||
|
||||
#Foundry files
|
||||
cache_forge
|
||||
node_modules
|
||||
out
|
||||
|
||||
# files
|
||||
*.env
|
||||
*.log
|
||||
.DS_Store
|
||||
.pnp.*
|
||||
lcov.info
|
||||
yarn.lock
|
||||
|
||||
# broadcasts
|
||||
!broadcast
|
||||
broadcast/*
|
||||
broadcast/*/31337/
|
||||
|
||||
.certora_internal
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[submodule "lib/forge-std"]
|
||||
branch = "v1"
|
||||
path = lib/forge-std
|
||||
url = https://github.com/foundry-rs/forge-std
|
||||
branch = v1.6.0
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
node_modules
|
||||
artifacts
|
||||
# directories
|
||||
broadcast
|
||||
cache
|
||||
coverage*
|
||||
gasReporterOutput.json
|
||||
lib
|
||||
node_modules
|
||||
out
|
||||
|
||||
# files
|
||||
*.env
|
||||
*.log
|
||||
.DS_Store
|
||||
.pnp.*
|
||||
lcov.info
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
yarn.lock
|
||||
|
||||
slither.config.json
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
bracketSpacing: true
|
||||
printWidth: 120
|
||||
proseWrap: "always"
|
||||
singleQuote: false
|
||||
tabWidth: 2
|
||||
trailingComma: "all"
|
||||
useTabs: false
|
|
@ -1,7 +1,13 @@
|
|||
{
|
||||
"extends": "solhint:recommended",
|
||||
"rules": {
|
||||
"compiler-version": ["error", "^0.8.0"],
|
||||
"func-visibility": ["warn", { "ignoreConstructors": true }]
|
||||
"code-complexity": ["error", 8],
|
||||
"compiler-version": ["error", ">=0.8.19"],
|
||||
"func-name-mixedcase": "off",
|
||||
"func-visibility": ["error", { "ignoreConstructors": true }],
|
||||
"max-line-length": ["error", 120],
|
||||
"named-parameters-mapping": "warn",
|
||||
"no-console": "off",
|
||||
"not-rely-on-time": "off"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2023 Paul Razvan Berg
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,15 @@
|
|||
## Protocol properties and invariants
|
||||
|
||||
Below is a list of all documented properties and invariants of this project that must hold true.
|
||||
|
||||
- **Property** - Describes the property of the project / protocol that should ultimately be tested and formaly verified.
|
||||
- **Type** - Properties are split into 5 main types: **Valid State**, **State Transition**, **Variable Transition**,
|
||||
**High-Level Property**, **Unit Test**
|
||||
- **Risk** - One of **High**, **Medium** and **Low**, depending on the property's risk factor
|
||||
- **Tested** - Whether this property has been (fuzz) tested
|
||||
|
||||
| **Property** | **Type** | **Risk** | **Tested** |
|
||||
| ------------ | -------- | -------- | ---------- |
|
||||
| | | | |
|
||||
| | | | |
|
||||
| | | | |
|
211
README.md
211
README.md
|
@ -1,60 +1,201 @@
|
|||
# Hardhat Project for rln-contract
|
||||
# Foundry Template [![Github Actions][gha-badge]][gha] [![Foundry][foundry-badge]][foundry] [![License: MIT][license-badge]][license]
|
||||
|
||||
## Requirements
|
||||
[gha]: https://github.com/vacp2p/foundry-template/actions
|
||||
[gha-badge]: https://github.com/vacp2p/foundry-template/actions/workflows/ci.yml/badge.svg
|
||||
[foundry]: https://getfoundry.sh/
|
||||
[foundry-badge]: https://img.shields.io/badge/Built%20with-Foundry-FFDB1C.svg
|
||||
[license]: https://opensource.org/licenses/MIT
|
||||
[license-badge]: https://img.shields.io/badge/License-MIT-blue.svg
|
||||
|
||||
The following will need to be installed in order to use this repo. Please follow the links and instructions.
|
||||
A Foundry-based template for developing Solidity smart contracts, with sensible defaults.
|
||||
|
||||
- [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
|
||||
- You'll know you've done it right if you can run `git --version`
|
||||
- [Foundry / Foundryup](https://github.com/gakonst/foundry)
|
||||
- This will install `forge`, `cast`, and `anvil`
|
||||
- You can test you've installed them right by running `forge --version` and get an output like: `forge 0.2.0 (92f8951 2022-08-06T00:09:32.96582Z)`
|
||||
- To get the latest of each, just run `foundryup`
|
||||
- [Yarn](https://classic.yarnpkg.com/lang/en/docs/install)
|
||||
This is a fork of [PaulRBerg's template](https://github.com/PaulRBerg/foundry-template) and adjusted to Vac's smart
|
||||
contracts unit's needs. See [Upstream differences](#upstream-differences) to learn more about how this template differs
|
||||
from Paul's.
|
||||
|
||||
## Compilation
|
||||
## What's Inside
|
||||
|
||||
```shell
|
||||
yarn compile
|
||||
- [Forge](https://github.com/foundry-rs/foundry/blob/master/forge): compile, test, fuzz, format, and deploy smart
|
||||
contracts
|
||||
- [Forge Std](https://github.com/foundry-rs/forge-std): collection of helpful contracts and cheatcodes for testing
|
||||
- [Solhint Community](https://github.com/solhint-community/solhint-community): linter for Solidity code
|
||||
|
||||
## Getting Started
|
||||
|
||||
Click the [`Use this template`](https://github.com/vacp2p/foundry-template/generate) button at the top of the page to
|
||||
create a new repository with this repo as the initial state.
|
||||
|
||||
Or, if you prefer to install the template manually:
|
||||
|
||||
```sh
|
||||
$ mkdir my-project
|
||||
$ cd my-project
|
||||
$ forge init --template vacp2p/foundry-template
|
||||
$ pnpm install # install Solhint, Prettier, and other Node.js deps
|
||||
```
|
||||
|
||||
## Testing with Hardhat
|
||||
If this is your first time with Foundry, check out the
|
||||
[installation](https://github.com/foundry-rs/foundry#installation) instructions.
|
||||
|
||||
```shell
|
||||
yarn test:hardhat
|
||||
## Features
|
||||
|
||||
This template builds upon the frameworks and libraries mentioned above, so for details about their specific features,
|
||||
please consult their respective documentation.
|
||||
|
||||
For example, if you're interested in exploring Foundry in more detail, you should look at the
|
||||
[Foundry Book](https://book.getfoundry.sh/). In particular, you may be interested in reading the
|
||||
[Writing Tests](https://book.getfoundry.sh/forge/writing-tests.html) tutorial.
|
||||
|
||||
### Upstream differences
|
||||
|
||||
As mentioned above, this template is a fork with adjustments specific to the needs of Vac's smart contract service unit.
|
||||
These differences are:
|
||||
|
||||
- **Removal of [PRBTest](https://github.com/PaulRBerg/prb-test)** - In an attempt to keep dependence on third-party code
|
||||
low, we've decided to remove this library as a standard dependency of every project within Vac. If we do see a need
|
||||
for it, we might bring it back in the future.
|
||||
- **PROPERTIES.md** - For invariant testing and formal verification, we've introduced a `PROPERTIES.md` to document all
|
||||
protocol properties that must hold true.
|
||||
|
||||
### Sensible Defaults
|
||||
|
||||
This template comes with a set of sensible default configurations for you to use. These defaults can be found in the
|
||||
following files:
|
||||
|
||||
```text
|
||||
├── .editorconfig
|
||||
├── .gitignore
|
||||
├── .prettierignore
|
||||
├── .prettierrc.yml
|
||||
├── .solhint.json
|
||||
├── foundry.toml
|
||||
├── remappings.txt
|
||||
└── slither.config.json
|
||||
```
|
||||
|
||||
## Testing with Foundry
|
||||
### VSCode Integration
|
||||
|
||||
```shell
|
||||
yarn test:foundry
|
||||
This template is IDE agnostic, but for the best user experience, you may want to use it in VSCode alongside Nomic
|
||||
Foundation's [Solidity extension](https://marketplace.visualstudio.com/items?itemName=NomicFoundation.hardhat-solidity).
|
||||
|
||||
For guidance on how to integrate a Foundry project in VSCode, please refer to this
|
||||
[guide](https://book.getfoundry.sh/config/vscode).
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
This template comes with GitHub Actions pre-configured. Your contracts will be linted and tested on every push and pull
|
||||
request made to the `main` branch.
|
||||
|
||||
You can edit the CI script in [.github/workflows/ci.yml](./.github/workflows/ci.yml).
|
||||
|
||||
## Writing Tests
|
||||
|
||||
If you would like to view the logs in the terminal output you can add the `-vvv` flag and use
|
||||
[console.log](https://book.getfoundry.sh/faq?highlight=console.log#how-do-i-use-consolelog).
|
||||
|
||||
This template comes with an example test contract [Foo.t.sol](./test/Foo.t.sol)
|
||||
|
||||
## Usage
|
||||
|
||||
This is a list of the most frequently needed commands.
|
||||
|
||||
### Build
|
||||
|
||||
Build the contracts:
|
||||
|
||||
```sh
|
||||
$ forge build
|
||||
```
|
||||
|
||||
## Deploying
|
||||
### Clean
|
||||
|
||||
### Locally
|
||||
Delete the build artifacts and cache directories:
|
||||
|
||||
- To deploy on a local node, first start the local node and then run the deploy script
|
||||
|
||||
```shell
|
||||
yarn node
|
||||
yarn deploy:localhost
|
||||
```sh
|
||||
$ forge clean
|
||||
```
|
||||
|
||||
### Sepolia
|
||||
### Compile
|
||||
|
||||
- To deploy to an target network (like Sepolia), use the name as mentioned in the Hardhat config file.
|
||||
Compile the contracts:
|
||||
|
||||
```shell
|
||||
yarn deploy:sepolia
|
||||
# You may verify the contract using
|
||||
yarn verify:sepolia # Ensure you have set ETHERSCAN_API_KEY in your env
|
||||
```sh
|
||||
$ forge build
|
||||
```
|
||||
|
||||
## References
|
||||
### Coverage
|
||||
|
||||
For more information, see https://hardhat.org/hardhat-runner/docs/guides/project-setup
|
||||
Get a test coverage report:
|
||||
|
||||
```sh
|
||||
$ forge coverage
|
||||
```
|
||||
|
||||
### Deploy
|
||||
|
||||
Deploy to Anvil:
|
||||
|
||||
```sh
|
||||
$ forge script script/Deploy.s.sol --broadcast --fork-url http://localhost:8545
|
||||
```
|
||||
|
||||
For this script to work, you need to have a `MNEMONIC` environment variable set to a valid
|
||||
[BIP39 mnemonic](https://iancoleman.io/bip39/).
|
||||
|
||||
For instructions on how to deploy to a testnet or mainnet, check out the
|
||||
[Solidity Scripting](https://book.getfoundry.sh/tutorials/solidity-scripting.html) tutorial.
|
||||
|
||||
### Format
|
||||
|
||||
Format the contracts:
|
||||
|
||||
```sh
|
||||
$ forge fmt
|
||||
```
|
||||
|
||||
### Gas Usage
|
||||
|
||||
Get a gas report:
|
||||
|
||||
```sh
|
||||
$ forge test --gas-report
|
||||
```
|
||||
|
||||
### Lint
|
||||
|
||||
Lint the contracts:
|
||||
|
||||
```sh
|
||||
$ pnpm lint
|
||||
```
|
||||
|
||||
#### Fixing linting issues
|
||||
|
||||
For any errors in solidity files, run `forge fmt`. For errors in any other file type, run `pnpm prettier:write`.
|
||||
|
||||
### Test
|
||||
|
||||
Run the tests:
|
||||
|
||||
```sh
|
||||
$ forge test
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
1. Foundry uses [git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules) to manage dependencies. For
|
||||
detailed instructions on working with dependencies, please refer to the
|
||||
[guide](https://book.getfoundry.sh/projects/dependencies.html) in the book
|
||||
2. You don't have to create a `.env` file, but filling in the environment variables may be useful when debugging and
|
||||
testing against a fork.
|
||||
|
||||
## Related Efforts
|
||||
|
||||
- [abigger87/femplate](https://github.com/abigger87/femplate)
|
||||
- [cleanunicorn/ethereum-smartcontract-template](https://github.com/cleanunicorn/ethereum-smartcontract-template)
|
||||
- [foundry-rs/forge-template](https://github.com/foundry-rs/forge-template)
|
||||
- [FrankieIsLost/forge-template](https://github.com/FrankieIsLost/forge-template)
|
||||
|
||||
## License
|
||||
|
||||
Dual-licensed under MIT or Apache 2.0, refer to [LICENSE-MIT](LICENSE-MIT) or [LICENSE-APACHE](LICENSE-APACHE) for more information.
|
||||
This project is licensed under MIT.
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"files": ["src/Foo.sol"],
|
||||
"msg": "Verifying Foo.sol",
|
||||
"rule_sanity": "basic",
|
||||
"verify": "Foo:certora/specs/Foo.spec",
|
||||
"wait_for_results": "all",
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
methods {
|
||||
function id(uint256) external returns (uint256) envfree;
|
||||
}
|
||||
|
||||
rule checkIdOutputIsAlwaysEqualToInput {
|
||||
uint256 input;
|
||||
|
||||
assert id(input) == input;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
codecov:
|
||||
require_ci_to_pass: false
|
||||
comment: false
|
||||
ignore:
|
||||
- "script"
|
||||
- "test"
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
# advanced settings
|
||||
|
||||
# Prevents PR from being blocked with a reduction in coverage.
|
||||
# Note, if we want to re-enable this, a `threshold` value can be used
|
||||
# allow coverage to drop by x% while still posting a success status.
|
||||
# `informational`: https://docs.codecov.com/docs/commit-status#informational
|
||||
# `threshold`: https://docs.codecov.com/docs/commit-status#threshold
|
||||
informational: true
|
||||
patch:
|
||||
default:
|
||||
# advanced settings
|
||||
|
||||
# Prevents PR from being blocked with a reduction in coverage.
|
||||
# Note, if we want to re-enable this, a `threshold` value can be used
|
||||
# allow coverage to drop by x% while still posting a success status.
|
||||
# `informational`: https://docs.codecov.com/docs/commit-status#informational
|
||||
# `threshold`: https://docs.codecov.com/docs/commit-status#threshold
|
||||
informational: true
|
|
@ -1,9 +0,0 @@
|
|||
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
pragma solidity 0.8.15;
|
||||
|
||||
interface IVerifier {
|
||||
function verifyProof(uint256[2] memory a, uint256[2][2] memory b, uint256[2] memory c, uint256[2] memory input)
|
||||
external
|
||||
view
|
||||
returns (bool);
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.15;
|
||||
|
||||
import "./RlnBase.sol";
|
||||
|
||||
contract RLN is RlnBase {
|
||||
constructor(uint256 membershipDeposit, uint256 depth, address _verifier)
|
||||
RlnBase(membershipDeposit, depth, _verifier)
|
||||
{}
|
||||
|
||||
function _validateRegistration(uint256 idCommitment) internal pure override {}
|
||||
|
||||
function _validateSlash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof)
|
||||
internal
|
||||
pure
|
||||
override
|
||||
{}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
import { HardhatRuntimeEnvironment } from "hardhat/types";
|
||||
import { DeployFunction } from "hardhat-deploy/types";
|
||||
|
||||
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
||||
const { deployments, getUnnamedAccounts } = hre;
|
||||
const { deploy } = deployments;
|
||||
|
||||
const [deployer] = await getUnnamedAccounts();
|
||||
|
||||
await deploy("PoseidonT3", {
|
||||
from: deployer,
|
||||
log: true,
|
||||
});
|
||||
};
|
||||
export default func;
|
||||
func.tags = ["PoseidonT3"];
|
|
@ -1,16 +0,0 @@
|
|||
import { HardhatRuntimeEnvironment } from "hardhat/types";
|
||||
import { DeployFunction } from "hardhat-deploy/types";
|
||||
|
||||
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
||||
const { deployments, getUnnamedAccounts } = hre;
|
||||
const { deploy } = deployments;
|
||||
|
||||
const [deployer] = await getUnnamedAccounts();
|
||||
|
||||
await deploy("Verifier", {
|
||||
from: deployer,
|
||||
log: true,
|
||||
});
|
||||
};
|
||||
export default func;
|
||||
func.tags = ["RlnVerifier"];
|
|
@ -1,21 +0,0 @@
|
|||
import { HardhatRuntimeEnvironment } from "hardhat/types";
|
||||
import { DeployFunction } from "hardhat-deploy/types";
|
||||
|
||||
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
||||
const { deployments, getUnnamedAccounts } = hre;
|
||||
const { deploy } = deployments;
|
||||
|
||||
const [deployer] = await getUnnamedAccounts();
|
||||
|
||||
await deploy("BinaryIMT", {
|
||||
from: deployer,
|
||||
log: true,
|
||||
libraries: {
|
||||
PoseidonT3: (await deployments.get("PoseidonT3")).address,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export default func;
|
||||
func.tags = ["BinaryIMT"];
|
||||
func.dependencies = ["PoseidonT3"];
|
|
@ -1,26 +0,0 @@
|
|||
import { HardhatRuntimeEnvironment } from "hardhat/types";
|
||||
import { DeployFunction } from "hardhat-deploy/types";
|
||||
|
||||
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
||||
const { deployments, getUnnamedAccounts } = hre;
|
||||
const { deploy } = deployments;
|
||||
|
||||
const [deployer] = await getUnnamedAccounts();
|
||||
|
||||
const rlnVerifierAddress = (await deployments.get("Verifier")).address;
|
||||
|
||||
const binaryIMTAddress = (await deployments.get("BinaryIMT")).address;
|
||||
|
||||
await deploy("RLN", {
|
||||
from: deployer,
|
||||
log: true,
|
||||
args: [1000000000000000, 20, rlnVerifierAddress],
|
||||
libraries: {
|
||||
BinaryIMT: binaryIMTAddress,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export default func;
|
||||
func.tags = ["RLN"];
|
||||
func.dependencies = ["PoseidonT3", "RlnVerifier", "BinaryIMT"];
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -1 +0,0 @@
|
|||
1442
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
11155111
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
558
docs/index.md
558
docs/index.md
|
@ -1,558 +0,0 @@
|
|||
# Solidity API
|
||||
|
||||
## IVerifier
|
||||
|
||||
### verifyProof
|
||||
|
||||
```solidity
|
||||
function verifyProof(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[2] input) external view returns (bool)
|
||||
```
|
||||
|
||||
## RLN
|
||||
|
||||
### constructor
|
||||
|
||||
```solidity
|
||||
constructor(uint256 membershipDeposit, uint256 depth, address _verifier) public
|
||||
```
|
||||
|
||||
### \_validateRegistration
|
||||
|
||||
```solidity
|
||||
function _validateRegistration(uint256 idCommitment) internal pure
|
||||
```
|
||||
|
||||
_Inheriting contracts MUST override this function_
|
||||
|
||||
### \_validateSlash
|
||||
|
||||
```solidity
|
||||
function _validateSlash(uint256 idCommitment, address payable receiver, uint256[8] proof) internal pure
|
||||
```
|
||||
|
||||
## FullTree
|
||||
|
||||
```solidity
|
||||
error FullTree()
|
||||
```
|
||||
|
||||
The tree is full
|
||||
|
||||
## InsufficientDeposit
|
||||
|
||||
```solidity
|
||||
error InsufficientDeposit(uint256 required, uint256 provided)
|
||||
```
|
||||
|
||||
Invalid deposit amount
|
||||
|
||||
### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| -------- | ------- | --------------------------- |
|
||||
| required | uint256 | The required deposit amount |
|
||||
| provided | uint256 | The provided deposit amount |
|
||||
|
||||
## DuplicateIdCommitment
|
||||
|
||||
```solidity
|
||||
error DuplicateIdCommitment()
|
||||
```
|
||||
|
||||
Member is already registered
|
||||
|
||||
## FailedValidation
|
||||
|
||||
```solidity
|
||||
error FailedValidation()
|
||||
```
|
||||
|
||||
Failed validation on registration/slashing
|
||||
|
||||
## InvalidIdCommitment
|
||||
|
||||
```solidity
|
||||
error InvalidIdCommitment(uint256 idCommitment)
|
||||
```
|
||||
|
||||
Invalid idCommitment
|
||||
|
||||
## InvalidReceiverAddress
|
||||
|
||||
```solidity
|
||||
error InvalidReceiverAddress(address to)
|
||||
```
|
||||
|
||||
Invalid receiver address, when the receiver is the contract itself or 0x0
|
||||
|
||||
## MemberNotRegistered
|
||||
|
||||
```solidity
|
||||
error MemberNotRegistered(uint256 idCommitment)
|
||||
```
|
||||
|
||||
Member is not registered
|
||||
|
||||
## MemberHasNoStake
|
||||
|
||||
```solidity
|
||||
error MemberHasNoStake(uint256 idCommitment)
|
||||
```
|
||||
|
||||
Member has no stake
|
||||
|
||||
## InsufficientWithdrawalBalance
|
||||
|
||||
```solidity
|
||||
error InsufficientWithdrawalBalance()
|
||||
```
|
||||
|
||||
User has insufficient balance to withdraw
|
||||
|
||||
## InsufficientContractBalance
|
||||
|
||||
```solidity
|
||||
error InsufficientContractBalance()
|
||||
```
|
||||
|
||||
Contract has insufficient balance to return
|
||||
|
||||
## InvalidProof
|
||||
|
||||
```solidity
|
||||
error InvalidProof()
|
||||
```
|
||||
|
||||
Invalid proof
|
||||
|
||||
## InvalidPaginationQuery
|
||||
|
||||
```solidity
|
||||
error InvalidPaginationQuery(uint256 startIndex, uint256 endIndex)
|
||||
```
|
||||
|
||||
Invalid pagination query
|
||||
|
||||
## RlnBase
|
||||
|
||||
### Q
|
||||
|
||||
```solidity
|
||||
uint256 Q
|
||||
```
|
||||
|
||||
The Field
|
||||
|
||||
### MEMBERSHIP_DEPOSIT
|
||||
|
||||
```solidity
|
||||
uint256 MEMBERSHIP_DEPOSIT
|
||||
```
|
||||
|
||||
The deposit amount required to register as a member
|
||||
|
||||
### DEPTH
|
||||
|
||||
```solidity
|
||||
uint256 DEPTH
|
||||
```
|
||||
|
||||
The depth of the merkle tree
|
||||
|
||||
### SET_SIZE
|
||||
|
||||
```solidity
|
||||
uint256 SET_SIZE
|
||||
```
|
||||
|
||||
The size of the merkle tree, i.e 2^depth
|
||||
|
||||
### idCommitmentIndex
|
||||
|
||||
```solidity
|
||||
uint256 idCommitmentIndex
|
||||
```
|
||||
|
||||
The index of the next member to be registered
|
||||
|
||||
### stakedAmounts
|
||||
|
||||
```solidity
|
||||
mapping(uint256 => uint256) stakedAmounts
|
||||
```
|
||||
|
||||
The amount of eth staked by each member
|
||||
maps from idCommitment to the amount staked
|
||||
|
||||
### members
|
||||
|
||||
```solidity
|
||||
mapping(uint256 => uint256) members
|
||||
```
|
||||
|
||||
The membership status of each member
|
||||
maps from idCommitment to their index in the set
|
||||
|
||||
### indexToCommitment
|
||||
|
||||
```solidity
|
||||
mapping(uint256 => uint256) indexToCommitment
|
||||
```
|
||||
|
||||
the index to commitment mapping
|
||||
|
||||
### memberExists
|
||||
|
||||
```solidity
|
||||
mapping(uint256 => bool) memberExists
|
||||
```
|
||||
|
||||
The membership status of each member
|
||||
|
||||
### withdrawalBalance
|
||||
|
||||
```solidity
|
||||
mapping(address => uint256) withdrawalBalance
|
||||
```
|
||||
|
||||
The balance of each user that can be withdrawn
|
||||
|
||||
### verifier
|
||||
|
||||
```solidity
|
||||
contract IVerifier verifier
|
||||
```
|
||||
|
||||
The groth16 verifier contract
|
||||
|
||||
### deployedBlockNumber
|
||||
|
||||
```solidity
|
||||
uint32 deployedBlockNumber
|
||||
```
|
||||
|
||||
the deployed block number
|
||||
|
||||
### imtData
|
||||
|
||||
```solidity
|
||||
struct BinaryIMTData imtData
|
||||
```
|
||||
|
||||
the Incremental Merkle Tree
|
||||
|
||||
### MemberRegistered
|
||||
|
||||
```solidity
|
||||
event MemberRegistered(uint256 idCommitment, uint256 index)
|
||||
```
|
||||
|
||||
Emitted when a new member is added to the set
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------------ | ------- | ---------------------------------- |
|
||||
| idCommitment | uint256 | The idCommitment of the member |
|
||||
| index | uint256 | The index of the member in the set |
|
||||
|
||||
### MemberWithdrawn
|
||||
|
||||
```solidity
|
||||
event MemberWithdrawn(uint256 idCommitment, uint256 index)
|
||||
```
|
||||
|
||||
Emitted when a member is removed from the set
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------------ | ------- | ---------------------------------- |
|
||||
| idCommitment | uint256 | The idCommitment of the member |
|
||||
| index | uint256 | The index of the member in the set |
|
||||
|
||||
### onlyValidIdCommitment
|
||||
|
||||
```solidity
|
||||
modifier onlyValidIdCommitment(uint256 idCommitment)
|
||||
```
|
||||
|
||||
### constructor
|
||||
|
||||
```solidity
|
||||
constructor(uint256 membershipDeposit, uint256 depth, address _verifier) internal
|
||||
```
|
||||
|
||||
### register
|
||||
|
||||
```solidity
|
||||
function register(uint256 idCommitment) external payable virtual
|
||||
```
|
||||
|
||||
Allows a user to register as a member
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------------ | ------- | ------------------------------ |
|
||||
| idCommitment | uint256 | The idCommitment of the member |
|
||||
|
||||
### \_register
|
||||
|
||||
```solidity
|
||||
function _register(uint256 idCommitment, uint256 stake) internal virtual
|
||||
```
|
||||
|
||||
Registers a member
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------------ | ------- | -------------------------------------- |
|
||||
| idCommitment | uint256 | The idCommitment of the member |
|
||||
| stake | uint256 | The amount of eth staked by the member |
|
||||
|
||||
### \_validateRegistration
|
||||
|
||||
```solidity
|
||||
function _validateRegistration(uint256 idCommitment) internal view virtual
|
||||
```
|
||||
|
||||
_Inheriting contracts MUST override this function_
|
||||
|
||||
### slash
|
||||
|
||||
```solidity
|
||||
function slash(uint256 idCommitment, address payable receiver, uint256[8] proof) external virtual
|
||||
```
|
||||
|
||||
_Allows a user to slash a member_
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------------ | --------------- | ------------------------------ |
|
||||
| idCommitment | uint256 | The idCommitment of the member |
|
||||
| receiver | address payable | |
|
||||
| proof | uint256[8] | |
|
||||
|
||||
### \_slash
|
||||
|
||||
```solidity
|
||||
function _slash(uint256 idCommitment, address payable receiver, uint256[8] proof) internal virtual
|
||||
```
|
||||
|
||||
_Slashes a member by removing them from the set, and adding their
|
||||
stake to the receiver's available withdrawal balance_
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------------ | --------------- | -------------------------------- |
|
||||
| idCommitment | uint256 | The idCommitment of the member |
|
||||
| receiver | address payable | The address to receive the funds |
|
||||
| proof | uint256[8] | |
|
||||
|
||||
### \_validateSlash
|
||||
|
||||
```solidity
|
||||
function _validateSlash(uint256 idCommitment, address payable receiver, uint256[8] proof) internal view virtual
|
||||
```
|
||||
|
||||
### withdraw
|
||||
|
||||
```solidity
|
||||
function withdraw() external virtual
|
||||
```
|
||||
|
||||
Allows a user to withdraw funds allocated to them upon slashing a member
|
||||
|
||||
### isValidCommitment
|
||||
|
||||
```solidity
|
||||
function isValidCommitment(uint256 idCommitment) public pure returns (bool)
|
||||
```
|
||||
|
||||
### \_verifyProof
|
||||
|
||||
```solidity
|
||||
function _verifyProof(uint256 idCommitment, address receiver, uint256[8] proof) internal view virtual returns (bool)
|
||||
```
|
||||
|
||||
_Groth16 proof verification_
|
||||
|
||||
### root
|
||||
|
||||
```solidity
|
||||
function root() external view returns (uint256)
|
||||
```
|
||||
|
||||
### getCommitments
|
||||
|
||||
```solidity
|
||||
function getCommitments(uint256 startIndex, uint256 endIndex) public view returns (uint256[])
|
||||
```
|
||||
|
||||
## Pairing
|
||||
|
||||
### G1Point
|
||||
|
||||
```solidity
|
||||
struct G1Point {
|
||||
uint256 X;
|
||||
uint256 Y;
|
||||
}
|
||||
```
|
||||
|
||||
### G2Point
|
||||
|
||||
```solidity
|
||||
struct G2Point {
|
||||
uint256[2] X;
|
||||
uint256[2] Y;
|
||||
}
|
||||
```
|
||||
|
||||
### P1
|
||||
|
||||
```solidity
|
||||
function P1() internal pure returns (struct Pairing.G1Point)
|
||||
```
|
||||
|
||||
#### Return Values
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---------------------- | ------------------- |
|
||||
| [0] | struct Pairing.G1Point | the generator of G1 |
|
||||
|
||||
### P2
|
||||
|
||||
```solidity
|
||||
function P2() internal pure returns (struct Pairing.G2Point)
|
||||
```
|
||||
|
||||
#### Return Values
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---------------------- | ------------------- |
|
||||
| [0] | struct Pairing.G2Point | the generator of G2 |
|
||||
|
||||
### negate
|
||||
|
||||
```solidity
|
||||
function negate(struct Pairing.G1Point p) internal pure returns (struct Pairing.G1Point r)
|
||||
```
|
||||
|
||||
#### Return Values
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---------------------- | -------------------------------------------------------------- |
|
||||
| r | struct Pairing.G1Point | the negation of p, i.e. p.addition(p.negate()) should be zero. |
|
||||
|
||||
### addition
|
||||
|
||||
```solidity
|
||||
function addition(struct Pairing.G1Point p1, struct Pairing.G1Point p2) internal view returns (struct Pairing.G1Point r)
|
||||
```
|
||||
|
||||
#### Return Values
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---------------------- | --------------------------- |
|
||||
| r | struct Pairing.G1Point | the sum of two points of G1 |
|
||||
|
||||
### scalar_mul
|
||||
|
||||
```solidity
|
||||
function scalar_mul(struct Pairing.G1Point p, uint256 s) internal view returns (struct Pairing.G1Point r)
|
||||
```
|
||||
|
||||
#### Return Values
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
||||
| r | struct Pairing.G1Point | the product of a point on G1 and a scalar, i.e. p == p.scalar_mul(1) and p.addition(p) == p.scalar_mul(2) for all points p. |
|
||||
|
||||
### pairing
|
||||
|
||||
```solidity
|
||||
function pairing(struct Pairing.G1Point[] p1, struct Pairing.G2Point[] p2) internal view returns (bool)
|
||||
```
|
||||
|
||||
#### Return Values
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [0] | bool | the result of computing the pairing check e(p1[0], p2[0]) _ .... _ e(p1[n], p2[n]) == 1 For example pairing([P1(), P1().negate()], [P2(), P2()]) should return true. |
|
||||
|
||||
### pairingProd2
|
||||
|
||||
```solidity
|
||||
function pairingProd2(struct Pairing.G1Point a1, struct Pairing.G2Point a2, struct Pairing.G1Point b1, struct Pairing.G2Point b2) internal view returns (bool)
|
||||
```
|
||||
|
||||
Convenience method for a pairing check for two pairs.
|
||||
|
||||
### pairingProd3
|
||||
|
||||
```solidity
|
||||
function pairingProd3(struct Pairing.G1Point a1, struct Pairing.G2Point a2, struct Pairing.G1Point b1, struct Pairing.G2Point b2, struct Pairing.G1Point c1, struct Pairing.G2Point c2) internal view returns (bool)
|
||||
```
|
||||
|
||||
Convenience method for a pairing check for three pairs.
|
||||
|
||||
### pairingProd4
|
||||
|
||||
```solidity
|
||||
function pairingProd4(struct Pairing.G1Point a1, struct Pairing.G2Point a2, struct Pairing.G1Point b1, struct Pairing.G2Point b2, struct Pairing.G1Point c1, struct Pairing.G2Point c2, struct Pairing.G1Point d1, struct Pairing.G2Point d2) internal view returns (bool)
|
||||
```
|
||||
|
||||
Convenience method for a pairing check for four pairs.
|
||||
|
||||
## Verifier
|
||||
|
||||
### VerifyingKey
|
||||
|
||||
```solidity
|
||||
struct VerifyingKey {
|
||||
struct Pairing.G1Point alfa1;
|
||||
struct Pairing.G2Point beta2;
|
||||
struct Pairing.G2Point gamma2;
|
||||
struct Pairing.G2Point delta2;
|
||||
struct Pairing.G1Point[] IC;
|
||||
}
|
||||
```
|
||||
|
||||
### Proof
|
||||
|
||||
```solidity
|
||||
struct Proof {
|
||||
struct Pairing.G1Point A;
|
||||
struct Pairing.G2Point B;
|
||||
struct Pairing.G1Point C;
|
||||
}
|
||||
```
|
||||
|
||||
### verifyingKey
|
||||
|
||||
```solidity
|
||||
function verifyingKey() internal pure returns (struct Verifier.VerifyingKey vk)
|
||||
```
|
||||
|
||||
### verify
|
||||
|
||||
```solidity
|
||||
function verify(uint256[] input, struct Verifier.Proof proof) internal view returns (uint256)
|
||||
```
|
||||
|
||||
### verifyProof
|
||||
|
||||
```solidity
|
||||
function verifyProof(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[2] input) public view returns (bool r)
|
||||
```
|
||||
|
||||
#### Return Values
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | --------------------------- |
|
||||
| r | bool | bool true if proof is valid |
|
43
foundry.toml
43
foundry.toml
|
@ -1,6 +1,39 @@
|
|||
# Full reference https://github.com/foundry-rs/foundry/tree/master/config
|
||||
|
||||
[profile.default]
|
||||
src = 'contracts'
|
||||
out = 'out'
|
||||
libs = ['node_modules', 'lib']
|
||||
test = 'test'
|
||||
cache_path = 'cache_forge'
|
||||
auto_detect_solc = false
|
||||
block_timestamp = 1_680_220_800 # March 31, 2023 at 00:00 GMT
|
||||
bytecode_hash = "none"
|
||||
cbor_metadata = false
|
||||
evm_version = "shanghai"
|
||||
fuzz = { runs = 1_000 }
|
||||
gas_reports = ["*"]
|
||||
libs = ["lib"]
|
||||
optimizer = true
|
||||
optimizer_runs = 10_000
|
||||
out = "out"
|
||||
script = "script"
|
||||
solc = "0.8.19"
|
||||
src = "src"
|
||||
test = "test"
|
||||
|
||||
[profile.ci]
|
||||
fuzz = { runs = 10_000 }
|
||||
verbosity = 4
|
||||
|
||||
[etherscan]
|
||||
sepolia = { key = "${API_KEY_ETHERSCAN}" }
|
||||
|
||||
[fmt]
|
||||
bracket_spacing = true
|
||||
int_types = "long"
|
||||
line_length = 120
|
||||
multiline_func_header = "all"
|
||||
number_underscore = "thousands"
|
||||
quote_style = "double"
|
||||
tab_width = 4
|
||||
wrap_comments = true
|
||||
|
||||
[rpc_endpoints]
|
||||
localhost = "http://localhost:8545"
|
||||
sepolia = "https://eth-sepolia.g.alchemy.com/v2/${SEPOLIA_API_KEY}"
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
import * as dotenv from "dotenv";
|
||||
|
||||
import { HardhatUserConfig } from "hardhat/config";
|
||||
import { NetworksUserConfig } from "hardhat/types";
|
||||
|
||||
import "@nomicfoundation/hardhat-foundry";
|
||||
import "hardhat-deploy";
|
||||
import "@nomiclabs/hardhat-etherscan";
|
||||
import "@nomiclabs/hardhat-ethers";
|
||||
import "@nomiclabs/hardhat-waffle";
|
||||
import "hardhat-gas-reporter";
|
||||
import "solidity-docgen";
|
||||
|
||||
dotenv.config();
|
||||
const {
|
||||
SEPOLIA_URL,
|
||||
PRIVATE_KEY,
|
||||
ETHERSCAN_API_KEY,
|
||||
POLYGON_ZKEVM_TESTNET_URL,
|
||||
} = process.env;
|
||||
|
||||
const getNetworkConfig = (): NetworksUserConfig | undefined => {
|
||||
if (
|
||||
SEPOLIA_URL &&
|
||||
PRIVATE_KEY &&
|
||||
ETHERSCAN_API_KEY &&
|
||||
POLYGON_ZKEVM_TESTNET_URL
|
||||
) {
|
||||
return {
|
||||
sepolia: {
|
||||
url: SEPOLIA_URL,
|
||||
accounts: [PRIVATE_KEY],
|
||||
forking: {
|
||||
url: SEPOLIA_URL,
|
||||
},
|
||||
verify: {
|
||||
etherscan: {
|
||||
apiKey: ETHERSCAN_API_KEY,
|
||||
apiUrl: "https://api-sepolia.etherscan.io",
|
||||
},
|
||||
},
|
||||
},
|
||||
polygonZkevmTestnet: {
|
||||
url: POLYGON_ZKEVM_TESTNET_URL,
|
||||
accounts: [PRIVATE_KEY],
|
||||
forking: {
|
||||
url: POLYGON_ZKEVM_TESTNET_URL,
|
||||
},
|
||||
},
|
||||
localhost_integration: {
|
||||
url: "http://localhost:8545",
|
||||
},
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
// You need to export an object to set up your config
|
||||
// Go to https://hardhat.org/config/ to learn more
|
||||
|
||||
const config: HardhatUserConfig = {
|
||||
solidity: {
|
||||
compilers: [
|
||||
{
|
||||
version: "0.8.15",
|
||||
},
|
||||
{
|
||||
version: "0.6.11",
|
||||
},
|
||||
],
|
||||
},
|
||||
networks: getNetworkConfig(),
|
||||
};
|
||||
|
||||
export default config;
|
74
package.json
74
package.json
|
@ -1,53 +1,35 @@
|
|||
{
|
||||
"name": "rln-contract",
|
||||
"license": "(MIT OR Apache-2.0)",
|
||||
"scripts": {
|
||||
"start": "hardhat node --export-all deployments/allDeployments.json",
|
||||
"compile": "hardhat compile",
|
||||
"test": "yarn test:foundry && yarn test:hardhat",
|
||||
"test:verbose": "yarn test:foundry -vvv && yarn test:hardhat --verbose",
|
||||
"test:hardhat": "hardhat test",
|
||||
"test:hardhat:localhost": "yarn test:hardhat --network localhost",
|
||||
"test:hardhat:sepolia": "yarn test:hardhat --network sepolia",
|
||||
"test:foundry": "forge test",
|
||||
"deploy": "hardhat deploy --export-all deployments/allDeployments.json --network",
|
||||
"deploy:sepolia": "yarn deploy sepolia",
|
||||
"deploy:polygon_zkevm_testnet": "yarn deploy polygonZkevmTestnet",
|
||||
"deploy:localhost": "yarn deploy localhost",
|
||||
"verify:sepolia": "hardhat --network sepolia etherscan-verify",
|
||||
"coverage": "forge coverage --report lcov",
|
||||
"fmt": "prettier --write \"**/*.{js,ts}\"",
|
||||
"lint": "prettier --check \"**/*.{js,ts}\"",
|
||||
"prepare": "husky install",
|
||||
"docgen": "hardhat docgen"
|
||||
"name": "@vacp2p/foundry-template",
|
||||
"description": "Foundry-based template for developing Solidity smart contracts used by Vac",
|
||||
"version": "1.0.0",
|
||||
"author": {
|
||||
"name": "0x-r4bbit",
|
||||
"url": "https://github.com/vacp2p"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nomicfoundation/hardhat-foundry": "^1.0.0",
|
||||
"@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers",
|
||||
"@nomiclabs/hardhat-etherscan": "^3.1.7",
|
||||
"@nomiclabs/hardhat-waffle": "^2.0.3",
|
||||
"@types/chai": "^4.3.4",
|
||||
"@types/mocha": "^9.1.1",
|
||||
"@types/node": "^16.11.6",
|
||||
"chai": "^4.3.6",
|
||||
"ethereum-waffle": "^3.4.4",
|
||||
"ethers": "^5.7.2",
|
||||
"hardhat": "^2.9.9",
|
||||
"hardhat-deploy": "0.11.20",
|
||||
"hardhat-gas-reporter": "^1.0.8",
|
||||
"husky": "^8.0.2",
|
||||
"lint-staged": "^13.0.3",
|
||||
"solidity-docgen": "0.6.0-beta.35",
|
||||
"ts-node": "^10.8.1",
|
||||
"typescript": "^4.7.4"
|
||||
"prettier": "^3.0.0",
|
||||
"solhint-community": "^3.6.0"
|
||||
},
|
||||
"keywords": [
|
||||
"blockchain",
|
||||
"ethereum",
|
||||
"forge",
|
||||
"foundry",
|
||||
"smart-contracts",
|
||||
"solidity",
|
||||
"template"
|
||||
],
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"clean": "rm -rf cache out",
|
||||
"lint": "pnpm lint:sol && pnpm prettier:check",
|
||||
"verify": "certoraRun certora/certora.conf",
|
||||
"lint:sol": "forge fmt --check && pnpm solhint {script,src,test,certora}/**/*.sol",
|
||||
"prettier:check": "prettier --check **/*.{json,md,yml} --ignore-path=.prettierignore",
|
||||
"prettier:write": "prettier --write **/*.{json,md,yml} --ignore-path=.prettierignore"
|
||||
},
|
||||
"dependencies": {
|
||||
"@zk-kit/imt.sol": "^2.0.0-beta",
|
||||
"dotenv": "^16.0.1"
|
||||
},
|
||||
"lint-staged": {
|
||||
"**/*": [
|
||||
"prettier --write --ignore-unknown"
|
||||
]
|
||||
"@zk-kit/imt.sol": "2.0.0-beta",
|
||||
"poseidon-solidity": "^0.0.5"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,470 @@
|
|||
lockfileVersion: '6.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
'@zk-kit/imt.sol':
|
||||
specifier: 2.0.0-beta
|
||||
version: 2.0.0-beta
|
||||
poseidon-solidity:
|
||||
specifier: ^0.0.5
|
||||
version: 0.0.5
|
||||
|
||||
devDependencies:
|
||||
prettier:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0
|
||||
solhint-community:
|
||||
specifier: ^3.6.0
|
||||
version: 3.6.0
|
||||
|
||||
packages:
|
||||
|
||||
/@babel/code-frame@7.22.5:
|
||||
resolution: {integrity: sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/highlight': 7.22.5
|
||||
dev: true
|
||||
|
||||
/@babel/helper-validator-identifier@7.22.5:
|
||||
resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dev: true
|
||||
|
||||
/@babel/highlight@7.22.5:
|
||||
resolution: {integrity: sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/helper-validator-identifier': 7.22.5
|
||||
chalk: 2.4.2
|
||||
js-tokens: 4.0.0
|
||||
dev: true
|
||||
|
||||
/@solidity-parser/parser@0.16.1:
|
||||
resolution: {integrity: sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw==}
|
||||
dependencies:
|
||||
antlr4ts: 0.5.0-alpha.4
|
||||
dev: true
|
||||
|
||||
/@zk-kit/imt.sol@2.0.0-beta:
|
||||
resolution: {integrity: sha512-bH7RvI5WHAEswUwPspUY582O2+71xbYv5aL+DM4xkaA0GdMyMLUwf5c1yJ4wrt46hp07iXCXJsLXdtLNsTnvZw==}
|
||||
dependencies:
|
||||
poseidon-solidity: 0.0.5
|
||||
dev: false
|
||||
|
||||
/ajv@6.12.6:
|
||||
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
|
||||
dependencies:
|
||||
fast-deep-equal: 3.1.3
|
||||
fast-json-stable-stringify: 2.1.0
|
||||
json-schema-traverse: 0.4.1
|
||||
uri-js: 4.4.1
|
||||
dev: true
|
||||
|
||||
/ajv@8.12.0:
|
||||
resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==}
|
||||
dependencies:
|
||||
fast-deep-equal: 3.1.3
|
||||
json-schema-traverse: 1.0.0
|
||||
require-from-string: 2.0.2
|
||||
uri-js: 4.4.1
|
||||
dev: true
|
||||
|
||||
/ansi-regex@5.0.1:
|
||||
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/ansi-styles@3.2.1:
|
||||
resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
|
||||
engines: {node: '>=4'}
|
||||
dependencies:
|
||||
color-convert: 1.9.3
|
||||
dev: true
|
||||
|
||||
/ansi-styles@4.3.0:
|
||||
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
dev: true
|
||||
|
||||
/antlr4@4.13.0:
|
||||
resolution: {integrity: sha512-zooUbt+UscjnWyOrsuY/tVFL4rwrAGwOivpQmvmUDE22hy/lUA467Rc1rcixyRwcRUIXFYBwv7+dClDSHdmmew==}
|
||||
engines: {node: '>=16'}
|
||||
dev: true
|
||||
|
||||
/antlr4ts@0.5.0-alpha.4:
|
||||
resolution: {integrity: sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==}
|
||||
dev: true
|
||||
|
||||
/argparse@2.0.1:
|
||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||
dev: true
|
||||
|
||||
/ast-parents@0.0.1:
|
||||
resolution: {integrity: sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==}
|
||||
dev: true
|
||||
|
||||
/astral-regex@2.0.0:
|
||||
resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
dev: true
|
||||
|
||||
/brace-expansion@2.0.1:
|
||||
resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
dev: true
|
||||
|
||||
/callsites@3.1.0:
|
||||
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/chalk@2.4.2:
|
||||
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
|
||||
engines: {node: '>=4'}
|
||||
dependencies:
|
||||
ansi-styles: 3.2.1
|
||||
escape-string-regexp: 1.0.5
|
||||
supports-color: 5.5.0
|
||||
dev: true
|
||||
|
||||
/chalk@4.1.2:
|
||||
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
supports-color: 7.2.0
|
||||
dev: true
|
||||
|
||||
/color-convert@1.9.3:
|
||||
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
|
||||
dependencies:
|
||||
color-name: 1.1.3
|
||||
dev: true
|
||||
|
||||
/color-convert@2.0.1:
|
||||
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
||||
engines: {node: '>=7.0.0'}
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
dev: true
|
||||
|
||||
/color-name@1.1.3:
|
||||
resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
|
||||
dev: true
|
||||
|
||||
/color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
dev: true
|
||||
|
||||
/commander@10.0.1:
|
||||
resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
|
||||
engines: {node: '>=14'}
|
||||
dev: true
|
||||
|
||||
/cosmiconfig@8.2.0:
|
||||
resolution: {integrity: sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==}
|
||||
engines: {node: '>=14'}
|
||||
dependencies:
|
||||
import-fresh: 3.3.0
|
||||
js-yaml: 4.1.0
|
||||
parse-json: 5.2.0
|
||||
path-type: 4.0.0
|
||||
dev: true
|
||||
|
||||
/emoji-regex@8.0.0:
|
||||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||
dev: true
|
||||
|
||||
/error-ex@1.3.2:
|
||||
resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
|
||||
dependencies:
|
||||
is-arrayish: 0.2.1
|
||||
dev: true
|
||||
|
||||
/escape-string-regexp@1.0.5:
|
||||
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
dev: true
|
||||
|
||||
/fast-deep-equal@3.1.3:
|
||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||
dev: true
|
||||
|
||||
/fast-diff@1.3.0:
|
||||
resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
|
||||
dev: true
|
||||
|
||||
/fast-json-stable-stringify@2.1.0:
|
||||
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
|
||||
dev: true
|
||||
|
||||
/fs.realpath@1.0.0:
|
||||
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
||||
dev: true
|
||||
|
||||
/glob@8.1.0:
|
||||
resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
fs.realpath: 1.0.0
|
||||
inflight: 1.0.6
|
||||
inherits: 2.0.4
|
||||
minimatch: 5.1.6
|
||||
once: 1.4.0
|
||||
dev: true
|
||||
|
||||
/has-flag@3.0.0:
|
||||
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
|
||||
engines: {node: '>=4'}
|
||||
dev: true
|
||||
|
||||
/has-flag@4.0.0:
|
||||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/ignore@5.2.4:
|
||||
resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
|
||||
engines: {node: '>= 4'}
|
||||
dev: true
|
||||
|
||||
/import-fresh@3.3.0:
|
||||
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
|
||||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
parent-module: 1.0.1
|
||||
resolve-from: 4.0.0
|
||||
dev: true
|
||||
|
||||
/inflight@1.0.6:
|
||||
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
|
||||
dependencies:
|
||||
once: 1.4.0
|
||||
wrappy: 1.0.2
|
||||
dev: true
|
||||
|
||||
/inherits@2.0.4:
|
||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||
dev: true
|
||||
|
||||
/is-arrayish@0.2.1:
|
||||
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
|
||||
dev: true
|
||||
|
||||
/is-fullwidth-code-point@3.0.0:
|
||||
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/js-tokens@4.0.0:
|
||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
dev: true
|
||||
|
||||
/js-yaml@4.1.0:
|
||||
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
argparse: 2.0.1
|
||||
dev: true
|
||||
|
||||
/json-parse-even-better-errors@2.3.1:
|
||||
resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
|
||||
dev: true
|
||||
|
||||
/json-schema-traverse@0.4.1:
|
||||
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
|
||||
dev: true
|
||||
|
||||
/json-schema-traverse@1.0.0:
|
||||
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
|
||||
dev: true
|
||||
|
||||
/lines-and-columns@1.2.4:
|
||||
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
|
||||
dev: true
|
||||
|
||||
/lodash.truncate@4.4.2:
|
||||
resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==}
|
||||
dev: true
|
||||
|
||||
/lodash@4.17.21:
|
||||
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
|
||||
dev: true
|
||||
|
||||
/minimatch@5.1.6:
|
||||
resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
dev: true
|
||||
|
||||
/once@1.4.0:
|
||||
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
||||
dependencies:
|
||||
wrappy: 1.0.2
|
||||
dev: true
|
||||
|
||||
/parent-module@1.0.1:
|
||||
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
||||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
callsites: 3.1.0
|
||||
dev: true
|
||||
|
||||
/parse-json@5.2.0:
|
||||
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.22.5
|
||||
error-ex: 1.3.2
|
||||
json-parse-even-better-errors: 2.3.1
|
||||
lines-and-columns: 1.2.4
|
||||
dev: true
|
||||
|
||||
/path-type@4.0.0:
|
||||
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/pluralize@8.0.0:
|
||||
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
|
||||
engines: {node: '>=4'}
|
||||
dev: true
|
||||
|
||||
/poseidon-solidity@0.0.5:
|
||||
resolution: {integrity: sha512-NzrvSwHzvZgT4hvg2GyGqeR+UOU/eLSEt4wAoXEua+VaR7NTKKwx1X9bPlh1VMBEVEno+IWvkRBbidFGzTeAqQ==}
|
||||
dev: false
|
||||
|
||||
/prettier@2.8.8:
|
||||
resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/prettier@3.0.0:
|
||||
resolution: {integrity: sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/punycode@2.3.0:
|
||||
resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/require-from-string@2.0.2:
|
||||
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/resolve-from@4.0.0:
|
||||
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
||||
engines: {node: '>=4'}
|
||||
dev: true
|
||||
|
||||
/semver@6.3.1:
|
||||
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/slice-ansi@4.0.0:
|
||||
resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
astral-regex: 2.0.0
|
||||
is-fullwidth-code-point: 3.0.0
|
||||
dev: true
|
||||
|
||||
/solhint-community@3.6.0:
|
||||
resolution: {integrity: sha512-3WGi8nB9VSdC7B3xawktFoQkJEgX6rsUe7jWZJteDBdix+tAOGN+2ZhRr7Cyv1s+h5BRLSsNOXoh7Vg9KEeQbg==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@solidity-parser/parser': 0.16.1
|
||||
ajv: 6.12.6
|
||||
antlr4: 4.13.0
|
||||
ast-parents: 0.0.1
|
||||
chalk: 4.1.2
|
||||
commander: 10.0.1
|
||||
cosmiconfig: 8.2.0
|
||||
fast-diff: 1.3.0
|
||||
glob: 8.1.0
|
||||
ignore: 5.2.4
|
||||
js-yaml: 4.1.0
|
||||
lodash: 4.17.21
|
||||
pluralize: 8.0.0
|
||||
semver: 6.3.1
|
||||
strip-ansi: 6.0.1
|
||||
table: 6.8.1
|
||||
text-table: 0.2.0
|
||||
optionalDependencies:
|
||||
prettier: 2.8.8
|
||||
dev: true
|
||||
|
||||
/string-width@4.2.3:
|
||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
emoji-regex: 8.0.0
|
||||
is-fullwidth-code-point: 3.0.0
|
||||
strip-ansi: 6.0.1
|
||||
dev: true
|
||||
|
||||
/strip-ansi@6.0.1:
|
||||
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
ansi-regex: 5.0.1
|
||||
dev: true
|
||||
|
||||
/supports-color@5.5.0:
|
||||
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
|
||||
engines: {node: '>=4'}
|
||||
dependencies:
|
||||
has-flag: 3.0.0
|
||||
dev: true
|
||||
|
||||
/supports-color@7.2.0:
|
||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
has-flag: 4.0.0
|
||||
dev: true
|
||||
|
||||
/table@6.8.1:
|
||||
resolution: {integrity: sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
dependencies:
|
||||
ajv: 8.12.0
|
||||
lodash.truncate: 4.4.2
|
||||
slice-ansi: 4.0.0
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
dev: true
|
||||
|
||||
/text-table@0.2.0:
|
||||
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
|
||||
dev: true
|
||||
|
||||
/uri-js@4.4.1:
|
||||
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
||||
dependencies:
|
||||
punycode: 2.3.0
|
||||
dev: true
|
||||
|
||||
/wrappy@1.0.2:
|
||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||
dev: true
|
|
@ -1,8 +1,3 @@
|
|||
@ensdomains/=node_modules/@ensdomains/
|
||||
ds-test/=lib/forge-std/lib/ds-test/src/
|
||||
eth-gas-reporter/=node_modules/eth-gas-reporter/
|
||||
forge-std/=lib/forge-std/src/
|
||||
hardhat-deploy/=node_modules/hardhat-deploy/
|
||||
hardhat/=node_modules/hardhat/
|
||||
@zk-kit/imt.sol/=node_modules/@zk-kit/imt.sol/
|
||||
poseidon-solidity/=node_modules/poseidon-solidity/
|
|
@ -0,0 +1,41 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.15;
|
||||
|
||||
import { Script } from "forge-std/Script.sol";
|
||||
|
||||
abstract contract BaseScript is Script {
|
||||
/// @dev Included to enable compilation of the script without a $MNEMONIC environment variable.
|
||||
string internal constant TEST_MNEMONIC = "test test test test test test test test test test test junk";
|
||||
|
||||
/// @dev Needed for the deterministic deployments.
|
||||
bytes32 internal constant ZERO_SALT = bytes32(0);
|
||||
|
||||
/// @dev The address of the transaction broadcaster.
|
||||
address internal broadcaster;
|
||||
|
||||
/// @dev Used to derive the broadcaster's address if $ETH_FROM is not defined.
|
||||
string internal mnemonic;
|
||||
|
||||
/// @dev Initializes the transaction broadcaster like this:
|
||||
///
|
||||
/// - If $ETH_FROM is defined, use it.
|
||||
/// - Otherwise, derive the broadcaster address from $MNEMONIC.
|
||||
/// - If $MNEMONIC is not defined, default to a test mnemonic.
|
||||
///
|
||||
/// The use case for $ETH_FROM is to specify the broadcaster key and its address via the command line.
|
||||
constructor() {
|
||||
address from = vm.envOr({ name: "ETH_FROM", defaultValue: address(0) });
|
||||
if (from != address(0)) {
|
||||
broadcaster = from;
|
||||
} else {
|
||||
mnemonic = vm.envOr({ name: "MNEMONIC", defaultValue: TEST_MNEMONIC });
|
||||
(broadcaster,) = deriveRememberKey({ mnemonic: mnemonic, index: 0 });
|
||||
}
|
||||
}
|
||||
|
||||
modifier broadcast() {
|
||||
vm.startBroadcast(broadcaster);
|
||||
_;
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity ^0.8.15;
|
||||
|
||||
import { Verifier } from "../src/RlnVerifier.sol";
|
||||
import { Rln } from "../src/Rln.sol";
|
||||
import { BaseScript } from "./Base.s.sol";
|
||||
import { DeploymentConfig } from "./DeploymentConfig.s.sol";
|
||||
|
||||
contract Deploy is BaseScript {
|
||||
function run() public returns (Rln rln, DeploymentConfig deploymentConfig) {
|
||||
deploymentConfig = new DeploymentConfig(broadcaster);
|
||||
|
||||
|
||||
|
||||
vm.startBroadcast(broadcaster);
|
||||
// step 1: deploy the verifier
|
||||
Verifier verifier = new Verifier();
|
||||
// step 2: deploy the rln contract
|
||||
rln = new Rln(0, 20, address(verifier));
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
//// SPDX-License-Identifier: UNLICENSED
|
||||
|
||||
pragma solidity ^0.8.15;
|
||||
|
||||
import { Script } from "forge-std/Script.sol";
|
||||
|
||||
contract DeploymentConfig is Script {
|
||||
error DeploymentConfig_InvalidDeployerAddress();
|
||||
error DeploymentConfig_NoConfigForChain(uint256);
|
||||
|
||||
struct NetworkConfig {
|
||||
address deployer;
|
||||
}
|
||||
|
||||
NetworkConfig public activeNetworkConfig;
|
||||
|
||||
address private deployer;
|
||||
|
||||
constructor(address _broadcaster) {
|
||||
if (_broadcaster == address(0)) revert DeploymentConfig_InvalidDeployerAddress();
|
||||
deployer = _broadcaster;
|
||||
if (block.chainid == 31_337) {
|
||||
activeNetworkConfig = getOrCreateAnvilEthConfig();
|
||||
} else if (block.chainid == 11155111) {
|
||||
activeNetworkConfig = getOrCreateSepoliaEthConfig();
|
||||
} else {
|
||||
revert DeploymentConfig_NoConfigForChain(block.chainid);
|
||||
}
|
||||
}
|
||||
|
||||
function getOrCreateAnvilEthConfig() public view returns (NetworkConfig memory) {
|
||||
return NetworkConfig({ deployer: deployer });
|
||||
}
|
||||
|
||||
function getOrCreateSepoliaEthConfig() public view returns (NetworkConfig memory) {
|
||||
return NetworkConfig({ deployer: deployer });
|
||||
}
|
||||
|
||||
// This function is a hack to have it excluded by `forge coverage` until
|
||||
// https://github.com/foundry-rs/foundry/issues/2988 is fixed.
|
||||
// See: https://github.com/foundry-rs/foundry/issues/2988#issuecomment-1437784542
|
||||
// for more info.
|
||||
// solhint-disable-next-line
|
||||
function test() public { }
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
contract_name="$1"
|
||||
|
||||
if [ -z "$contract_name" ]; then
|
||||
echo "Usage: ./script/deploy.sh <contract_name>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Sourcing .env"
|
||||
source .env
|
||||
|
||||
# Check if appropriate env vars are set
|
||||
if [ -z "$RPC_URL" ]; then
|
||||
echo "RPC_URL is not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$PRIVATE_KEY" ]; then
|
||||
echo "PRIVATE_KEY is not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Deploying $contract_name..."
|
||||
|
||||
# Deploy the contract
|
||||
if [ "$contract_name" = "rln" ]; then
|
||||
chain_id=$(cast chain-id --rpc-url "$RPC_URL")
|
||||
|
||||
chain_name=""
|
||||
verifier_url=""
|
||||
if [ -z "$chain_id" ]; then
|
||||
echo "Failed to get chain id"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$chain_id" = "11155111" ]; then
|
||||
chain_name="sepolia"
|
||||
else
|
||||
echo "Invalid chain id, try again with sepolia"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
forge script script/Deploy.s.sol:Deploy --rpc-url "$RPC_URL" --private-key "$PRIVATE_KEY" --broadcast -v --json
|
||||
echo "Deployed Rln contracts, Now verifying"
|
||||
|
||||
# Get the PoseidonT3 contract address from ./broadcast/Deploy.s.sol/$chain_id/run-latest.json
|
||||
poseidon_t3_name=$(cat ./broadcast/Deploy.s.sol/$chain_id/run-latest.json | jq -r '.["transactions"][0]["contractName"]')
|
||||
poseidon_t3_address=$(cat ./broadcast/Deploy.s.sol/$chain_id/run-latest.json | jq -r '.["transactions"][0]["contractAddress"]')
|
||||
|
||||
echo "Verifying $poseidon_t3_name library"
|
||||
forge verify-contract $poseidon_t3_address --chain $chain_name $poseidon_t3_name --watch
|
||||
|
||||
# Get the BinaryIMT contract address from ./broadcast/Deploy.s.sol/$chain_id/run-latest.json
|
||||
binary_imt_name=$(cat ./broadcast/Deploy.s.sol/$chain_id/run-latest.json | jq -r '.["transactions"][1]["contractName"]')
|
||||
binary_imt_address=$(cat ./broadcast/Deploy.s.sol/$chain_id/run-latest.json | jq -r '.["transactions"][1]["contractAddress"]')
|
||||
|
||||
echo "Verifying $binary_imt_name library"
|
||||
forge verify-contract --libraries "poseidon-solidity/PoseidonT3.sol:$poseidon_t3_name:$poseidon_t3_address" $binary_imt_address --chain $chain_name $binary_imt_name --watch
|
||||
|
||||
# Get the Verifier contract address from ./broadcast/Deploy.s.sol/$chain_id/run-latest.json
|
||||
verifier_name=$(cat ./broadcast/Deploy.s.sol/$chain_id/run-latest.json | jq -r '.["transactions"][2]["contractName"]')
|
||||
verifier_address=$(cat ./broadcast/Deploy.s.sol/$chain_id/run-latest.json | jq -r '.["transactions"][2]["contractAddress"]')
|
||||
|
||||
echo "Verifying $verifier_name library"
|
||||
forge verify-contract $verifier_address --chain $chain_name $verifier_name --watch
|
||||
|
||||
# Get the Rln contract address from ./broadcast/Deploy.s.sol/$chain_id/run-latest.json
|
||||
rln_name=$(cat ./broadcast/Deploy.s.sol/$chain_id/run-latest.json | jq -r '.["transactions"][3]["contractName"]')
|
||||
rln_address=$(cat ./broadcast/Deploy.s.sol/$chain_id/run-latest.json | jq -r '.["transactions"][3]["contractAddress"]')
|
||||
|
||||
echo "Verifying $rln_name library"
|
||||
forge verify-contract \
|
||||
$rln_address \
|
||||
--libraries "poseidon-solidity/PoseidonT3.sol:$poseidon_t3_name:$poseidon_t3_address" \
|
||||
--libraries "@zk-kit/imt.sol/BinaryIMT.sol:$binary_imt_name:$binary_imt_address" \
|
||||
--chain $chain_name \
|
||||
$rln_name \
|
||||
--watch \
|
||||
--constructor-args $(cast abi-encode "constructor(uint256,uint256,address)" 0 20 "$verifier_address")
|
||||
|
||||
echo "Verified $rln_name contract, now dumping the artifacts to ./deployments/$chain_id/latest.json"
|
||||
|
||||
# Dump the artifacts to ./deployments/$chain_id/latest.json
|
||||
mkdir -p ./deployments/$chain_id
|
||||
cat ./broadcast/Deploy.s.sol/$chain_id/run-latest.json | jq -r '.["transactions"]' > ./deployments/$chain_id/latest.json
|
||||
else
|
||||
echo "Invalid contract name, please use rln."
|
||||
fi
|
|
@ -1,3 +1,8 @@
|
|||
{
|
||||
"filter_paths": "contracts"
|
||||
"detectors_to_exclude": "naming-convention,reentrancy-events,solc-version,timestamp",
|
||||
"filter_paths": "(lib|test)",
|
||||
"solc_remaps": [
|
||||
"@openzeppelin/contracts=lib/openzeppelin-contracts/contracts/",
|
||||
"forge-std/=lib/forge-std/src/"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
pragma solidity ^0.8.15;
|
||||
|
||||
interface IVerifier {
|
||||
function verifyProof(
|
||||
uint256[2] memory a,
|
||||
uint256[2][2] memory b,
|
||||
uint256[2] memory c,
|
||||
uint256[2] memory input
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (bool);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.15;
|
||||
|
||||
import "./RlnBase.sol";
|
||||
|
||||
contract Rln is RlnBase {
|
||||
constructor(
|
||||
uint256 membershipDeposit,
|
||||
uint256 depth,
|
||||
address _verifier
|
||||
)
|
||||
RlnBase(membershipDeposit, depth, _verifier)
|
||||
{ }
|
||||
|
||||
function _validateRegistration(uint256 idCommitment) internal pure override { }
|
||||
|
||||
function _validateSlash(
|
||||
uint256 idCommitment,
|
||||
address payable receiver,
|
||||
uint256[8] calldata proof
|
||||
)
|
||||
internal
|
||||
pure
|
||||
override
|
||||
{ }
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity 0.8.15;
|
||||
pragma solidity ^0.8.15;
|
||||
|
||||
import {IVerifier} from "./IVerifier.sol";
|
||||
import {BinaryIMT, BinaryIMTData} from "@zk-kit/imt.sol/BinaryIMT.sol";
|
||||
import { IVerifier } from "./IVerifier.sol";
|
||||
import { BinaryIMT, BinaryIMTData } from "@zk-kit/imt.sol/BinaryIMT.sol";
|
||||
|
||||
/// The tree is full
|
||||
error FullTree();
|
||||
|
@ -45,7 +45,8 @@ error InvalidPaginationQuery(uint256 startIndex, uint256 endIndex);
|
|||
|
||||
abstract contract RlnBase {
|
||||
/// @notice The Field
|
||||
uint256 public constant Q = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
|
||||
uint256 public constant Q =
|
||||
21_888_242_871_839_275_222_246_405_745_257_275_088_548_364_400_416_034_343_698_204_186_575_808_495_617;
|
||||
|
||||
/// @notice The deposit amount required to register as a member
|
||||
uint256 public immutable MEMBERSHIP_DEPOSIT;
|
||||
|
@ -141,7 +142,11 @@ abstract contract RlnBase {
|
|||
|
||||
/// @dev Allows a user to slash a member
|
||||
/// @param idCommitment The idCommitment of the member
|
||||
function slash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof)
|
||||
function slash(
|
||||
uint256 idCommitment,
|
||||
address payable receiver,
|
||||
uint256[8] calldata proof
|
||||
)
|
||||
external
|
||||
virtual
|
||||
onlyValidIdCommitment(idCommitment)
|
||||
|
@ -185,7 +190,11 @@ abstract contract RlnBase {
|
|||
emit MemberWithdrawn(idCommitment, index);
|
||||
}
|
||||
|
||||
function _validateSlash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof)
|
||||
function _validateSlash(
|
||||
uint256 idCommitment,
|
||||
address payable receiver,
|
||||
uint256[8] calldata proof
|
||||
)
|
||||
internal
|
||||
view
|
||||
virtual;
|
||||
|
@ -209,7 +218,11 @@ abstract contract RlnBase {
|
|||
}
|
||||
|
||||
/// @dev Groth16 proof verification
|
||||
function _verifyProof(uint256 idCommitment, address receiver, uint256[8] calldata proof)
|
||||
function _verifyProof(
|
||||
uint256 idCommitment,
|
||||
address receiver,
|
||||
uint256[8] calldata proof
|
||||
)
|
||||
internal
|
||||
view
|
||||
virtual
|
|
@ -1,8 +1,15 @@
|
|||
// File: https://github.com/Rate-Limiting-Nullifier/rln-contract-v1/blob/main/src/RLNVerifier.sol
|
||||
// Copyright 2017 Christian Reitwiessner
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
||||
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
||||
// Software.
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// 2019 OKIMS
|
||||
// ported to solidity 0.6
|
||||
|
@ -11,7 +18,7 @@
|
|||
//
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity ^0.6.11;
|
||||
pragma solidity ^0.8.11;
|
||||
|
||||
library Pairing {
|
||||
struct G1Point {
|
||||
|
@ -35,12 +42,12 @@ library Pairing {
|
|||
// Original code point
|
||||
return G2Point(
|
||||
[
|
||||
11559732032986387107991004021392285783925812861821192530917403151452391805634,
|
||||
10857046999023057135944570762232829481370756359578518086990519993285655852781
|
||||
11_559_732_032_986_387_107_991_004_021_392_285_783_925_812_861_821_192_530_917_403_151_452_391_805_634,
|
||||
10_857_046_999_023_057_135_944_570_762_232_829_481_370_756_359_578_518_086_990_519_993_285_655_852_781
|
||||
],
|
||||
[
|
||||
4082367875863433681332203403145435568316851327593401208105741076214120093531,
|
||||
8495653923123431417604973247489272438418190587263600148770280649306958101930
|
||||
4_082_367_875_863_433_681_332_203_403_145_435_568_316_851_327_593_401_208_105_741_076_214_120_093_531,
|
||||
8_495_653_923_123_431_417_604_973_247_489_272_438_418_190_587_263_600_148_770_280_649_306_958_101_930
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -57,7 +64,8 @@ library Pairing {
|
|||
|
||||
function negate(G1Point memory p) internal pure returns (G1Point memory r) {
|
||||
// The prime q in the base field F_q for G1
|
||||
uint256 q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
|
||||
uint256 q =
|
||||
21_888_242_871_839_275_222_246_405_745_257_275_088_696_311_157_297_823_662_689_037_894_645_226_208_583;
|
||||
if (p.X == 0 && p.Y == 0) {
|
||||
return G1Point(0, 0);
|
||||
}
|
||||
|
@ -108,7 +116,7 @@ library Pairing {
|
|||
require(p1.length == p2.length, "pairing-lengths-failed");
|
||||
uint256 elements = p1.length;
|
||||
uint256 inputSize = elements * 6;
|
||||
uint256[] memory input = new uint[](inputSize);
|
||||
uint256[] memory input = new uint256[](inputSize);
|
||||
for (uint256 i = 0; i < elements; i++) {
|
||||
input[i * 6 + 0] = p1[i].X;
|
||||
input[i * 6 + 1] = p1[i].Y;
|
||||
|
@ -131,7 +139,12 @@ library Pairing {
|
|||
}
|
||||
/// Convenience method for a pairing check for two pairs.
|
||||
|
||||
function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2)
|
||||
function pairingProd2(
|
||||
G1Point memory a1,
|
||||
G2Point memory a2,
|
||||
G1Point memory b1,
|
||||
G2Point memory b2
|
||||
)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
|
@ -153,7 +166,11 @@ library Pairing {
|
|||
G2Point memory b2,
|
||||
G1Point memory c1,
|
||||
G2Point memory c2
|
||||
) internal view returns (bool) {
|
||||
)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
G1Point[] memory p1 = new G1Point[](3);
|
||||
G2Point[] memory p2 = new G2Point[](3);
|
||||
p1[0] = a1;
|
||||
|
@ -175,7 +192,11 @@ library Pairing {
|
|||
G2Point memory c2,
|
||||
G1Point memory d1,
|
||||
G2Point memory d2
|
||||
) internal view returns (bool) {
|
||||
)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
G1Point[] memory p1 = new G1Point[](4);
|
||||
G2Point[] memory p2 = new G2Point[](4);
|
||||
p1[0] = a1;
|
||||
|
@ -209,60 +230,61 @@ contract Verifier {
|
|||
|
||||
function verifyingKey() internal pure returns (VerifyingKey memory vk) {
|
||||
vk.alfa1 = Pairing.G1Point(
|
||||
20491192805390485299153009773594534940189261866228447918068658471970481763042,
|
||||
9383485363053290200918347156157836566562967994039712273449902621266178545958
|
||||
20_491_192_805_390_485_299_153_009_773_594_534_940_189_261_866_228_447_918_068_658_471_970_481_763_042,
|
||||
9_383_485_363_053_290_200_918_347_156_157_836_566_562_967_994_039_712_273_449_902_621_266_178_545_958
|
||||
);
|
||||
|
||||
vk.beta2 = Pairing.G2Point(
|
||||
[
|
||||
4252822878758300859123897981450591353533073413197771768651442665752259397132,
|
||||
6375614351688725206403948262868962793625744043794305715222011528459656738731
|
||||
4_252_822_878_758_300_859_123_897_981_450_591_353_533_073_413_197_771_768_651_442_665_752_259_397_132,
|
||||
6_375_614_351_688_725_206_403_948_262_868_962_793_625_744_043_794_305_715_222_011_528_459_656_738_731
|
||||
],
|
||||
[
|
||||
21847035105528745403288232691147584728191162732299865338377159692350059136679,
|
||||
10505242626370262277552901082094356697409835680220590971873171140371331206856
|
||||
21_847_035_105_528_745_403_288_232_691_147_584_728_191_162_732_299_865_338_377_159_692_350_059_136_679,
|
||||
10_505_242_626_370_262_277_552_901_082_094_356_697_409_835_680_220_590_971_873_171_140_371_331_206_856
|
||||
]
|
||||
);
|
||||
vk.gamma2 = Pairing.G2Point(
|
||||
[
|
||||
11559732032986387107991004021392285783925812861821192530917403151452391805634,
|
||||
10857046999023057135944570762232829481370756359578518086990519993285655852781
|
||||
11_559_732_032_986_387_107_991_004_021_392_285_783_925_812_861_821_192_530_917_403_151_452_391_805_634,
|
||||
10_857_046_999_023_057_135_944_570_762_232_829_481_370_756_359_578_518_086_990_519_993_285_655_852_781
|
||||
],
|
||||
[
|
||||
4082367875863433681332203403145435568316851327593401208105741076214120093531,
|
||||
8495653923123431417604973247489272438418190587263600148770280649306958101930
|
||||
4_082_367_875_863_433_681_332_203_403_145_435_568_316_851_327_593_401_208_105_741_076_214_120_093_531,
|
||||
8_495_653_923_123_431_417_604_973_247_489_272_438_418_190_587_263_600_148_770_280_649_306_958_101_930
|
||||
]
|
||||
);
|
||||
vk.delta2 = Pairing.G2Point(
|
||||
[
|
||||
12423666958566268737444308034237892912702648013927558883280319245968679130649,
|
||||
15986964528637281931410749976607406939789163617014270799373312764775965360012
|
||||
12_423_666_958_566_268_737_444_308_034_237_892_912_702_648_013_927_558_883_280_319_245_968_679_130_649,
|
||||
15_986_964_528_637_281_931_410_749_976_607_406_939_789_163_617_014_270_799_373_312_764_775_965_360_012
|
||||
],
|
||||
[
|
||||
8394023076056524902583796202128496802110914536948580183128578071394816660799,
|
||||
4964607673011101982600772762445991192038811950832626693345350322823626470007
|
||||
8_394_023_076_056_524_902_583_796_202_128_496_802_110_914_536_948_580_183_128_578_071_394_816_660_799,
|
||||
4_964_607_673_011_101_982_600_772_762_445_991_192_038_811_950_832_626_693_345_350_322_823_626_470_007
|
||||
]
|
||||
);
|
||||
vk.IC = new Pairing.G1Point[](3);
|
||||
|
||||
vk.IC[0] = Pairing.G1Point(
|
||||
1655549413518972190198478012616802994254462093161203201613599472264958303841,
|
||||
21742734017792296281216385119397138748114275727065024271646515586404591497876
|
||||
1_655_549_413_518_972_190_198_478_012_616_802_994_254_462_093_161_203_201_613_599_472_264_958_303_841,
|
||||
21_742_734_017_792_296_281_216_385_119_397_138_748_114_275_727_065_024_271_646_515_586_404_591_497_876
|
||||
);
|
||||
|
||||
vk.IC[1] = Pairing.G1Point(
|
||||
16497930821522159474595176304955625435616718625609462506360632944366974274906,
|
||||
10404924572941018678793755094259635830045501866471999610240845041996101882275
|
||||
16_497_930_821_522_159_474_595_176_304_955_625_435_616_718_625_609_462_506_360_632_944_366_974_274_906,
|
||||
10_404_924_572_941_018_678_793_755_094_259_635_830_045_501_866_471_999_610_240_845_041_996_101_882_275
|
||||
);
|
||||
|
||||
vk.IC[2] = Pairing.G1Point(
|
||||
9567910551099174794221497568036631681620409346997815381833929247558241020796,
|
||||
17282591858786007768931802126325866705896012606427630592145070155065868649172
|
||||
9_567_910_551_099_174_794_221_497_568_036_631_681_620_409_346_997_815_381_833_929_247_558_241_020_796,
|
||||
17_282_591_858_786_007_768_931_802_126_325_866_705_896_012_606_427_630_592_145_070_155_065_868_649_172
|
||||
);
|
||||
}
|
||||
|
||||
function verify(uint256[] memory input, Proof memory proof) internal view returns (uint256) {
|
||||
uint256 snark_scalar_field = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
|
||||
uint256 snark_scalar_field =
|
||||
21_888_242_871_839_275_222_246_405_745_257_275_088_548_364_400_416_034_343_698_204_186_575_808_495_617;
|
||||
VerifyingKey memory vk = verifyingKey();
|
||||
require(input.length + 1 == vk.IC.length, "verifier-bad-input");
|
||||
// Compute the linear combination vk_x
|
||||
|
@ -281,7 +303,12 @@ contract Verifier {
|
|||
}
|
||||
/// @return r bool true if proof is valid
|
||||
|
||||
function verifyProof(uint256[2] memory a, uint256[2][2] memory b, uint256[2] memory c, uint256[2] memory input)
|
||||
function verifyProof(
|
||||
uint256[2] memory a,
|
||||
uint256[2][2] memory b,
|
||||
uint256[2] memory c,
|
||||
uint256[2] memory input
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (bool r)
|
||||
|
@ -290,7 +317,7 @@ contract Verifier {
|
|||
proof.A = Pairing.G1Point(a[0], a[1]);
|
||||
proof.B = Pairing.G2Point([b[0][0], b[0][1]], [b[1][0], b[1][1]]);
|
||||
proof.C = Pairing.G1Point(c[0], c[1]);
|
||||
uint256[] memory inputValues = new uint[](input.length);
|
||||
uint256[] memory inputValues = new uint256[](input.length);
|
||||
for (uint256 i = 0; i < input.length; i++) {
|
||||
inputValues[i] = input[i];
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
// SPDX-License-Identifier: Unlicense
|
||||
pragma solidity ^0.8.15;
|
||||
|
||||
import "poseidon-solidity/PoseidonT3.sol";
|
||||
import "forge-std/Test.sol";
|
||||
|
||||
contract PoseidonHasherTest is Test {
|
||||
/// @dev Setup the testing environment.
|
||||
function setUp() public {}
|
||||
|
||||
/// @dev Ensure that you can hash a value.
|
||||
function testHasher() public {
|
||||
assertEq(
|
||||
PoseidonT3.hash([19014214495641488759237505126948346942972912379615652741039992445865937985820, 0]),
|
||||
13164376930590487041313497514223288845711140604177161029957349518915056324115
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
// SPDX-License-Identifier: Unlicense
|
||||
pragma solidity ^0.8.15;
|
||||
|
||||
import "../contracts/RlnBase.sol";
|
||||
import "./Verifier.sol";
|
||||
import "forge-std/Test.sol";
|
||||
import "forge-std/StdCheats.sol";
|
||||
import "forge-std/console.sol";
|
||||
|
||||
contract RlnApp is RlnBase {
|
||||
uint256 public constant allowedIdCommitment =
|
||||
19014214495641488759237505126948346942972912379615652741039992445865937985820;
|
||||
|
||||
uint256 private membershipDeposit = 1000000000000000;
|
||||
uint256 private depth = 20;
|
||||
|
||||
constructor(address _verifier) RlnBase(membershipDeposit, depth, _verifier) {}
|
||||
|
||||
function _validateRegistration(uint256 idCommitment) internal pure override {
|
||||
if (idCommitment != allowedIdCommitment) revert FailedValidation();
|
||||
}
|
||||
|
||||
function _validateSlash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof)
|
||||
internal
|
||||
pure
|
||||
override
|
||||
{
|
||||
if (idCommitment == allowedIdCommitment) revert FailedValidation();
|
||||
}
|
||||
}
|
||||
|
||||
contract RLNAppTest is Test {
|
||||
RlnApp public rlnApp;
|
||||
TrueVerifier public trueVerifier;
|
||||
|
||||
uint256 public constant MEMBERSHIP_DEPOSIT = 1000000000000000;
|
||||
uint256 public constant DEPTH = 20;
|
||||
uint256 public constant SET_SIZE = 1048576;
|
||||
uint256[8] public zeroedProof = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||
|
||||
function setUp() public {
|
||||
trueVerifier = new TrueVerifier();
|
||||
rlnApp = new RlnApp(address(trueVerifier));
|
||||
}
|
||||
|
||||
function test__Constants() public {
|
||||
// sanity checking
|
||||
assertEq(rlnApp.MEMBERSHIP_DEPOSIT(), MEMBERSHIP_DEPOSIT);
|
||||
assertEq(rlnApp.DEPTH(), DEPTH);
|
||||
assertEq(rlnApp.SET_SIZE(), SET_SIZE);
|
||||
}
|
||||
|
||||
function test__InvalidRegistration(uint256 idCommitment) public {
|
||||
vm.assume(idCommitment != rlnApp.allowedIdCommitment());
|
||||
vm.assume(rlnApp.isValidCommitment(idCommitment));
|
||||
vm.expectRevert(FailedValidation.selector);
|
||||
rlnApp.register{value: MEMBERSHIP_DEPOSIT}(idCommitment);
|
||||
}
|
||||
|
||||
function test__ValidRegistration() public {
|
||||
rlnApp.register{value: MEMBERSHIP_DEPOSIT}(rlnApp.allowedIdCommitment());
|
||||
}
|
||||
|
||||
function test__InvalidSlash() public {
|
||||
uint256 allowedIdCommitment = rlnApp.allowedIdCommitment();
|
||||
rlnApp.register{value: MEMBERSHIP_DEPOSIT}(allowedIdCommitment);
|
||||
vm.expectRevert(FailedValidation.selector);
|
||||
rlnApp.slash(allowedIdCommitment, payable(address(this)), zeroedProof);
|
||||
}
|
||||
}
|
159
test/Rln.t.sol
159
test/Rln.t.sol
|
@ -1,31 +1,34 @@
|
|||
// SPDX-License-Identifier: Unlicense
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity ^0.8.15;
|
||||
|
||||
import "../contracts/Rln.sol";
|
||||
import "./Verifier.sol";
|
||||
import "forge-std/Test.sol";
|
||||
import { Test, console } from "forge-std/Test.sol";
|
||||
import "forge-std/StdCheats.sol";
|
||||
import "forge-std/console.sol";
|
||||
|
||||
import { TrueVerifier, FalseVerifier } from "./mocks/VerifierMock.sol";
|
||||
|
||||
import { Deploy } from "../script/Deploy.s.sol";
|
||||
import { DeploymentConfig } from "../script/DeploymentConfig.s.sol";
|
||||
import "../src/Rln.sol";
|
||||
|
||||
contract RlnTest is Test {
|
||||
using stdStorage for StdStorage;
|
||||
|
||||
RLN public rln;
|
||||
TrueVerifier public trueVerifier;
|
||||
FalseVerifier public falseVerifier;
|
||||
Rln internal rln;
|
||||
TrueVerifier internal trueVerifier;
|
||||
FalseVerifier internal falseVerifier;
|
||||
|
||||
uint256 public constant MEMBERSHIP_DEPOSIT = 1000000000000000;
|
||||
uint256 public constant DEPTH = 20;
|
||||
uint256 public constant SET_SIZE = 1048576;
|
||||
uint256[8] public zeroedProof = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||
|
||||
/// @dev Setup the testing environment.
|
||||
function setUp() public {
|
||||
function setUp() public virtual {
|
||||
trueVerifier = new TrueVerifier();
|
||||
falseVerifier = new FalseVerifier();
|
||||
rln = new RLN(MEMBERSHIP_DEPOSIT, DEPTH, address(trueVerifier));
|
||||
|
||||
rln = new Rln(MEMBERSHIP_DEPOSIT, DEPTH, address(trueVerifier));
|
||||
}
|
||||
|
||||
uint256 public constant MEMBERSHIP_DEPOSIT = 1_000_000_000_000_000;
|
||||
uint256 public constant DEPTH = 20;
|
||||
uint256 public constant SET_SIZE = 1_048_576;
|
||||
uint256[8] public zeroedProof = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||
|
||||
/// @dev Ensure that you can hash a value.
|
||||
function test__Constants() public {
|
||||
assertEq(rln.MEMBERSHIP_DEPOSIT(), MEMBERSHIP_DEPOSIT);
|
||||
|
@ -36,7 +39,7 @@ contract RlnTest is Test {
|
|||
|
||||
function test__ValidRegistration(uint256 idCommitment) public {
|
||||
vm.assume(rln.isValidCommitment(idCommitment));
|
||||
rln.register{value: MEMBERSHIP_DEPOSIT}(idCommitment);
|
||||
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
||||
assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT);
|
||||
assertEq(rln.memberExists(idCommitment), true);
|
||||
assertEq(rln.members(idCommitment), 0);
|
||||
|
@ -44,40 +47,36 @@ contract RlnTest is Test {
|
|||
|
||||
function test__InvalidRegistration__DuplicateCommitment(uint256 idCommitment) public {
|
||||
vm.assume(rln.isValidCommitment(idCommitment));
|
||||
rln.register{value: MEMBERSHIP_DEPOSIT}(idCommitment);
|
||||
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
||||
assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT);
|
||||
assertEq(rln.memberExists(idCommitment), true);
|
||||
assertEq(rln.members(idCommitment), 0);
|
||||
vm.expectRevert(DuplicateIdCommitment.selector);
|
||||
rln.register{value: MEMBERSHIP_DEPOSIT}(idCommitment);
|
||||
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
||||
}
|
||||
|
||||
function test__InvalidRegistration__InvalidIdCommitment(uint256 idCommitment) public {
|
||||
vm.assume(!rln.isValidCommitment(idCommitment));
|
||||
vm.expectRevert(abi.encodeWithSelector(InvalidIdCommitment.selector, idCommitment));
|
||||
rln.register{value: MEMBERSHIP_DEPOSIT}(idCommitment);
|
||||
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
||||
}
|
||||
|
||||
function test__InvalidRegistration__InsufficientDeposit(uint256 idCommitment) public {
|
||||
vm.assume(rln.isValidCommitment(idCommitment));
|
||||
uint256 badDepositAmount = MEMBERSHIP_DEPOSIT - 1;
|
||||
vm.expectRevert(abi.encodeWithSelector(InsufficientDeposit.selector, MEMBERSHIP_DEPOSIT, badDepositAmount));
|
||||
rln.register{value: badDepositAmount}(idCommitment);
|
||||
rln.register{ value: badDepositAmount }(idCommitment);
|
||||
}
|
||||
|
||||
function test__InvalidRegistration__FullSet() public {
|
||||
RLN tempRln = new RLN(
|
||||
MEMBERSHIP_DEPOSIT,
|
||||
2,
|
||||
address(rln.verifier())
|
||||
);
|
||||
Rln tempRln = new Rln(MEMBERSHIP_DEPOSIT, 2, address(rln.verifier()));
|
||||
uint256 setSize = tempRln.SET_SIZE();
|
||||
for (uint256 i = 1; i <= setSize; i++) {
|
||||
tempRln.register{value: MEMBERSHIP_DEPOSIT}(i);
|
||||
tempRln.register{ value: MEMBERSHIP_DEPOSIT }(i);
|
||||
}
|
||||
assertEq(tempRln.idCommitmentIndex(), 4);
|
||||
vm.expectRevert(FullTree.selector);
|
||||
tempRln.register{value: MEMBERSHIP_DEPOSIT}(setSize + 1);
|
||||
tempRln.register{ value: MEMBERSHIP_DEPOSIT }(setSize + 1);
|
||||
}
|
||||
|
||||
function test__ValidSlash(uint256 idCommitment, address payable to) public {
|
||||
|
@ -88,7 +87,7 @@ contract RlnTest is Test {
|
|||
vm.assume(to != address(0));
|
||||
vm.assume(rln.isValidCommitment(idCommitment));
|
||||
|
||||
rln.register{value: MEMBERSHIP_DEPOSIT}(idCommitment);
|
||||
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
||||
assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT);
|
||||
|
||||
uint256 balanceBefore = to.balance;
|
||||
|
@ -103,17 +102,19 @@ contract RlnTest is Test {
|
|||
}
|
||||
|
||||
function test__InvalidSlash__ToZeroAddress() public {
|
||||
uint256 idCommitment = 9014214495641488759237505126948346942972912379615652741039992445865937985820;
|
||||
uint256 idCommitment =
|
||||
9_014_214_495_641_488_759_237_505_126_948_346_942_972_912_379_615_652_741_039_992_445_865_937_985_820;
|
||||
|
||||
rln.register{value: MEMBERSHIP_DEPOSIT}(idCommitment);
|
||||
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
||||
assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT);
|
||||
vm.expectRevert(abi.encodeWithSelector(InvalidReceiverAddress.selector, address(0)));
|
||||
rln.slash(idCommitment, payable(address(0)), zeroedProof);
|
||||
}
|
||||
|
||||
function test__InvalidSlash__ToRlnAddress() public {
|
||||
uint256 idCommitment = 19014214495641488759237505126948346942972912379615652741039992445865937985820;
|
||||
rln.register{value: MEMBERSHIP_DEPOSIT}(idCommitment);
|
||||
uint256 idCommitment =
|
||||
19_014_214_495_641_488_759_237_505_126_948_346_942_972_912_379_615_652_741_039_992_445_865_937_985_820;
|
||||
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
||||
assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT);
|
||||
vm.expectRevert(abi.encodeWithSelector(InvalidReceiverAddress.selector, address(rln)));
|
||||
rln.slash(idCommitment, payable(address(rln)), zeroedProof);
|
||||
|
@ -133,7 +134,7 @@ contract RlnTest is Test {
|
|||
vm.assume(to != address(0));
|
||||
vm.assume(rln.isValidCommitment(idCommitment));
|
||||
|
||||
rln.register{value: MEMBERSHIP_DEPOSIT}(idCommitment);
|
||||
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
||||
assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT);
|
||||
|
||||
rln.slash(idCommitment, to, zeroedProof);
|
||||
|
@ -148,15 +149,12 @@ contract RlnTest is Test {
|
|||
}
|
||||
|
||||
function test__InvalidSlash__InvalidProof() public {
|
||||
uint256 idCommitment = 19014214495641488759237505126948346942972912379615652741039992445865937985820;
|
||||
uint256 idCommitment =
|
||||
19_014_214_495_641_488_759_237_505_126_948_346_942_972_912_379_615_652_741_039_992_445_865_937_985_820;
|
||||
|
||||
RLN tempRln = new RLN(
|
||||
MEMBERSHIP_DEPOSIT,
|
||||
2,
|
||||
address(falseVerifier)
|
||||
);
|
||||
Rln tempRln = new Rln(MEMBERSHIP_DEPOSIT, 2, address(falseVerifier));
|
||||
|
||||
tempRln.register{value: MEMBERSHIP_DEPOSIT}(idCommitment);
|
||||
tempRln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
||||
|
||||
vm.expectRevert(InvalidProof.selector);
|
||||
tempRln.slash(idCommitment, payable(address(this)), zeroedProof);
|
||||
|
@ -168,8 +166,9 @@ contract RlnTest is Test {
|
|||
}
|
||||
|
||||
function test__InvalidWithdraw__InsufficientContractBalance() public {
|
||||
uint256 idCommitment = 19014214495641488759237505126948346942972912379615652741039992445865937985820;
|
||||
rln.register{value: MEMBERSHIP_DEPOSIT}(idCommitment);
|
||||
uint256 idCommitment =
|
||||
19_014_214_495_641_488_759_237_505_126_948_346_942_972_912_379_615_652_741_039_992_445_865_937_985_820;
|
||||
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
||||
assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT);
|
||||
rln.slash(idCommitment, payable(address(this)), zeroedProof);
|
||||
assertEq(rln.stakedAmounts(idCommitment), 0);
|
||||
|
@ -185,9 +184,10 @@ contract RlnTest is Test {
|
|||
assumeNotPrecompile(to);
|
||||
vm.assume(to != address(0));
|
||||
|
||||
uint256 idCommitment = 19014214495641488759237505126948346942972912379615652741039992445865937985820;
|
||||
uint256 idCommitment =
|
||||
19_014_214_495_641_488_759_237_505_126_948_346_942_972_912_379_615_652_741_039_992_445_865_937_985_820;
|
||||
|
||||
rln.register{value: MEMBERSHIP_DEPOSIT}(idCommitment);
|
||||
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
||||
assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT);
|
||||
rln.slash(idCommitment, to, zeroedProof);
|
||||
assertEq(rln.stakedAmounts(idCommitment), 0);
|
||||
|
@ -201,42 +201,65 @@ contract RlnTest is Test {
|
|||
|
||||
function test__root() public {
|
||||
uint256[] memory idCommitments = new uint256[](10);
|
||||
idCommitments[0] = 19143711682366759980911001457853255795836264632723844153354310748778748156460;
|
||||
idCommitments[1] = 16984765328852711772291441487727981184905800779020079168989152080434188364678;
|
||||
idCommitments[2] = 10972315136095845343447418815139813428649316683283020632475608655814722712541;
|
||||
idCommitments[3] = 2709631781045191277266130708832884002577134582503944059038971337978087532997;
|
||||
idCommitments[4] = 8255654132980945447086418574686169461187805238257784695584517016324877809505;
|
||||
idCommitments[5] = 20291701150251695209910387548168084091751201746043024067531503187703236470983;
|
||||
idCommitments[6] = 11817872986033932471261438074921403500882957864164537515599299873089437746577;
|
||||
idCommitments[7] = 18475838919635792169148272767721284591038756730004222133003018558598315558783;
|
||||
idCommitments[8] = 10612118277928165031660389522171737855229037400929675201853245490188277695983;
|
||||
idCommitments[9] = 17318633845296358766427229711888486415250435256643711009388405482885762601797;
|
||||
idCommitments[0] =
|
||||
19_143_711_682_366_759_980_911_001_457_853_255_795_836_264_632_723_844_153_354_310_748_778_748_156_460;
|
||||
idCommitments[1] =
|
||||
16_984_765_328_852_711_772_291_441_487_727_981_184_905_800_779_020_079_168_989_152_080_434_188_364_678;
|
||||
idCommitments[2] =
|
||||
10_972_315_136_095_845_343_447_418_815_139_813_428_649_316_683_283_020_632_475_608_655_814_722_712_541;
|
||||
idCommitments[3] =
|
||||
2_709_631_781_045_191_277_266_130_708_832_884_002_577_134_582_503_944_059_038_971_337_978_087_532_997;
|
||||
idCommitments[4] =
|
||||
8_255_654_132_980_945_447_086_418_574_686_169_461_187_805_238_257_784_695_584_517_016_324_877_809_505;
|
||||
idCommitments[5] =
|
||||
20_291_701_150_251_695_209_910_387_548_168_084_091_751_201_746_043_024_067_531_503_187_703_236_470_983;
|
||||
idCommitments[6] =
|
||||
11_817_872_986_033_932_471_261_438_074_921_403_500_882_957_864_164_537_515_599_299_873_089_437_746_577;
|
||||
idCommitments[7] =
|
||||
18_475_838_919_635_792_169_148_272_767_721_284_591_038_756_730_004_222_133_003_018_558_598_315_558_783;
|
||||
idCommitments[8] =
|
||||
10_612_118_277_928_165_031_660_389_522_171_737_855_229_037_400_929_675_201_853_245_490_188_277_695_983;
|
||||
idCommitments[9] =
|
||||
17_318_633_845_296_358_766_427_229_711_888_486_415_250_435_256_643_711_009_388_405_482_885_762_601_797;
|
||||
|
||||
vm.pauseGasMetering();
|
||||
for (uint256 i = 0; i < idCommitments.length; i++) {
|
||||
rln.register{value: MEMBERSHIP_DEPOSIT}(idCommitments[i]);
|
||||
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitments[i]);
|
||||
}
|
||||
vm.resumeGasMetering();
|
||||
|
||||
assertEq(rln.root(), 5210724218081541877101688952118136930297124697603087561558225712176057209122);
|
||||
assertEq(
|
||||
rln.root(),
|
||||
5_210_724_218_081_541_877_101_688_952_118_136_930_297_124_697_603_087_561_558_225_712_176_057_209_122
|
||||
);
|
||||
}
|
||||
|
||||
function test__paginationCommitments() public {
|
||||
uint256[] memory idCommitments = new uint256[](10);
|
||||
idCommitments[0] = 19143711682366759980911001457853255795836264632723844153354310748778748156460;
|
||||
idCommitments[1] = 16984765328852711772291441487727981184905800779020079168989152080434188364678;
|
||||
idCommitments[2] = 10972315136095845343447418815139813428649316683283020632475608655814722712541;
|
||||
idCommitments[3] = 2709631781045191277266130708832884002577134582503944059038971337978087532997;
|
||||
idCommitments[4] = 8255654132980945447086418574686169461187805238257784695584517016324877809505;
|
||||
idCommitments[5] = 20291701150251695209910387548168084091751201746043024067531503187703236470983;
|
||||
idCommitments[6] = 11817872986033932471261438074921403500882957864164537515599299873089437746577;
|
||||
idCommitments[7] = 18475838919635792169148272767721284591038756730004222133003018558598315558783;
|
||||
idCommitments[8] = 10612118277928165031660389522171737855229037400929675201853245490188277695983;
|
||||
idCommitments[9] = 17318633845296358766427229711888486415250435256643711009388405482885762601797;
|
||||
idCommitments[0] =
|
||||
19_143_711_682_366_759_980_911_001_457_853_255_795_836_264_632_723_844_153_354_310_748_778_748_156_460;
|
||||
idCommitments[1] =
|
||||
16_984_765_328_852_711_772_291_441_487_727_981_184_905_800_779_020_079_168_989_152_080_434_188_364_678;
|
||||
idCommitments[2] =
|
||||
10_972_315_136_095_845_343_447_418_815_139_813_428_649_316_683_283_020_632_475_608_655_814_722_712_541;
|
||||
idCommitments[3] =
|
||||
2_709_631_781_045_191_277_266_130_708_832_884_002_577_134_582_503_944_059_038_971_337_978_087_532_997;
|
||||
idCommitments[4] =
|
||||
8_255_654_132_980_945_447_086_418_574_686_169_461_187_805_238_257_784_695_584_517_016_324_877_809_505;
|
||||
idCommitments[5] =
|
||||
20_291_701_150_251_695_209_910_387_548_168_084_091_751_201_746_043_024_067_531_503_187_703_236_470_983;
|
||||
idCommitments[6] =
|
||||
11_817_872_986_033_932_471_261_438_074_921_403_500_882_957_864_164_537_515_599_299_873_089_437_746_577;
|
||||
idCommitments[7] =
|
||||
18_475_838_919_635_792_169_148_272_767_721_284_591_038_756_730_004_222_133_003_018_558_598_315_558_783;
|
||||
idCommitments[8] =
|
||||
10_612_118_277_928_165_031_660_389_522_171_737_855_229_037_400_929_675_201_853_245_490_188_277_695_983;
|
||||
idCommitments[9] =
|
||||
17_318_633_845_296_358_766_427_229_711_888_486_415_250_435_256_643_711_009_388_405_482_885_762_601_797;
|
||||
|
||||
vm.pauseGasMetering();
|
||||
for (uint256 i = 0; i < idCommitments.length; i++) {
|
||||
rln.register{value: MEMBERSHIP_DEPOSIT}(idCommitments[i]);
|
||||
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitments[i]);
|
||||
}
|
||||
vm.resumeGasMetering();
|
||||
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
// SPDX-License-Identifier: Unlicense
|
||||
pragma solidity ^0.8.15;
|
||||
|
||||
import {IVerifier} from "../contracts/IVerifier.sol";
|
||||
|
||||
contract TrueVerifier is IVerifier {
|
||||
function verifyProof(uint256[2] memory a, uint256[2][2] memory b, uint256[2] memory c, uint256[2] memory input)
|
||||
external
|
||||
pure
|
||||
returns (bool)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
contract FalseVerifier is IVerifier {
|
||||
function verifyProof(uint256[2] memory a, uint256[2][2] memory b, uint256[2] memory c, uint256[2] memory input)
|
||||
external
|
||||
pure
|
||||
returns (bool)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
// SPDX-License-Identifier: Unlicense
|
||||
pragma solidity ^0.8.15;
|
||||
|
||||
import { IVerifier } from "../../src/IVerifier.sol";
|
||||
|
||||
contract TrueVerifier is IVerifier {
|
||||
function verifyProof(
|
||||
uint256[2] memory a,
|
||||
uint256[2][2] memory b,
|
||||
uint256[2] memory c,
|
||||
uint256[2] memory input
|
||||
)
|
||||
external
|
||||
pure
|
||||
returns (bool)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
contract FalseVerifier is IVerifier {
|
||||
function verifyProof(
|
||||
uint256[2] memory a,
|
||||
uint256[2][2] memory b,
|
||||
uint256[2] memory c,
|
||||
uint256[2] memory input
|
||||
)
|
||||
external
|
||||
pure
|
||||
returns (bool)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
import { expect } from "chai";
|
||||
import { ethers, deployments } from "hardhat";
|
||||
|
||||
describe("PoseidonT3", () => {
|
||||
beforeEach(async () => {
|
||||
await deployments.fixture(["PoseidonT3"]);
|
||||
});
|
||||
|
||||
it("should hash correctly", async function () {
|
||||
const poseidonHasher = await ethers.getContract("PoseidonT3");
|
||||
|
||||
// We test hashing for a random number
|
||||
const hash = await poseidonHasher.hash([
|
||||
"19014214495641488759237505126948346942972912379615652741039992445865937985820",
|
||||
"0",
|
||||
]);
|
||||
|
||||
expect(hash.toHexString()).to.eql(
|
||||
"0x1d1ac5f6cf23b059eb43c657ce622b614b5960ea4b23f92d428d3e42982a4e13"
|
||||
);
|
||||
});
|
||||
});
|
|
@ -1,78 +0,0 @@
|
|||
import { expect } from "chai";
|
||||
import { ethers, deployments } from "hardhat";
|
||||
|
||||
describe("Rln", () => {
|
||||
beforeEach(async () => {
|
||||
await deployments.fixture(["RLN"]);
|
||||
});
|
||||
|
||||
it("should register new memberships", async () => {
|
||||
const rln = await ethers.getContract("RLN", ethers.provider.getSigner(0));
|
||||
|
||||
const price = await rln.MEMBERSHIP_DEPOSIT();
|
||||
|
||||
// A valid pair of (id_secret, id_commitment) generated in rust
|
||||
const idCommitment =
|
||||
"0x0c3ac305f6a4fe9bfeb3eba978bc876e2a99208b8b56c80160cfb54ba8f02368";
|
||||
|
||||
const registerTx = await rln["register(uint256)"](idCommitment, {
|
||||
value: price,
|
||||
});
|
||||
const txRegisterReceipt = await registerTx.wait();
|
||||
|
||||
const pubkey = txRegisterReceipt.events[0].args.idCommitment;
|
||||
|
||||
// We ensure the registered id_commitment is the one we passed
|
||||
expect(
|
||||
pubkey.toHexString() === idCommitment,
|
||||
"registered commitment doesn't match passed commitment"
|
||||
);
|
||||
});
|
||||
|
||||
it("should slash membership", async () => {
|
||||
const rln = await ethers.getContract("RLN", ethers.provider.getSigner(0));
|
||||
|
||||
const price = await rln.MEMBERSHIP_DEPOSIT();
|
||||
|
||||
// A valid id_commitment generated in zerokit
|
||||
const idCommitment =
|
||||
"0x0c3ac305f6a4fe9bfeb3eba978bc876e2a99208b8b56c80160cfb54ba8f02368";
|
||||
|
||||
const registerTx = await rln["register(uint256)"](idCommitment, {
|
||||
value: price,
|
||||
});
|
||||
await registerTx.wait();
|
||||
|
||||
// We slash the id_commitment
|
||||
const receiverAddress = "0x000000000000000000000000000000000000dead";
|
||||
const slashTx = rln["slash(uint256,address,uint256[8])"](
|
||||
idCommitment,
|
||||
receiverAddress,
|
||||
[0, 0, 0, 0, 0, 0, 0, 0]
|
||||
);
|
||||
|
||||
await expect(slashTx).to.be.revertedWith("InvalidProof()");
|
||||
});
|
||||
|
||||
it("should not allow multiple registrations with same pubkey", async () => {
|
||||
const rln = await ethers.getContract("RLN", ethers.provider.getSigner(0));
|
||||
|
||||
const price = await rln.MEMBERSHIP_DEPOSIT();
|
||||
|
||||
// A valid pair of (id_secret, id_commitment) generated in rust
|
||||
const idCommitment =
|
||||
"0x0c3ac305f6a4fe9bfeb3eba978bc876e2a99208b8b56c80160cfb54ba8f02368";
|
||||
|
||||
const registerTx = await rln["register(uint256)"](idCommitment, {
|
||||
value: price,
|
||||
});
|
||||
await registerTx.wait();
|
||||
|
||||
// Send the same tx again
|
||||
const registerTx2 = rln["register(uint256)"](idCommitment, {
|
||||
value: price,
|
||||
});
|
||||
|
||||
await expect(registerTx2).to.be.revertedWith("DuplicateIdCommitment()");
|
||||
});
|
||||
});
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2018",
|
||||
"module": "commonjs",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"outDir": "dist",
|
||||
"declaration": true
|
||||
},
|
||||
"include": [
|
||||
"./scripts",
|
||||
"./test",
|
||||
"./typechain",
|
||||
"deploy"
|
||||
],
|
||||
"files": [
|
||||
"./hardhat.config.ts"
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue