style: fmt

This commit is contained in:
rymnc
2022-11-25 11:38:38 +05:30
parent 712b373c92
commit 67ed8ee703
14 changed files with 232 additions and 189 deletions

View File

@@ -1,4 +1,4 @@
module.exports = {
istanbulReporter: ['lcov'],
istanbulFolder: 'coverage',
}
istanbulReporter: ["lcov"],
istanbulFolder: "coverage",
};

View File

@@ -1,9 +1,5 @@
export const devNets = [
'hardhat',
'localhost',
'goerli',
]
export const devNets = ["hardhat", "localhost", "goerli"];
export const prodNets = ['mainnet']
export const prodNets = ["mainnet"];
export const isDevNet = (networkName: string) => devNets.includes(networkName)
export const isDevNet = (networkName: string) => devNets.includes(networkName);

View File

@@ -1,3 +1,3 @@
// barrel for all other utils
export * from './interep-utils';
export * from './chain-utils';
export * from "./interep-utils";
export * from "./chain-utils";

View File

@@ -1,33 +1,42 @@
import {utils} from "ethers";
import { utils } from "ethers";
export const sToBytes32 = (str: string): string => {
return utils.formatBytes32String(str);
}
return utils.formatBytes32String(str);
};
export const SNARK_SCALAR_FIELD = BigInt(
"21888242871839275222246405745257275088548364400416034343698204186575808495617"
)
"21888242871839275222246405745257275088548364400416034343698204186575808495617"
);
export const createGroupId = (provider: string, name: string): bigint => {
const providerBytes = sToBytes32(provider);
const nameBytes = sToBytes32(name);
return BigInt(utils.solidityKeccak256(["bytes32", "bytes32"], [providerBytes, nameBytes])) % SNARK_SCALAR_FIELD
}
const providerBytes = sToBytes32(provider);
const nameBytes = sToBytes32(name);
return (
BigInt(
utils.solidityKeccak256(
["bytes32", "bytes32"],
[providerBytes, nameBytes]
)
) % SNARK_SCALAR_FIELD
);
};
const providers = ['github', 'twitter', 'reddit'];
const tiers = ['bronze', 'silver', 'gold'];
const providers = ["github", "twitter", "reddit"];
const tiers = ["bronze", "silver", "gold"];
export const getGroups = () => {
return providers.flatMap(provider => tiers.map(tier => {
return {
provider: sToBytes32(provider),
name: sToBytes32(tier),
root: 1,
depth: 10,
}
}));
}
return providers.flatMap((provider) =>
tiers.map((tier) => {
return {
provider: sToBytes32(provider),
name: sToBytes32(tier),
root: 1,
depth: 10,
};
})
);
};
export const getValidGroups = () => {
return getGroups().filter(group => group.name !== sToBytes32('bronze'));
}
return getGroups().filter((group) => group.name !== sToBytes32("bronze"));
};

View File

@@ -1,16 +1,16 @@
import {HardhatRuntimeEnvironment} from 'hardhat/types';
import {DeployFunction} from 'hardhat-deploy/types';
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('PoseidonHasher', {
from: deployer,
log: true,
});
const { deployments, getUnnamedAccounts } = hre;
const { deploy } = deployments;
const [deployer] = await getUnnamedAccounts();
await deploy("PoseidonHasher", {
from: deployer,
log: true,
});
};
export default func;
func.tags = ['PoseidonHasher'];
func.tags = ["PoseidonHasher"];

View File

