Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

refactor(lean-imt): move from hardhat to forge #23

Closed
wants to merge 14 commits into from
Prev Previous commit
Next Next commit
chore: rebase
sripwoud committed Jul 3, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 27d8502e799f395dd5a2ef2fa2432c294253223a
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -4,3 +4,6 @@
[submodule "packages/lean-imt/lib/poseidon-solidity"]
path = packages/lean-imt/lib/poseidon-solidity
url = https://github.com/vimwitch/poseidon-solidity
[submodule "packages/lean-imt/lib/forge-std"]
path = packages/lean-imt/lib/forge-std
url = [email protected]:foundry-rs/forge-std.git
4 changes: 4 additions & 0 deletions packages/lean-imt/foundry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[profile.default]
remappings = [
"poseidon-solidity/=lib/poseidon-solidity/contracts/",
]
62 changes: 1 addition & 61 deletions packages/lean-imt/out/Constants.sol/Constants.json
Original file line number Diff line number Diff line change
@@ -1,61 +1 @@
{
"abi": [],
"bytecode": { "object": "0x", "linkReferences": {} },
"deployedBytecode": { "object": "0x", "linkReferences": {} },
"ast": {
"absolutePath": "src/Constants.sol",
"id": 37,
"exportedSymbols": { "SNARK_SCALAR_FIELD": [36] },
"nodeType": "SourceUnit",
"src": "39:142:1",
"nodes": [
{
"id": 33,
"nodeType": "PragmaDirective",
"src": "39:23:1",
"nodes": [],
"literals": ["solidity", "^", "0.8", ".4"]
},
{
"id": 36,
"nodeType": "VariableDeclaration",
"src": "64:115:1",
"nodes": [],
"constant": true,
"mutability": "constant",
"name": "SNARK_SCALAR_FIELD",
"nameLocation": "81:18:1",
"scope": 37,
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" },
"typeName": {
"id": 34,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "64:7:1",
"typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }
},
"value": {
"hexValue": "3231383838323432383731383339323735323232323436343035373435323537323735303838353438333634343030343136303334333433363938323034313836353735383038343935363137",
"id": 35,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "102:77:1",
"typeDescriptions": {
"typeIdentifier": "t_rational_21888242871839275222246405745257275088548364400416034343698204186575808495617_by_1",
"typeString": "int_const 2188...(69 digits omitted)...5617"
},
"value": "21888242871839275222246405745257275088548364400416034343698204186575808495617"
},
"visibility": "internal"
}
],
"license": "UNLICENSED"
},
"id": 1
}
{"abi":[],"bytecode":{"object":"0x","linkReferences":{}},"deployedBytecode":{"object":"0x","linkReferences":{}},"ast":{"absolutePath":"src/Constants.sol","id":38828,"exportedSymbols":{"SNARK_SCALAR_FIELD":[38827]},"nodeType":"SourceUnit","src":"39:142:24","nodes":[{"id":38824,"nodeType":"PragmaDirective","src":"39:23:24","nodes":[],"literals":["solidity","^","0.8",".4"]},{"id":38827,"nodeType":"VariableDeclaration","src":"64:115:24","nodes":[],"constant":true,"mutability":"constant","name":"SNARK_SCALAR_FIELD","nameLocation":"81:18:24","scope":38828,"stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":38825,"name":"uint256","nodeType":"ElementaryTypeName","src":"64:7:24","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"value":{"hexValue":"3231383838323432383731383339323735323232323436343035373435323537323735303838353438333634343030343136303334333433363938323034313836353735383038343935363137","id":38826,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"102:77:24","typeDescriptions":{"typeIdentifier":"t_rational_21888242871839275222246405745257275088548364400416034343698204186575808495617_by_1","typeString":"int_const 2188...(69 digits omitted)...5617"},"value":"21888242871839275222246405745257275088548364400416034343698204186575808495617"},"visibility":"internal"}],"license":"UNLICENSED"},"id":24}
9,986 changes: 1 addition & 9,985 deletions packages/lean-imt/out/InternalLeanIMT.sol/InternalLeanIMT.json

Large diffs are not rendered by default.

1,694 changes: 1 addition & 1,693 deletions packages/lean-imt/out/LeanIMT.sol/LeanIMT.json

Large diffs are not rendered by default.

240 changes: 1 addition & 239 deletions packages/lean-imt/out/LeanIMTTest.sol/LeanIMTTest.json

Large diffs are not rendered by default.

41,919 changes: 1 addition & 41,918 deletions packages/lean-imt/out/PoseidonT3.sol/PoseidonT3.json

Large diffs are not rendered by default.

60,949 changes: 0 additions & 60,949 deletions packages/lean-imt/out/build-info/b47d77f45b413256ebac8dd46e8783f0.json

This file was deleted.

This file was deleted.

156 changes: 156 additions & 0 deletions packages/lean-imt/test/LeamIMT.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "forge-std/Test.sol";
import "src/LeanIMT.sol";
import {LeafAlreadyExists, LeafCannotBeZero, LeafDoesNotExist, LeafGreaterThanSnarkScalarField, WrongSiblingNodes} from "src/InternalLeanIMT.sol";
import {SNARK_SCALAR_FIELD} from "src/Constants.sol";
import "forge-std/console.sol";

contract LeanIMTTest is Test {
using LeanIMT for LeanIMTData;

LeanIMTData private imt;

function boundLeaf(uint256 leaf) private view returns (uint256) {
return bound(leaf, 1, SNARK_SCALAR_FIELD - 1);
}

function boundLeaves(uint256[] calldata leaves) private view returns (uint256[] memory) {
uint256[] memory boundedLeaves = new uint256[](leaves.length);
for (uint256 i = 0; i < leaves.length; i++) {
boundedLeaves[i] = boundLeaf(leaves[i]);
}
return boundedLeaves;
}

function test_RevertIf_InsertLeafGreaterThanSnarkScalarField() public {
vm.expectRevert(LeafGreaterThanSnarkScalarField.selector);
imt.insert(SNARK_SCALAR_FIELD);

vm.expectRevert(LeafGreaterThanSnarkScalarField.selector);
imt.insert(SNARK_SCALAR_FIELD + 1);
}

function test_RevertIf_InsertZeroLeaf() public {
vm.expectRevert(LeafCannotBeZero.selector);
imt.insert(0);
}

function testRevert_InsertDuplicateLeaf() public {
imt.insert(1);
vm.expectRevert(LeafAlreadyExists.selector);
imt.insert(1);
}

function testFuzz_Insert(uint256 leaf) public {
// revert if leaf out of bound already tested above
leaf = boundLeaf(leaf);
uint256 root = imt.insert(leaf);

assertTrue(imt.has(leaf));
assertEq(imt.indexOf(leaf), 0);
assertEq(imt.root(), root);
assertEq(imt.size, 1);
assertEq(imt.depth, 0);
}

function test_RevertIf_InsertManyGreaterThanSnarkField() public {
vm.expectRevert(LeafGreaterThanSnarkScalarField.selector);
uint256[] memory leaves = new uint256[](1);
leaves[0] = SNARK_SCALAR_FIELD;

imt.insertMany(leaves);
}

function test_RevertIf_InsertManyZeroLeaf() public {
vm.expectRevert(LeafCannotBeZero.selector);
uint256[] memory leaves = new uint256[](1);
leaves[0] = 0;

imt.insertMany(leaves);
}

function test_RevertIf_InsertManyDuplicateLeaf() public {
uint256[] memory leaves = new uint256[](2);
leaves[0] = 1;
leaves[1] = 1;

vm.expectRevert(LeafAlreadyExists.selector);
imt.insertMany(leaves);
}

function test_insertMany() public {
uint256[] memory leaves = new uint256[](3);
leaves[0] = 1;
leaves[1] = 2;
leaves[2] = 3;

uint256 root = imt.insertMany(leaves);

for (uint256 i = 0; i < leaves.length; i++) {
assertTrue(imt.has(leaves[i]));
assertEq(imt.indexOf(leaves[i]), i);
}
assertEq(imt.root(), root);
assertEq(imt.size, 3);
assertEq(imt.depth, 2);
}

function test_RevertIf_UpdateNewLeafGreaterThanSnarkScalarField() public {
imt.insert(1);
vm.expectRevert(LeafGreaterThanSnarkScalarField.selector);
imt.update(1, SNARK_SCALAR_FIELD, new uint256[](0));

vm.expectRevert(LeafGreaterThanSnarkScalarField.selector);
imt.update(1, SNARK_SCALAR_FIELD + 1, new uint256[](0));
}

function test_RevertIf_UpdateNewLeafAlreadyExists() public {
imt.insert(1);
vm.expectRevert(LeafAlreadyExists.selector);
imt.update(1, 1, new uint256[](0));
}

function test_RevertIf_UpdateOldLeafDoesNotExist() public {
imt.insert(1);
vm.expectRevert(LeafDoesNotExist.selector);
imt.update(2, 3, new uint256[](0));
}

function testFuzz_Update(uint256 oldLeaf, uint256 newLeaf) public {
// all revert cases already tested above, so forcing they can't happen while still fuzzing
oldLeaf = boundLeaf(oldLeaf);
newLeaf = boundLeaf(newLeaf);
while (oldLeaf == newLeaf) {
newLeaf = boundLeaf(newLeaf + 1);
}

imt.insert(oldLeaf);
uint256 root = imt.update(oldLeaf, newLeaf, new uint256[](0));

assertTrue(imt.has(newLeaf));
assertFalse(imt.has(oldLeaf));
assertEq(imt.indexOf(newLeaf), 0);
assertEq(imt.root(), root);
assertEq(imt.size, 1);
assertEq(imt.depth, 0);
}

function test_FuzzRemove(uint256 leaf) public {
leaf = boundLeaf(leaf);
assertEq(imt.size, 0);
imt.insert(leaf);
uint256 root = imt.remove(leaf, new uint256[](0));

assertFalse(imt.has(leaf));
assertEq(imt.root(), root);
// TODO: question: remove does not update size??
assertFalse(imt.size == 0);
}

function test_RevertIf_IndexOfLeafDoesNotExist() public {
vm.expectRevert(LeafDoesNotExist.selector);
imt.indexOf(1);
}
}