diff --git a/.husky/pre-commit b/.husky/pre-commit index 0312b76..d6ba6c3 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,5 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" +yarn docgen && git add docs npx lint-staged \ No newline at end of file diff --git a/contracts/PoseidonHasher.sol b/contracts/PoseidonHasher.sol index 2a7907c..50348c1 100644 --- a/contracts/PoseidonHasher.sol +++ b/contracts/PoseidonHasher.sol @@ -5,6 +5,8 @@ pragma solidity 0.8.15; interface IPoseidonHasher { + /// @notice Hashes the input using the Poseidon hash function, n = 2, second input is the constant 0 + /// @param input The input to hash function hash(uint256 input) external pure returns (uint256 result); } diff --git a/contracts/Rln.sol b/contracts/Rln.sol index 22157e4..2c1ab80 100644 --- a/contracts/Rln.sol +++ b/contracts/Rln.sol @@ -5,17 +5,34 @@ pragma solidity 0.8.15; import {IPoseidonHasher} from "./PoseidonHasher.sol"; contract RLN { + /// @notice The deposit amount required to register as a member uint256 public immutable MEMBERSHIP_DEPOSIT; + + /// @notice The depth of the merkle tree uint256 public immutable DEPTH; + + /// @notice The size of the merkle tree, i.e 2^depth uint256 public immutable SET_SIZE; + /// @notice The index of the next member to be registered uint256 public idCommitmentIndex; + + /// @notice The amount of eth staked by each member mapping(uint256 => uint256) public stakedAmounts; + + /// @notice The membership status of each member mapping(uint256 => bool) public members; + /// @notice The Poseidon hasher contract IPoseidonHasher public poseidonHasher; + /// Emitted when a new member is added to the set + /// @param idCommitment The idCommitment of the member + /// @param index The index of the member in the set event MemberRegistered(uint256 idCommitment, uint256 index); + + /// Emitted when a member is removed from the set + /// @param idCommitment The idCommitment of the member event MemberWithdrawn(uint256 idCommitment); constructor( @@ -29,6 +46,8 @@ contract RLN { poseidonHasher = IPoseidonHasher(_poseidonHasher); } + /// Allows a user to register as a member + /// @param idCommitment The idCommitment of the member function register(uint256 idCommitment) external payable { require( msg.value == MEMBERSHIP_DEPOSIT, @@ -37,6 +56,8 @@ contract RLN { _register(idCommitment, msg.value); } + /// Allows batch registration of members + /// @param idCommitments array of idCommitments function registerBatch(uint256[] calldata idCommitments) external payable { uint256 idCommitmentlen = idCommitments.length; require(idCommitmentlen > 0, "RLN, registerBatch: batch size zero"); @@ -53,6 +74,9 @@ contract RLN { } } + /// Registers a member + /// @param idCommitment The idCommitment of the member + /// @param stake The amount of eth staked by the member function _register(uint256 idCommitment, uint256 stake) internal { require( !members[idCommitment], @@ -67,6 +91,9 @@ contract RLN { idCommitmentIndex += 1; } + /// Allows a user to slash a batch of members + /// @param secrets array of idSecretHashes + /// @param receivers array of addresses to receive the funds function withdrawBatch( uint256[] calldata secrets, address payable[] calldata receivers @@ -82,10 +109,16 @@ contract RLN { } } + /// Allows a user to slash a member + /// @param secret The idSecretHash of the member function withdraw(uint256 secret, address payable receiver) external { _withdraw(secret, receiver); } + /// Slashes a member by removing them from the set, and transferring their + /// stake to the receiver + /// @param secret The idSecretHash of the member + /// @param receiver The address to receive the funds function _withdraw(uint256 secret, address payable receiver) internal { require( receiver != address(0), @@ -120,6 +153,9 @@ contract RLN { emit MemberWithdrawn(idCommitment); } + /// Hashes a value using the Poseidon hasher + /// NOTE: The variant of Poseidon we use accepts only 1 input, assume n=2, and the second input is 0 + /// @param input The value to hash function hash(uint256 input) internal view returns (uint256) { return poseidonHasher.hash(input); } diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..c1c6ae8 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,1034 @@ +# Solidity API + +## IPoseidonHasher + +### hash + +```solidity +function hash(uint256 input) external pure returns (uint256 result) +``` + +Hashes the input using the Poseidon hash function, n = 2, second input is the constant 0 + +#### Parameters + +| Name | Type | Description | +| ----- | ------- | ----------------- | +| input | uint256 | The input to hash | + +## PoseidonHasher + +### Q + +```solidity +uint256 Q +``` + +### C0 + +```solidity +uint256 C0 +``` + +### C1 + +```solidity +uint256 C1 +``` + +### C2 + +```solidity +uint256 C2 +``` + +### C3 + +```solidity +uint256 C3 +``` + +### C4 + +```solidity +uint256 C4 +``` + +### C5 + +```solidity +uint256 C5 +``` + +### C6 + +```solidity +uint256 C6 +``` + +### C7 + +```solidity +uint256 C7 +``` + +### C8 + +```solidity +uint256 C8 +``` + +### C9 + +```solidity +uint256 C9 +``` + +### C10 + +```solidity +uint256 C10 +``` + +### C11 + +```solidity +uint256 C11 +``` + +### C12 + +```solidity +uint256 C12 +``` + +### C13 + +```solidity +uint256 C13 +``` + +### C14 + +```solidity +uint256 C14 +``` + +### C15 + +```solidity +uint256 C15 +``` + +### C16 + +```solidity +uint256 C16 +``` + +### C17 + +```solidity +uint256 C17 +``` + +### C18 + +```solidity +uint256 C18 +``` + +### C19 + +```solidity +uint256 C19 +``` + +### C20 + +```solidity +uint256 C20 +``` + +### C21 + +```solidity +uint256 C21 +``` + +### C22 + +```solidity +uint256 C22 +``` + +### C23 + +```solidity +uint256 C23 +``` + +### C24 + +```solidity +uint256 C24 +``` + +### C25 + +```solidity +uint256 C25 +``` + +### C26 + +```solidity +uint256 C26 +``` + +### C27 + +```solidity +uint256 C27 +``` + +### C28 + +```solidity +uint256 C28 +``` + +### C29 + +```solidity +uint256 C29 +``` + +### C30 + +```solidity +uint256 C30 +``` + +### C31 + +```solidity +uint256 C31 +``` + +### C32 + +```solidity +uint256 C32 +``` + +### C33 + +```solidity +uint256 C33 +``` + +### C34 + +```solidity +uint256 C34 +``` + +### C35 + +```solidity +uint256 C35 +``` + +### C36 + +```solidity +uint256 C36 +``` + +### C37 + +```solidity +uint256 C37 +``` + +### C38 + +```solidity +uint256 C38 +``` + +### C39 + +```solidity +uint256 C39 +``` + +### C40 + +```solidity +uint256 C40 +``` + +### C41 + +```solidity +uint256 C41 +``` + +### C42 + +```solidity +uint256 C42 +``` + +### C43 + +```solidity +uint256 C43 +``` + +### C44 + +```solidity +uint256 C44 +``` + +### C45 + +```solidity +uint256 C45 +``` + +### C46 + +```solidity +uint256 C46 +``` + +### C47 + +```solidity +uint256 C47 +``` + +### C48 + +```solidity +uint256 C48 +``` + +### C49 + +```solidity +uint256 C49 +``` + +### C50 + +```solidity +uint256 C50 +``` + +### C51 + +```solidity +uint256 C51 +``` + +### C52 + +```solidity +uint256 C52 +``` + +### C53 + +```solidity +uint256 C53 +``` + +### C54 + +```solidity +uint256 C54 +``` + +### C55 + +```solidity +uint256 C55 +``` + +### C56 + +```solidity +uint256 C56 +``` + +### C57 + +```solidity +uint256 C57 +``` + +### C58 + +```solidity +uint256 C58 +``` + +### C59 + +```solidity +uint256 C59 +``` + +### C60 + +```solidity +uint256 C60 +``` + +### C61 + +```solidity +uint256 C61 +``` + +### C62 + +```solidity +uint256 C62 +``` + +### C63 + +```solidity +uint256 C63 +``` + +### C64 + +```solidity +uint256 C64 +``` + +### C65 + +```solidity +uint256 C65 +``` + +### C66 + +```solidity +uint256 C66 +``` + +### C67 + +```solidity +uint256 C67 +``` + +### C68 + +```solidity +uint256 C68 +``` + +### C69 + +```solidity +uint256 C69 +``` + +### C70 + +```solidity +uint256 C70 +``` + +### C71 + +```solidity +uint256 C71 +``` + +### C72 + +```solidity +uint256 C72 +``` + +### C73 + +```solidity +uint256 C73 +``` + +### C74 + +```solidity +uint256 C74 +``` + +### C75 + +```solidity +uint256 C75 +``` + +### C76 + +```solidity +uint256 C76 +``` + +### C77 + +```solidity +uint256 C77 +``` + +### C78 + +```solidity +uint256 C78 +``` + +### C79 + +```solidity +uint256 C79 +``` + +### C80 + +```solidity +uint256 C80 +``` + +### C81 + +```solidity +uint256 C81 +``` + +### C82 + +```solidity +uint256 C82 +``` + +### C83 + +```solidity +uint256 C83 +``` + +### C84 + +```solidity +uint256 C84 +``` + +### C85 + +```solidity +uint256 C85 +``` + +### C86 + +```solidity +uint256 C86 +``` + +### C87 + +```solidity +uint256 C87 +``` + +### C88 + +```solidity +uint256 C88 +``` + +### C89 + +```solidity +uint256 C89 +``` + +### C90 + +```solidity +uint256 C90 +``` + +### C91 + +```solidity +uint256 C91 +``` + +### C92 + +```solidity +uint256 C92 +``` + +### C93 + +```solidity +uint256 C93 +``` + +### C94 + +```solidity +uint256 C94 +``` + +### C95 + +```solidity +uint256 C95 +``` + +### C96 + +```solidity +uint256 C96 +``` + +### C97 + +```solidity +uint256 C97 +``` + +### C98 + +```solidity +uint256 C98 +``` + +### C99 + +```solidity +uint256 C99 +``` + +### C100 + +```solidity +uint256 C100 +``` + +### C101 + +```solidity +uint256 C101 +``` + +### C102 + +```solidity +uint256 C102 +``` + +### C103 + +```solidity +uint256 C103 +``` + +### C104 + +```solidity +uint256 C104 +``` + +### C105 + +```solidity +uint256 C105 +``` + +### C106 + +```solidity +uint256 C106 +``` + +### C107 + +```solidity +uint256 C107 +``` + +### C108 + +```solidity +uint256 C108 +``` + +### C109 + +```solidity +uint256 C109 +``` + +### C110 + +```solidity +uint256 C110 +``` + +### C111 + +```solidity +uint256 C111 +``` + +### C112 + +```solidity +uint256 C112 +``` + +### C113 + +```solidity +uint256 C113 +``` + +### C114 + +```solidity +uint256 C114 +``` + +### C115 + +```solidity +uint256 C115 +``` + +### C116 + +```solidity +uint256 C116 +``` + +### C117 + +```solidity +uint256 C117 +``` + +### C118 + +```solidity +uint256 C118 +``` + +### C119 + +```solidity +uint256 C119 +``` + +### C120 + +```solidity +uint256 C120 +``` + +### C121 + +```solidity +uint256 C121 +``` + +### C122 + +```solidity +uint256 C122 +``` + +### C123 + +```solidity +uint256 C123 +``` + +### C124 + +```solidity +uint256 C124 +``` + +### C125 + +```solidity +uint256 C125 +``` + +### C126 + +```solidity +uint256 C126 +``` + +### C127 + +```solidity +uint256 C127 +``` + +### M00 + +```solidity +uint256 M00 +``` + +### M01 + +```solidity +uint256 M01 +``` + +### M10 + +```solidity +uint256 M10 +``` + +### M11 + +```solidity +uint256 M11 +``` + +### hash + +```solidity +function hash(uint256 input) external pure returns (uint256 result) +``` + +Hashes the input using the Poseidon hash function, n = 2, second input is the constant 0 + +#### Parameters + +| Name | Type | Description | +| ----- | ------- | ----------------- | +| input | uint256 | The input to hash | + +### \_hash + +```solidity +function _hash(uint256 input) internal pure returns (uint256 result) +``` + +## RLN + +### 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 + +### members + +```solidity +mapping(uint256 => bool) members +``` + +The membership status of each member + +### poseidonHasher + +```solidity +contract IPoseidonHasher poseidonHasher +``` + +The Poseidon hasher contract + +### 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) +``` + +Emitted when a member is removed from the set + +#### Parameters + +| Name | Type | Description | +| ------------ | ------- | ------------------------------ | +| idCommitment | uint256 | The idCommitment of the member | + +### constructor + +```solidity +constructor(uint256 membershipDeposit, uint256 depth, address _poseidonHasher) public +``` + +### register + +```solidity +function register(uint256 idCommitment) external payable +``` + +Allows a user to register as a member + +#### Parameters + +| Name | Type | Description | +| ------------ | ------- | ------------------------------ | +| idCommitment | uint256 | The idCommitment of the member | + +### registerBatch + +```solidity +function registerBatch(uint256[] idCommitments) external payable +``` + +Allows batch registration of members + +#### Parameters + +| Name | Type | Description | +| ------------- | --------- | ---------------------- | +| idCommitments | uint256[] | array of idCommitments | + +### \_register + +```solidity +function _register(uint256 idCommitment, uint256 stake) internal +``` + +Registers a member + +#### Parameters + +| Name | Type | Description | +| ------------ | ------- | -------------------------------------- | +| idCommitment | uint256 | The idCommitment of the member | +| stake | uint256 | The amount of eth staked by the member | + +### withdrawBatch + +```solidity +function withdrawBatch(uint256[] secrets, address payable[] receivers) external +``` + +Allows a user to slash a batch of members + +#### Parameters + +| Name | Type | Description | +| --------- | ----------------- | --------------------------------------- | +| secrets | uint256[] | array of idSecretHashes | +| receivers | address payable[] | array of addresses to receive the funds | + +### withdraw + +```solidity +function withdraw(uint256 secret, address payable receiver) external +``` + +Allows a user to slash a member + +#### Parameters + +| Name | Type | Description | +| -------- | --------------- | ------------------------------ | +| secret | uint256 | The idSecretHash of the member | +| receiver | address payable | | + +### \_withdraw + +```solidity +function _withdraw(uint256 secret, address payable receiver) internal +``` + +Slashes a member by removing them from the set, and transferring their +stake to the receiver + +#### Parameters + +| Name | Type | Description | +| -------- | --------------- | -------------------------------- | +| secret | uint256 | The idSecretHash of the member | +| receiver | address payable | The address to receive the funds | + +### hash + +```solidity +function hash(uint256 input) internal view returns (uint256) +``` + +Hashes a value using the Poseidon hasher +NOTE: The variant of Poseidon we use accepts only 1 input, assume n=2, and the second input is 0 + +#### Parameters + +| Name | Type | Description | +| ----- | ------- | ----------------- | +| input | uint256 | The value to hash | diff --git a/hardhat.config.ts b/hardhat.config.ts index 2701eb5..c727cbb 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -9,6 +9,7 @@ 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 } = process.env; diff --git a/package.json b/package.json index 32df47a..84f8af1 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "coverage": "forge coverage --report lcov", "fmt": "prettier --write \"**/*.{js,ts}\"", "lint": "prettier --check \"**/*.{js,ts}\"", - "prepare": "husky install" + "prepare": "husky install", + "docgen": "hardhat docgen" }, "devDependencies": { "@nomicfoundation/hardhat-foundry": "^1.0.0", @@ -36,7 +37,8 @@ "husky": "^8.0.2", "lint-staged": "^13.0.3", "ts-node": "^10.8.1", - "typescript": "^4.7.4" + "typescript": "^4.7.4", + "solidity-docgen": "0.6.0-beta.35" }, "dependencies": { "dotenv": "^16.0.1" diff --git a/yarn.lock b/yarn.lock index 46275bb..91be2ee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4510,6 +4510,18 @@ growl@1.10.5: resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== +handlebars@^4.7.7: + version "4.7.7" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" + integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.0" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" @@ -6313,6 +6325,11 @@ negotiator@0.6.3: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== +neo-async@^2.6.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + next-tick@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" @@ -7739,6 +7756,19 @@ solc@^0.6.3: semver "^5.5.0" tmp "0.0.33" +solidity-ast@^0.4.38: + version "0.4.46" + resolved "https://registry.yarnpkg.com/solidity-ast/-/solidity-ast-0.4.46.tgz#d0745172dced937741d07464043564e35b147c59" + integrity sha512-MlPZQfPhjWXqh7YxWcBGDXaPZIfMYCOHYoLEhGDWulNwEPIQQZuB7mA9eP17CU0jY/bGR4avCEUVVpvHtT2gbA== + +solidity-docgen@0.6.0-beta.35: + version "0.6.0-beta.35" + resolved "https://registry.yarnpkg.com/solidity-docgen/-/solidity-docgen-0.6.0-beta.35.tgz#174d7fe54efa8b10f7d3cbe0dfc40e52e11bf867" + integrity sha512-9QdwK1THk/MWIdq1PEW/6dvtND0pUqpFTsbKwwU9YQIMYuRhH1lek9SsgnsGGYtdJ0VTrXXcVT30q20a8Y610A== + dependencies: + handlebars "^4.7.7" + solidity-ast "^0.4.38" + source-map-resolve@^0.5.0: version "0.5.3" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" @@ -7783,7 +7813,7 @@ source-map@^0.5.6, source-map@^0.5.7: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== -source-map@^0.6.0: +source-map@^0.6.0, source-map@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -8461,6 +8491,11 @@ typical@^2.6.0, typical@^2.6.1: resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d" integrity sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg== +uglify-js@^3.1.4: + version "3.17.4" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" + integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== + ultron@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" @@ -9027,6 +9062,11 @@ window-size@^0.2.0: resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" integrity sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw== +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== + workerpool@6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343"