@@ -1,35 +1,33 @@
import {HardhatRuntimeEnvironment} from 'hardhat/types';
import {DeployFunction} from 'hardhat-deploy/types';
import {
getGroups,
isDevNet
} from '../common';
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
import { getGroups, isDevNet } from "../common";
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const {deployments, getUnnamedAccounts} = hre;
const {deploy} = deployments;
const [deployer] = await getUnnamedAccounts();
const interepTest = await deploy('InterepTest', {
from: deployer,
log: true,
args: [],
});
const { deployments, getUnnamedAccounts } = hre;
const { deploy } = deployments;
const contract = await hre.ethers.getContractAt('InterepTest', interepTest.address);
const groups = getGroups();
const groupInsertionTx = await contract.updateGroups(groups);
await groupInsertionTx.wait();
const [deployer] = await getUnnamedAccounts();
const interepTest = await deploy("InterepTest", {
from: deployer,
log: true,
args: [],
});
const contract = await hre.ethers.getContractAt(
"InterepTest",
interepTest.address
);
const groups = getGroups();
const groupInsertionTx = await contract.updateGroups(groups);
await groupInsertionTx.wait();
};
export default func;
func.tags = ['InterepTest'];
func.tags = ["InterepTest"];
// skip when running on mainnet
func.skip = async (hre: HardhatRuntimeEnvironment) => {
if (isDevNet(hre.network.name)) {
return false;
}
return true;
}
if (isDevNet(hre.network.name)) {
return false;
}
return true;
};

View File

@@ -1,24 +1,26 @@
import {HardhatRuntimeEnvironment} from 'hardhat/types';
import {DeployFunction} from 'hardhat-deploy/types';
import {getValidGroups, isDevNet} from '../common';
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
import { getValidGroups, isDevNet } from "../common";
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const {deployments, getUnnamedAccounts} = hre;
const {deploy} = deployments;
const [deployer] = await getUnnamedAccounts();
const { deployments, getUnnamedAccounts } = hre;
const { deploy } = deployments;
if (!isDevNet(hre.network.name)) {
throw new Error('Interep not deployed on mainnet yet.')
}
const interepAddress = isDevNet(hre.network.name) ? (await deployments.get('InterepTest')).address : '0x0000000000000000000000000000000000000000';
await deploy('ValidGroupStorage', {
from: deployer,
log: true,
args: [interepAddress, getValidGroups()]
});
const [deployer] = await getUnnamedAccounts();
if (!isDevNet(hre.network.name)) {
throw new Error("Interep not deployed on mainnet yet.");
}
const interepAddress = isDevNet(hre.network.name)
? (await deployments.get("InterepTest")).address
: "0x0000000000000000000000000000000000000000";
await deploy("ValidGroupStorage", {
from: deployer,
log: true,
args: [interepAddress, getValidGroups()],
});
};
export default func;
func.tags = ['ValidGroupStorage'];
func.dependencies = ['InterepTest'];
func.tags = ["ValidGroupStorage"];
func.dependencies = ["InterepTest"];

View File

@@ -1,21 +1,28 @@
import {HardhatRuntimeEnvironment} from 'hardhat/types';
import {DeployFunction} from 'hardhat-deploy/types';
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 { deployments, getUnnamedAccounts } = hre;
const { deploy } = deployments;
const poseidonHasherAddress = (await deployments.get('PoseidonHasher')).address;
const validGroupStorageAddress = (await deployments.get('ValidGroupStorage')).address;
await deploy('RLN', {
from: deployer,
log: true,
args: [1000000000000000, 20, poseidonHasherAddress, validGroupStorageAddress]
});
const [deployer] = await getUnnamedAccounts();
const poseidonHasherAddress = (await deployments.get("PoseidonHasher"))
.address;
const validGroupStorageAddress = (await deployments.get("ValidGroupStorage"))
.address;
await deploy("RLN", {
from: deployer,
log: true,
args: [
1000000000000000,
20,
poseidonHasherAddress,
validGroupStorageAddress,
],
});
};
export default func;
func.tags = ['RLN'];
func.dependencies = ['PoseidonHasher', 'ValidGroupStorage'];
func.tags = ["RLN"];
func.dependencies = ["PoseidonHasher", "ValidGroupStorage"];

View File

@@ -10,32 +10,35 @@ import "hardhat-gas-reporter";
import "solidity-coverage";
dotenv.config();
const {GOERLI_URL,PRIVATE_KEY} = process.env;
const { GOERLI_URL, PRIVATE_KEY } = process.env;
const getNetworkConfig = (): NetworksUserConfig | undefined => {
if (GOERLI_URL && PRIVATE_KEY) {
return {
goerli: {
url: GOERLI_URL,
accounts: [PRIVATE_KEY],
}
};
}
return undefined;
}
if (GOERLI_URL && PRIVATE_KEY) {
return {
goerli: {
url: GOERLI_URL,
accounts: [PRIVATE_KEY],
},
};
}
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.4",
}, {
version: "0.8.15"
}],
compilers: [
{
version: "0.8.4",
},
{
version: "0.8.15",
},
],
},
networks: getNetworkConfig()
networks: getNetworkConfig(),
};
export default config;
export default config;

View File

@@ -9,7 +9,8 @@
"deploy": "hardhat run scripts/deploy.ts --network",
"deploy:goerli": "yarn deploy goerli",
"deploy:localhost": "yarn deploy localhost",
"coverage": "hardhat coverage"
"coverage": "hardhat coverage",
"fmt": "prettier --write \"**/*.{js,ts}\""
},
"devDependencies": {
"@interep/contracts": "0.6.0",
@@ -24,6 +25,7 @@
"hardhat": "^2.9.9",
"hardhat-deploy": "0.11.20",
"hardhat-gas-reporter": "^1.0.8",
"prettier": "^2.8.0",
"solidity-coverage": "^0.7.21",
"ts-node": "^10.8.1",
"typescript": "^4.7.4"
@@ -31,4 +33,4 @@
"dependencies": {
"dotenv": "^16.0.1"
}
}
}

View File

@@ -8,10 +8,14 @@ describe("PoseidonHasher", () => {
it("should hash correctly", async function () {
const poseidonHasher = await ethers.getContract("PoseidonHasher");
// We test hashing for a random number
const hash = await poseidonHasher.hash("19014214495641488759237505126948346942972912379615652741039992445865937985820");
expect(hash._hex).to.eql("0x0c3ac305f6a4fe9bfeb3eba978bc876e2a99208b8b56c80160cfb54ba8f02368");
const hash = await poseidonHasher.hash(
"19014214495641488759237505126948346942972912379615652741039992445865937985820"
);
expect(hash._hex).to.eql(
"0x0c3ac305f6a4fe9bfeb3eba978bc876e2a99208b8b56c80160cfb54ba8f02368"
);
});
});

View File

@@ -4,53 +4,66 @@ 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 idCommitment =
"0x0c3ac305f6a4fe9bfeb3eba978bc876e2a99208b8b56c80160cfb54ba8f02368";
const registerTx = await rln['register(uint256)'](idCommitment, {value: price});
const registerTx = await rln["register(uint256)"](idCommitment, {
value: price,
});
const txRegisterReceipt = await registerTx.wait();
const pubkey = txRegisterReceipt.events[0].args.pubkey;
const pubkey = txRegisterReceipt.events[0].args.pubkey;
// We ensure the registered id_commitment is the one we passed
expect(pubkey.toHexString() === idCommitment, "registered commitment doesn't match passed commitment");
expect(
pubkey.toHexString() === idCommitment,
"registered commitment doesn't match passed commitment"
);
});
it("should withdraw membership", 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 idSecret = "0x2a09a9fd93c590c26b91effbb2499f07e8f7aa12e2b4940a3aed2411cb65e11c"
const idCommitment = "0x0c3ac305f6a4fe9bfeb3eba978bc876e2a99208b8b56c80160cfb54ba8f02368"
const idSecret =
"0x2a09a9fd93c590c26b91effbb2499f07e8f7aa12e2b4940a3aed2411cb65e11c";
const idCommitment =
"0x0c3ac305f6a4fe9bfeb3eba978bc876e2a99208b8b56c80160cfb54ba8f02368";
const registerTx = await rln['register(uint256)'](idCommitment, {value: price});
const registerTx = await rln["register(uint256)"](idCommitment, {
value: price,
});
const txRegisterReceipt = await registerTx.wait();
const treeIndex = txRegisterReceipt.events[0].args.index;
const treeIndex = txRegisterReceipt.events[0].args.index;
// We withdraw our id_commitment
const receiverAddress = "0x000000000000000000000000000000000000dead";
const withdrawTx = await rln.withdraw(idSecret, treeIndex, receiverAddress);
const txWithdrawReceipt = await withdrawTx.wait();
const withdrawalPk = txWithdrawReceipt.events[0].args.pubkey;
const withdrawalTreeIndex = txWithdrawReceipt.events[0].args.index;
// We ensure the registered id_commitment is the one we passed and that the index is the same
expect(withdrawalPk.toHexString() === idCommitment, "withdraw commitment doesn't match registered commitment");
expect(withdrawalTreeIndex.toHexString() === treeIndex.toHexString(), "withdraw index doesn't match registered index");
})
});
const receiverAddress = "0x000000000000000000000000000000000000dead";
const withdrawTx = await rln.withdraw(idSecret, treeIndex, receiverAddress);
const txWithdrawReceipt = await withdrawTx.wait();
const withdrawalPk = txWithdrawReceipt.events[0].args.pubkey;
const withdrawalTreeIndex = txWithdrawReceipt.events[0].args.index;
// We ensure the registered id_commitment is the one we passed and that the index is the same
expect(
withdrawalPk.toHexString() === idCommitment,
"withdraw commitment doesn't match registered commitment"
);
expect(
withdrawalTreeIndex.toHexString() === treeIndex.toHexString(),
"withdraw index doesn't match registered index"
);
});
});

View File

@@ -1,33 +1,42 @@
import {expect} from "chai";
import {ethers, deployments} from "hardhat";
import {sToBytes32, createGroupId} from '../common';
import { expect } from "chai";
import { ethers, deployments } from "hardhat";
import { sToBytes32, createGroupId } from "../common";
describe("Valid Group Storage", () => {
beforeEach(async () => {
await deployments.fixture(['ValidGroupStorage']);
})
beforeEach(async () => {
await deployments.fixture(["ValidGroupStorage"]);
});
it('should not deploy if an invalid group is passed in constructor', async () => {
const interepTest = await ethers.getContract('InterepTest');
const interepAddress = interepTest.address;
const ValidGroupStorage = await ethers.getContractFactory("ValidGroupStorage");
expect(ValidGroupStorage.deploy(interepAddress, [{
provider: sToBytes32('github'),
name: sToBytes32('diamond'),
}])).to.be.revertedWith("[ValidGroupStorage] Invalid group");
})
it("should not deploy if an invalid group is passed in constructor", async () => {
const interepTest = await ethers.getContract("InterepTest");
const interepAddress = interepTest.address;
it("should return true for valid group", async () => {
const validGroupStorage = await ethers.getContract('ValidGroupStorage');
const valid = await validGroupStorage.isValidGroup(createGroupId('github', 'silver'));
expect(valid).to.be.true;
});
const ValidGroupStorage = await ethers.getContractFactory(
"ValidGroupStorage"
);
expect(
ValidGroupStorage.deploy(interepAddress, [
{
provider: sToBytes32("github"),
name: sToBytes32("diamond"),
},
])
).to.be.revertedWith("[ValidGroupStorage] Invalid group");
});
it("should return false for invalid group", async () => {
const validGroupStorage = await ethers.getContract('ValidGroupStorage');
const valid = await validGroupStorage.isValidGroup(createGroupId('github', 'bronze'));
expect(valid).to.be.false;
});
})
it("should return true for valid group", async () => {
const validGroupStorage = await ethers.getContract("ValidGroupStorage");
const valid = await validGroupStorage.isValidGroup(
createGroupId("github", "silver")
);
expect(valid).to.be.true;
});
it("should return false for invalid group", async () => {
const validGroupStorage = await ethers.getContract("ValidGroupStorage");
const valid = await validGroupStorage.isValidGroup(
createGroupId("github", "bronze")
);
expect(valid).to.be.false;
});
});

View File

@@ -6970,7 +6970,7 @@ prepend-http@^2.0.0:
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==
prettier@^2.1.2:
prettier@^2.1.2, prettier@^2.8.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.0.tgz#c7df58393c9ba77d6fba3921ae01faf994fb9dc9"
integrity sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA==