diff --git a/packages/contracts/contracts/UnirepApp.sol b/packages/contracts/contracts/UnirepApp.sol index 45f2b4bd..ef62a216 100644 --- a/packages/contracts/contracts/UnirepApp.sol +++ b/packages/contracts/contracts/UnirepApp.sol @@ -1,16 +1,21 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; +import { Unirep } from "@unirep/contracts/Unirep.sol"; +import { EpochKeyVerifierHelper } from "@unirep/contracts/verifierHelpers/EpochKeyVerifierHelper.sol"; +import { EpochKeyLiteVerifierHelper } from "@unirep/contracts/verifierHelpers/EpochKeyLiteVerifierHelper.sol"; +import { BaseVerifierHelper } from "@unirep/contracts/verifierHelpers/BaseVerifierHelper.sol"; +import { VerifierHelperManager } from "./verifierHelpers/VerifierHelperManager.sol"; +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; +import { DailyClaimVHelper } from "./verifierHelpers/DailyClaimVHelper.sol"; -import {Unirep} from "@unirep/contracts/Unirep.sol"; -import {ReputationVerifierHelper} from "@unirep/contracts/verifierHelpers/ReputationVerifierHelper.sol"; -import {EpochKeyLiteVerifierHelper} from "@unirep/contracts/verifierHelpers/EpochKeyLiteVerifierHelper.sol"; -import {BaseVerifierHelper} from "@unirep/contracts/verifierHelpers/BaseVerifierHelper.sol"; -import {VerifierHelperManager} from "./verifierHelpers/VerifierHelperManager.sol"; -import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; -import {DailyClaimVHelper} from "./verifierHelpers/DailyClaimVHelper.sol"; +// Uncomment this line to use console.log +// import "hardhat/console.sol"; interface IVerifier { - function verifyProof(uint256[] calldata publicSignals, uint256[8] calldata proof) external view returns (bool); + function verifyProof( + uint256[] calldata publicSignals, + uint256[8] calldata proof + ) external view returns (bool); } contract UnirepApp is Ownable { @@ -27,7 +32,7 @@ contract UnirepApp is Ownable { Unirep public unirep; IVerifier internal dataVerifier; - ReputationVerifierHelper internal repHelper; + EpochKeyVerifierHelper internal epkHelper; EpochKeyLiteVerifierHelper internal epkLiteHelper; VerifierHelperManager internal verifierHelperManager; @@ -47,21 +52,42 @@ contract UnirepApp is Ownable { // Nagative Reputation field index in Unirep protocol uint256 public immutable negRepFieldIndex = 1; - event Post(uint256 indexed epochKey, uint256 indexed postId, uint256 indexed epoch, string content); + event Post( + uint256 indexed epochKey, + uint256 indexed postId, + uint256 indexed epoch, + string content + ); event Comment( - uint256 indexed epochKey, uint256 indexed postId, uint256 indexed commentId, uint256 epoch, string content + uint256 indexed epochKey, + uint256 indexed postId, + uint256 indexed commentId, + uint256 epoch, + string content ); event UpdatedComment( - uint256 indexed epochKey, uint256 indexed postId, uint256 indexed commentId, uint256 epoch, string newContent + uint256 indexed epochKey, + uint256 indexed postId, + uint256 indexed commentId, + uint256 epoch, + string newContent ); - event ClaimPosRep(uint256 indexed epochKey, uint256 epoch); + event ClaimPosRep( + uint256 indexed epochKey, + uint256 epoch + ); - event ClaimNegRep(uint256 indexed epochKey, uint256 epoch); + event ClaimNegRep( + uint256 indexed epochKey, + uint256 epoch + ); - event DailyEpochEnded(uint48 indexed epoch); + event DailyEpochEnded( + uint48 indexed epoch + ); uint160 immutable attesterId; @@ -79,7 +105,7 @@ contract UnirepApp is Ownable { constructor( Unirep _unirep, - ReputationVerifierHelper _repHelper, + EpochKeyVerifierHelper _epkHelper, EpochKeyLiteVerifierHelper _epkLiteHelper, IVerifier _dataVerifier, VerifierHelperManager _verifierHelperManager, @@ -88,8 +114,8 @@ contract UnirepApp is Ownable { // set unirep address unirep = _unirep; - // set reputation verifier helper address - repHelper = _repHelper; + // set epoch key verifier helper address + epkHelper = _epkHelper; // set epoch key lite verifier helper address epkLiteHelper = _epkLiteHelper; @@ -100,25 +126,18 @@ contract UnirepApp is Ownable { // set verifierHelper manager verifierHelperManager = _verifierHelperManager; - dailyEpochData = - DailyEpochData({startTimestamp: uint48(block.timestamp), currentEpoch: 0, epochLength: 24 * 60 * 60}); + dailyEpochData = DailyEpochData({ + startTimestamp: uint48(block.timestamp), + currentEpoch: 0, + epochLength: 24*60*60 + }); // sign up as an attester attesterId = uint160(msg.sender); unirep.attesterSignUp(_epochLength); } - /// @dev Decode and verify the reputation proofs - /// @return proofSignals proof signals or fails - function decodeAndVerify(uint256[] calldata publicSignals, uint256[8] calldata proof) - internal - view - returns (ReputationVerifierHelper.ReputationSignals memory proofSignals) - { - return repHelper.verifyAndCheckCaller(publicSignals, proof); - } - - /** + /** * Sign up users in this app * @param publicSignals: public signals * @param proof: UserSignUpProof @@ -144,10 +163,14 @@ contract UnirepApp is Ownable { /** * Post a content in this app * @param publicSignals: public signals - * @param proof: reputationProof from the user + * @param proof: epockKeyProof from the user * @param content: content of this post - */ - function post(uint256[] calldata publicSignals, uint256[8] calldata proof, string memory content) public { + */ + function post( + uint256[] memory publicSignals, + uint256[8] memory proof, + string memory content + ) public { // check if proof is used before bytes32 nullifier = keccak256(abi.encodePacked(publicSignals, proof)); if (proofNullifier[nullifier]) { @@ -156,7 +179,8 @@ contract UnirepApp is Ownable { proofNullifier[nullifier] = true; - ReputationVerifierHelper.ReputationSignals memory signals = decodeAndVerify(publicSignals, proof); + EpochKeyVerifierHelper.EpochKeySignals memory signals = epkHelper + .decodeEpochKeySignals(publicSignals); // check the epoch != current epoch (ppl can only post in current aepoch) uint48 epoch = unirep.attesterCurrentEpoch(signals.attesterId); @@ -164,8 +188,12 @@ contract UnirepApp is Ownable { revert InvalidEpoch(); } + // should check lastly + epkHelper.verifyAndCheckCaller(publicSignals, proof); + emit Post(signals.epochKey, latestPostId, signals.epoch, content); latestPostId++; + } /** @@ -176,8 +204,8 @@ contract UnirepApp is Ownable { * @param content: comment content */ function leaveComment( - uint256[] calldata publicSignals, - uint256[8] calldata proof, + uint256[] memory publicSignals, + uint256[8] memory proof, uint256 postId, string memory content ) public { @@ -188,19 +216,29 @@ contract UnirepApp is Ownable { } proofNullifier[nullifier] = true; - ReputationVerifierHelper.ReputationSignals memory signals = decodeAndVerify(publicSignals, proof); + EpochKeyVerifierHelper.EpochKeySignals memory signals = epkHelper + .decodeEpochKeySignals(publicSignals); - // check the epoch != current epoch (ppl can only leave comment in current epoch) + // check the epoch != current epoch (ppl can only post in current aepoch) uint48 epoch = unirep.attesterCurrentEpoch(signals.attesterId); if (signals.epoch != epoch) { revert InvalidEpoch(); } + // check if the proof is valid + epkHelper.verifyAndCheckCaller(publicSignals, proof); + uint256 commentId = postCommentIndex[postId]; epochKeyCommentMap[postId][commentId] = signals.epochKey; postCommentIndex[postId] = commentId + 1; - emit Comment(signals.epochKey, postId, commentId, signals.epoch, content); + emit Comment( + signals.epochKey, + postId, + commentId, + signals.epoch, + content + ); } /** @@ -226,8 +264,10 @@ contract UnirepApp is Ownable { proofNullifier[nullifier] = true; - EpochKeyLiteVerifierHelper.EpochKeySignals memory signals = - epkLiteHelper.decodeEpochKeyLiteSignals(publicSignals); + EpochKeyLiteVerifierHelper.EpochKeySignals + memory signals = epkLiteHelper.decodeEpochKeyLiteSignals( + publicSignals + ); // check the epoch != current epoch (ppl can only post in current aepoch) uint48 epoch = unirep.attesterCurrentEpoch(signals.attesterId); @@ -246,20 +286,29 @@ contract UnirepApp is Ownable { epkLiteHelper.verifyAndCheckCaller(publicSignals, proof); - emit UpdatedComment(signals.epochKey, postId, commentId, signals.epoch, newContent); + emit UpdatedComment( + signals.epochKey, + postId, + commentId, + signals.epoch, + newContent + ); } /// @param publicSignals The public signals of the snark proof /// @param proof The proof data of the snark proof /// @param identifier sha256(verifier_contract_name) /// @return signals The EpochKeySignals from BaseVerifierHelper - function verifyWithIdentifier(uint256[] calldata publicSignals, uint256[8] calldata proof, bytes32 identifier) - public - view - returns (BaseVerifierHelper.EpochKeySignals memory) - { - BaseVerifierHelper.EpochKeySignals memory signal = - verifierHelperManager.verifyProof(publicSignals, proof, identifier); + function verifyWithIdentifier( + uint256[] calldata publicSignals, + uint256[8] calldata proof, + bytes32 identifier + ) public view returns (BaseVerifierHelper.EpochKeySignals memory) { + BaseVerifierHelper.EpochKeySignals memory signal = verifierHelperManager.verifyProof( + publicSignals, + proof, + identifier + ); return signal; } @@ -278,11 +327,19 @@ contract UnirepApp is Ownable { } } - function submitAttestation(uint256 epochKey, uint48 targetEpoch, uint256 fieldIndex, uint256 val) public { + function submitAttestation( + uint256 epochKey, + uint48 targetEpoch, + uint256 fieldIndex, + uint256 val + ) public { unirep.attest(epochKey, targetEpoch, fieldIndex, val); } - function verifyDataProof(uint256[] calldata publicSignals, uint256[8] calldata proof) public view returns (bool) { + function verifyDataProof( + uint256[] calldata publicSignals, + uint256[8] calldata proof + ) public view returns (bool) { return dataVerifier.verifyProof(publicSignals, proof); } @@ -297,7 +354,7 @@ contract UnirepApp is Ownable { uint256[8] calldata proof, bytes32 identifier, uint256 change - ) public onlyOwner { + ) public onlyOwner() { // check if proof is used before bytes32 nullifier = keccak256(abi.encodePacked(publicSignals, proof)); if (proofNullifier[nullifier]) { @@ -306,8 +363,11 @@ contract UnirepApp is Ownable { proofNullifier[nullifier] = true; - BaseVerifierHelper.EpochKeySignals memory signals = - verifierHelperManager.verifyProof(publicSignals, proof, identifier); + BaseVerifierHelper.EpochKeySignals memory signals = verifierHelperManager.verifyProof( + publicSignals, + proof, + identifier + ); // check the epoch != current epoch (ppl can only claim in current epoch) uint48 epoch = unirep.attesterCurrentEpoch(signals.attesterId); @@ -331,10 +391,11 @@ contract UnirepApp is Ownable { * @param publicSignals: public signals * @param proof: daily claim proof */ - function claimDailyLoginRep(uint256[] calldata publicSignals, uint256[8] calldata proof, bytes32 identifier) - public - onlyOwner - { + function claimDailyLoginRep( + uint256[] calldata publicSignals, + uint256[8] calldata proof, + bytes32 identifier + ) public onlyOwner() { _updateDailyEpochIfNeeded(); DailyClaimVHelper dailyClaimVHelpers = DailyClaimVHelper(verifierHelperManager.registeredVHelpers(identifier)); @@ -363,7 +424,11 @@ contract UnirepApp is Ownable { revert NonNegativeReputation(); } - verifierHelperManager.verifyProof(publicSignals, proof, identifier); + verifierHelperManager.verifyProof( + publicSignals, + proof, + identifier + ); // attesting on Unirep contract: unirep.attest( @@ -373,7 +438,10 @@ contract UnirepApp is Ownable { 1 ); - emit ClaimPosRep(signals.epochKey, epoch); + emit ClaimPosRep( + signals.epochKey, + epoch + ); } /** @@ -387,7 +455,7 @@ contract UnirepApp is Ownable { uint256[8] calldata proof, bytes32 identifier, uint256 change - ) public onlyOwner { + ) public onlyOwner() { // check if proof is used before bytes32 nullifier = keccak256(abi.encodePacked(publicSignals, proof)); if (proofNullifier[nullifier]) { @@ -396,8 +464,11 @@ contract UnirepApp is Ownable { proofNullifier[nullifier] = true; - BaseVerifierHelper.EpochKeySignals memory signals = - verifierHelperManager.verifyProof(publicSignals, proof, identifier); + BaseVerifierHelper.EpochKeySignals memory signals = verifierHelperManager.verifyProof( + publicSignals, + proof, + identifier + ); // check the epoch != current epoch (ppl can only claim in current epoch) uint48 epoch = unirep.attesterCurrentEpoch(signals.attesterId); @@ -408,7 +479,12 @@ contract UnirepApp is Ownable { // attesting on Unirep contract: // 1. punishing poster (5) // 2. punishing reporter (1) - unirep.attest(signals.epochKey, epoch, negRepFieldIndex, change); + unirep.attest( + signals.epochKey, + epoch, + negRepFieldIndex, + change + ); emit ClaimNegRep(signals.epochKey, epoch); } diff --git a/packages/contracts/contracts/interfaces/IVerifierHelper.sol b/packages/contracts/contracts/interfaces/IVerifierHelper.sol index d78b5bc8..67192e02 100644 --- a/packages/contracts/contracts/interfaces/IVerifierHelper.sol +++ b/packages/contracts/contracts/interfaces/IVerifierHelper.sol @@ -1,25 +1,24 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {Unirep} from "@unirep/contracts/Unirep.sol"; -import {IVerifier} from "@unirep/contracts/interfaces/IVerifier.sol"; -import {BaseVerifierHelper} from "@unirep/contracts/verifierHelpers/BaseVerifierHelper.sol"; +import { Unirep } from "@unirep/contracts/Unirep.sol"; +import { IVerifier } from "@unirep/contracts/interfaces/IVerifier.sol"; +import { BaseVerifierHelper } from "@unirep/contracts/verifierHelpers/BaseVerifierHelper.sol"; /// @title IVerifierHelper /// @dev Interface for VerifierHelpers in Unirep Social-TW interface IVerifierHelper { /// @param publicSignals The public signals of the snark proof /// @return signals The EpochKeySignals - function decodeSignals(uint256[] calldata publicSignals) - external - pure - returns (BaseVerifierHelper.EpochKeySignals memory); + function decodeSignals( + uint256[] calldata publicSignals + ) external pure returns (BaseVerifierHelper.EpochKeySignals memory); /// @param publicSignals The public signals of the snark proof /// @param proof The proof data of the snark proof /// @return signals The EpochKeySignals - function verifyAndCheck(uint256[] calldata publicSignals, uint256[8] calldata proof) - external - view - returns (BaseVerifierHelper.EpochKeySignals memory); + function verifyAndCheck( + uint256[] calldata publicSignals, + uint256[8] calldata proof + ) external view returns (BaseVerifierHelper.EpochKeySignals memory); } diff --git a/packages/contracts/contracts/verifierHelpers/DailyClaimVHelper.sol b/packages/contracts/contracts/verifierHelpers/DailyClaimVHelper.sol index 088d63cc..d02cf0c7 100644 --- a/packages/contracts/contracts/verifierHelpers/DailyClaimVHelper.sol +++ b/packages/contracts/contracts/verifierHelpers/DailyClaimVHelper.sol @@ -1,13 +1,16 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {BaseVerifierHelper} from "@unirep/contracts/verifierHelpers/BaseVerifierHelper.sol"; -import {Unirep} from "@unirep/contracts/Unirep.sol"; -import {IVerifier} from "@unirep/contracts/interfaces/IVerifier.sol"; -import {IVerifierHelper} from "../interfaces/IVerifierHelper.sol"; +import { BaseVerifierHelper } from "@unirep/contracts/verifierHelpers/BaseVerifierHelper.sol"; +import { Unirep } from "@unirep/contracts/Unirep.sol"; +import { IVerifier } from "@unirep/contracts/interfaces/IVerifier.sol"; +import { IVerifierHelper } from "../interfaces/IVerifierHelper.sol"; contract DailyClaimVHelper is BaseVerifierHelper, IVerifierHelper { - constructor(Unirep _unirep, IVerifier _verifier) BaseVerifierHelper(_unirep, _verifier) {} + constructor( + Unirep _unirep, + IVerifier _verifier + ) BaseVerifierHelper(_unirep, _verifier) {} struct DailyClaimSignals { uint256 epochKey; @@ -28,12 +31,19 @@ contract DailyClaimVHelper is BaseVerifierHelper, IVerifierHelper { /// @param publicSignals The public signals of the snark proof /// @return signals The EpochKeySignals - function decodeSignals(uint256[] calldata publicSignals) public pure returns (EpochKeySignals memory) { + function decodeSignals( + uint256[] calldata publicSignals + ) public pure returns (EpochKeySignals memory) { EpochKeySignals memory signals; - (signals.nonce, signals.epoch, signals.attesterId, signals.revealNonce, signals.chainId) = - super.decodeEpochKeyControl(publicSignals[1]); + ( + signals.nonce, + signals.epoch, + signals.attesterId, + signals.revealNonce, + signals.chainId + ) = super.decodeEpochKeyControl(publicSignals[1]); signals.epochKey = publicSignals[0]; - + if (signals.epochKey >= SNARK_SCALAR_FIELD) revert InvalidEpochKey(); return signals; @@ -42,15 +52,22 @@ contract DailyClaimVHelper is BaseVerifierHelper, IVerifierHelper { /// @dev https://developer.unirep.io/docs/contracts-api/verifiers/reputation-verifier-helper#decodereputationsignals /// @param publicSignals The public signals of the snark proof /// @return signals The ReputationSignals - function decodeDailyClaimSignals(uint256[] calldata publicSignals) public pure returns (DailyClaimSignals memory) { + function decodeDailyClaimSignals( + uint256[] calldata publicSignals + ) public pure returns (DailyClaimSignals memory) { DailyClaimSignals memory signals; signals.epochKey = publicSignals[0]; signals.dailyEpoch = uint48(publicSignals[3]); signals.dailyNullifier = publicSignals[4]; // now decode the control values - (signals.nonce, signals.epoch, signals.attesterId, signals.revealNonce, signals.chainId) = - super.decodeEpochKeyControl(publicSignals[1]); + ( + signals.nonce, + signals.epoch, + signals.attesterId, + signals.revealNonce, + signals.chainId + ) = super.decodeEpochKeyControl(publicSignals[1]); ( signals.minRep, @@ -66,15 +83,14 @@ contract DailyClaimVHelper is BaseVerifierHelper, IVerifierHelper { return signals; } - + /// @param publicSignals The public signals of the snark proof /// @param proof The proof data of the snark proof /// @return signals The EpochKeySignals - function verifyAndCheck(uint256[] calldata publicSignals, uint256[8] calldata proof) - public - view - returns (EpochKeySignals memory) - { + function verifyAndCheck( + uint256[] calldata publicSignals, + uint256[8] calldata proof + ) public view returns (EpochKeySignals memory) { EpochKeySignals memory signals = decodeSignals(publicSignals); if (!verifier.verifyProof(publicSignals, proof)) revert InvalidProof(); @@ -90,7 +106,9 @@ contract DailyClaimVHelper is BaseVerifierHelper, IVerifierHelper { /// @return proveMaxRep Whether to prove maximum rep information in the control field /// @return proveZeroRep Whether to prove zero rep information in the control field /// @return proveGraffiti Whether to prove graffiti information in the control field - function decodeReputationControl(uint256 control) + function decodeReputationControl( + uint256 control + ) public pure returns ( @@ -123,4 +141,4 @@ contract DailyClaimVHelper is BaseVerifierHelper, IVerifierHelper { proveGraffiti = bool(shiftAndParse(control, accBits, oneBit) != 0); accBits += oneBit; } -} +} \ No newline at end of file diff --git a/packages/contracts/contracts/verifierHelpers/ReportNonNullifierVHelper.sol b/packages/contracts/contracts/verifierHelpers/ReportNonNullifierVHelper.sol index 6491c133..b71a1022 100644 --- a/packages/contracts/contracts/verifierHelpers/ReportNonNullifierVHelper.sol +++ b/packages/contracts/contracts/verifierHelpers/ReportNonNullifierVHelper.sol @@ -1,39 +1,48 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {BaseVerifierHelper} from "@unirep/contracts/verifierHelpers/BaseVerifierHelper.sol"; -import {Unirep} from "@unirep/contracts/Unirep.sol"; -import {IVerifier} from "@unirep/contracts/interfaces/IVerifier.sol"; -import {IVerifierHelper} from "../interfaces/IVerifierHelper.sol"; +import { BaseVerifierHelper } from "@unirep/contracts/verifierHelpers/BaseVerifierHelper.sol"; +import { Unirep } from "@unirep/contracts/Unirep.sol"; +import { IVerifier } from "@unirep/contracts/interfaces/IVerifier.sol"; +import { IVerifierHelper } from "../interfaces/IVerifierHelper.sol"; contract ReportNonNullifierVHelper is BaseVerifierHelper, IVerifierHelper { - constructor(Unirep _unirep, IVerifier _verifier) BaseVerifierHelper(_unirep, _verifier) {} + constructor( + Unirep _unirep, + IVerifier _verifier + ) BaseVerifierHelper(_unirep, _verifier) {} /// @param publicSignals The public signals of the snark proof /// @return signals The EpochKeySignals - function decodeSignals(uint256[] calldata publicSignals) public pure returns (EpochKeySignals memory) { + function decodeSignals( + uint256[] calldata publicSignals + ) public pure returns (EpochKeySignals memory) { EpochKeySignals memory signals; - (signals.nonce, signals.epoch, signals.attesterId, signals.revealNonce, signals.chainId) = - super.decodeEpochKeyControl(publicSignals[0]); + ( + signals.nonce, + signals.epoch, + signals.attesterId, + signals.revealNonce, + signals.chainId + ) = super.decodeEpochKeyControl(publicSignals[0]); signals.epochKey = publicSignals[1]; - + if (signals.epochKey >= SNARK_SCALAR_FIELD) revert InvalidEpochKey(); return signals; } - + /// @param publicSignals The public signals of the snark proof /// @param proof The proof data of the snark proof /// @return signals The EpochKeySignals - function verifyAndCheck(uint256[] calldata publicSignals, uint256[8] calldata proof) - public - view - returns (EpochKeySignals memory) - { + function verifyAndCheck( + uint256[] calldata publicSignals, + uint256[8] calldata proof + ) public view returns (EpochKeySignals memory) { EpochKeySignals memory signals = decodeSignals(publicSignals); if (!verifier.verifyProof(publicSignals, proof)) revert InvalidProof(); return signals; } -} +} \ No newline at end of file diff --git a/packages/contracts/contracts/verifierHelpers/ReportNullifierVHelper.sol b/packages/contracts/contracts/verifierHelpers/ReportNullifierVHelper.sol index ef4f631b..6adb0a25 100644 --- a/packages/contracts/contracts/verifierHelpers/ReportNullifierVHelper.sol +++ b/packages/contracts/contracts/verifierHelpers/ReportNullifierVHelper.sol @@ -1,40 +1,49 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {BaseVerifierHelper} from "@unirep/contracts/verifierHelpers/BaseVerifierHelper.sol"; -import {Unirep} from "@unirep/contracts/Unirep.sol"; -import {IVerifier} from "@unirep/contracts/interfaces/IVerifier.sol"; -import {IVerifierHelper} from "../interfaces/IVerifierHelper.sol"; +import { BaseVerifierHelper } from "@unirep/contracts/verifierHelpers/BaseVerifierHelper.sol"; +import { Unirep } from "@unirep/contracts/Unirep.sol"; +import { IVerifier } from "@unirep/contracts/interfaces/IVerifier.sol"; +import { IVerifierHelper } from "../interfaces/IVerifierHelper.sol"; contract ReportNullifierVHelper is BaseVerifierHelper, IVerifierHelper { - constructor(Unirep _unirep, IVerifier _verifier) BaseVerifierHelper(_unirep, _verifier) {} + constructor( + Unirep _unirep, + IVerifier _verifier + ) BaseVerifierHelper(_unirep, _verifier) {} /// @param publicSignals The public signals of the snark proof /// @return signals The EpochKeySignals - function decodeSignals(uint256[] calldata publicSignals) public pure returns (EpochKeySignals memory) { + function decodeSignals( + uint256[] calldata publicSignals + ) public pure returns (EpochKeySignals memory) { EpochKeySignals memory signals; - (signals.nonce, signals.epoch, signals.attesterId, signals.revealNonce, signals.chainId) = - super.decodeEpochKeyControl(publicSignals[0]); + ( + signals.nonce, + signals.epoch, + signals.attesterId, + signals.revealNonce, + signals.chainId + ) = super.decodeEpochKeyControl(publicSignals[0]); signals.epochKey = publicSignals[1]; - + if (signals.epochKey >= SNARK_SCALAR_FIELD) revert InvalidEpochKey(); return signals; } - + /// @param publicSignals The public signals of the snark proof /// @param proof The proof data of the snark proof /// @return signals The EpochKeySignals - function verifyAndCheck(uint256[] calldata publicSignals, uint256[8] calldata proof) - public - view - returns (EpochKeySignals memory) - { + function verifyAndCheck( + uint256[] calldata publicSignals, + uint256[8] calldata proof + ) public view returns (EpochKeySignals memory) { EpochKeySignals memory signals = decodeSignals(publicSignals); if (!verifier.verifyProof(publicSignals, proof)) revert InvalidProof(); return signals; } -} +} \ No newline at end of file diff --git a/packages/contracts/contracts/verifierHelpers/VerifierHelperManager.sol b/packages/contracts/contracts/verifierHelpers/VerifierHelperManager.sol index a70d404f..27c98bc3 100644 --- a/packages/contracts/contracts/verifierHelpers/VerifierHelperManager.sol +++ b/packages/contracts/contracts/verifierHelpers/VerifierHelperManager.sol @@ -1,19 +1,21 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {IVerifierHelper} from "../interfaces/IVerifierHelper.sol"; -import {BaseVerifierHelper} from "@unirep/contracts/verifierHelpers/BaseVerifierHelper.sol"; -import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; +import { IVerifierHelper } from "../interfaces/IVerifierHelper.sol"; +import { BaseVerifierHelper } from "@unirep/contracts/verifierHelpers/BaseVerifierHelper.sol"; +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; contract VerifierHelperManager is Ownable { mapping(bytes32 => address) public registeredVHelpers; // see verifierRegister - error IdentifierNotRegistered(bytes32); /// @dev register VerifierHelper Contract in Unirep Social-TW /// @param identifier sha256(verifier_contract_name) - /// @param addr the address where the verifier is deployed - function verifierRegister(bytes32 identifier, address addr) public onlyOwner { + /// @param addr the address where the verifier is deployed + function verifierRegister( + bytes32 identifier, + address addr + ) public onlyOwner() { registeredVHelpers[identifier] = addr; } @@ -22,17 +24,16 @@ contract VerifierHelperManager is Ownable { /// @param proof The proof data of the snark proof /// @param identifier sha256(verifier_contract_name) /// @return signals The EpochKeySignals from BaseVerifierHelper - function verifyProof(uint256[] calldata publicSignals, uint256[8] calldata proof, bytes32 identifier) - public - view - returns (BaseVerifierHelper.EpochKeySignals memory) - { + function verifyProof( + uint256[] calldata publicSignals, + uint256[8] calldata proof, + bytes32 identifier + ) public view returns (BaseVerifierHelper.EpochKeySignals memory) { address vHelperAddr = registeredVHelpers[identifier]; if (vHelperAddr == address(0)) { revert IdentifierNotRegistered(identifier); } - BaseVerifierHelper.EpochKeySignals memory signal = - IVerifierHelper(vHelperAddr).verifyAndCheck(publicSignals, proof); - return signal; + BaseVerifierHelper.EpochKeySignals memory signal = IVerifierHelper(vHelperAddr).verifyAndCheck(publicSignals, proof); + return signal; } -} +} \ No newline at end of file diff --git a/packages/contracts/scripts/utils/deployUnirepSocialTw.ts b/packages/contracts/scripts/utils/deployUnirepSocialTw.ts index 7d6e0c65..b1b729c9 100644 --- a/packages/contracts/scripts/utils/deployUnirepSocialTw.ts +++ b/packages/contracts/scripts/utils/deployUnirepSocialTw.ts @@ -21,12 +21,11 @@ const VHelperManager = VerifierHelperManager // alias for verifier helper manage export async function deployApp(deployer: ethers.Signer, epochLength: number) { const unirep = await deployUnirep(deployer) - const repHelper = await deployVerifierHelper( + const epkHelper = await deployVerifierHelper( unirep.address, deployer, - Circuit.reputation + Circuit.epochKey ) - const epkLiteHelper = await deployVerifierHelper( unirep.address, deployer, @@ -112,7 +111,7 @@ export async function deployApp(deployer: ethers.Signer, epochLength: number) { const app = await AppF.deploy( unirep.address, - repHelper.address, + epkHelper.address, epkLiteHelper.address, dataProofVerifier.address, vHelperManager.address, diff --git a/packages/contracts/test/ClaimDailyLoginRep.test.ts b/packages/contracts/test/ClaimDailyLoginRep.test.ts index 46abe1e7..c399308f 100644 --- a/packages/contracts/test/ClaimDailyLoginRep.test.ts +++ b/packages/contracts/test/ClaimDailyLoginRep.test.ts @@ -1,9 +1,9 @@ // @ts-ignore +import { ethers } from 'hardhat' import { DailyClaimProof } from '@unirep-app/circuits' import { ReputationProof } from '@unirep/circuits' import { genEpochKey } from '@unirep/utils' import { expect } from 'chai' -import { ethers } from 'hardhat' import { deployApp } from '../scripts/utils/deployUnirepSocialTw' import { Unirep, UnirepApp } from '../typechain-types' import { IdentityObject } from './types' diff --git a/packages/contracts/test/Comment.test.ts b/packages/contracts/test/Comment.test.ts index 764a0dbb..b2b118ae 100644 --- a/packages/contracts/test/Comment.test.ts +++ b/packages/contracts/test/Comment.test.ts @@ -1,15 +1,16 @@ //@ts-ignore -import { CircuitConfig } from '@unirep/circuits' -import { expect } from 'chai' import { ethers } from 'hardhat' +import { expect } from 'chai' +import { CircuitConfig } from '@unirep/circuits' import { describe } from 'node:test' import { deployApp } from '../scripts/utils/deployUnirepSocialTw' import { Unirep, UnirepApp } from '../typechain-types' import { createMultipleUserIdentity, genEpochKeyLiteProof, - genReputationProof, + genEpochKeyProof, genUserState, + randomData, } from './utils' const { STATE_TREE_DEPTH } = CircuitConfig.default @@ -67,8 +68,9 @@ describe('Comment Test', function () { // user 1 post something const content = 'something interesting' const userState = await genUserState(users[0].id, app) - const repProof = await userState.genProveReputationProof({}) - await app.post(repProof.publicSignals, repProof.proof, content) + const { publicSignals: epochKeySig1, proof: epochKeyProof1 } = + await userState.genEpochKeyProof() + await app.post(epochKeySig1, epochKeyProof1, content) chainId = await unirep.chainid() }) @@ -77,18 +79,17 @@ describe('Comment Test', function () { it('should revert leaving comment with invalid epoch', async function () { const userState = await genUserState(users[1].id, app) const id = users[1].id - const attesterId = userState.sync.attesterId - const epoch = await userState.sync.loadCurrentEpoch() // generating a proof with wrong epoch const wrongEpoch = 44444 + const attesterId = userState.sync.attesterId + const epoch = await userState.sync.loadCurrentEpoch() const tree = await userState.sync.genStateTree(epoch, attesterId) const leafIndex = await userState.latestStateTreeLeafIndex( epoch, attesterId ) - const data = await userState.getProvableData() - - const repProof = await genReputationProof({ + const data = randomData() + const { publicSignals, proof } = await genEpochKeyProof({ id, tree, leafIndex, @@ -98,60 +99,48 @@ describe('Comment Test', function () { attesterId, data, }) - const postId = 0 await expect( - app.leaveComment( - repProof.publicSignals, - repProof.proof, - postId, - 'Invalid Epoch' - ) + app.leaveComment(publicSignals, proof, postId, 'Invalid Epoch') ).to.be.revertedWithCustomError(app, 'InvalidEpoch') userState.stop() }) - it('should revert leaving comment with invalid reputation proof', async function () { + it('should revert leaving comment with invalid epoch key proof', async function () { const userState = await genUserState(users[1].id, app) - const repProof = await userState.genProveReputationProof({}) + const { publicSignals, proof } = await userState.genEpochKeyProof({ + nonce: 0, + }) const content = 'This is so interesting!' - repProof.proof[0] = BigInt(0) + proof[0] = BigInt(0) await expect( - app.leaveComment( - repProof.publicSignals, - repProof.proof, - BigInt(0), - content - ) + app.leaveComment(publicSignals, proof, BigInt(0), content) ).to.be.reverted userState.stop() }) - it('should comment with valid reputation proof and signals', async function () { + it('should comment with valid epoch key proof and signals', async function () { const userState = await genUserState(users[1].id, app) - const repProof = await userState.genProveReputationProof({}) + const { publicSignals, proof } = await userState.genEpochKeyProof({ + nonce: 0, + }) const content = 'This is so interesting!' const postId = 0 const commentId = 0 const epoch = await userState.sync.loadCurrentEpoch() // record the used proof here - inputPublicSig = repProof.publicSignals - inputProof = repProof.proof + inputPublicSig = publicSignals + inputProof = proof await expect( - app.leaveComment( - repProof.publicSignals, - repProof.proof, - postId, - content - ) + app.leaveComment(publicSignals, proof, postId, content) ) .to.emit(app, 'Comment') .withArgs( - repProof.publicSignals[0], // epochKey + publicSignals[0], // epochKey postId, commentId, epoch, diff --git a/packages/contracts/test/SignupAndPost.test.ts b/packages/contracts/test/SignupAndPost.test.ts index 6939447f..ce722463 100644 --- a/packages/contracts/test/SignupAndPost.test.ts +++ b/packages/contracts/test/SignupAndPost.test.ts @@ -1,21 +1,22 @@ //@ts-ignore +import { ethers } from 'hardhat' import { DataProof } from '@unirep-app/circuits' import { defaultProver as prover } from '@unirep-app/circuits/provers/defaultProver' import { Circuit, CircuitConfig } from '@unirep/circuits' import { deployVerifierHelper } from '@unirep/contracts/deploy' import { stringifyBigInts } from '@unirep/utils' import { expect } from 'chai' -import { ethers } from 'hardhat' import { describe } from 'node:test' import { deployApp } from '../scripts/utils/deployUnirepSocialTw' import { IdentityObject } from './types' import { createRandomUserIdentity, - genReputationProof, + genEpochKeyProof, genUserState, + randomData, } from './utils' -const { FIELD_COUNT } = CircuitConfig.default +const { FIELD_COUNT, STATE_TREE_DEPTH } = CircuitConfig.default describe('Unirep App', function () { let unirep: any @@ -114,15 +115,16 @@ describe('Unirep App', function () { describe('user post', function () { it('should fail to post with invalid proof', async function () { const userState = await genUserState(user.id, app) - const repProof = await userState.genProveReputationProof({}) + const { publicSignals, proof } = await userState.genEpochKeyProof() // generate a fake proof - repProof.proof[0] = BigInt(0) + const concoctProof = [...proof] + const len = concoctProof[0].toString().length + concoctProof[0] = BigInt(2) const content = 'Invalid Proof' - await expect( - app.post(repProof.publicSignals, repProof.proof, content) - ).to.be.reverted // revert in epkHelper.verifyAndCheck() + await expect(app.post(publicSignals, concoctProof, content)).to.be + .reverted // revert in epkHelper.verifyAndCheck() userState.stop() }) @@ -130,13 +132,14 @@ describe('Unirep App', function () { it('should post with valid proof', async function () { const content = 'Valid Proof' const userState = await genUserState(user.id, app) - const repProof = await userState.genProveReputationProof({}) + const { publicSignals, proof } = await userState.genEpochKeyProof() - await expect( - app.post(repProof.publicSignals, repProof.proof, content) - ) + inputPublicSig = publicSignals + inputProof = proof + + await expect(app.post(publicSignals, proof, content)) .to.emit(app, 'Post') - .withArgs(repProof.publicSignals[0], 0, 0, content) + .withArgs(publicSignals[0], 0, 0, content) userState.stop() }) @@ -144,16 +147,14 @@ describe('Unirep App', function () { it('should post and have the correct postId', async function () { const content = 'Valid Proof' const userState = await genUserState(user.id, app) - const repProof = await userState.genProveReputationProof({}) + const { publicSignals, proof } = await userState.genEpochKeyProof() - inputPublicSig = repProof.publicSignals - inputProof = repProof.proof + inputPublicSig = publicSignals + inputProof = proof - await expect( - app.post(repProof.publicSignals, repProof.proof, content) - ) + await expect(app.post(publicSignals, proof, content)) .to.emit(app, 'Post') - .withArgs(repProof.publicSignals[0], 1, 0, content) + .withArgs(publicSignals[0], 1, 0, content) userState.stop() }) @@ -177,10 +178,8 @@ describe('Unirep App', function () { epoch, attesterId ) - - const data = await userState.getProvableData() - - const repProof = await genReputationProof({ + const data = randomData() + const { publicSignals, proof } = await genEpochKeyProof({ id, tree, leafIndex, @@ -190,13 +189,8 @@ describe('Unirep App', function () { attesterId, data, }) - await expect( - app.post( - repProof.publicSignals, - repProof.proof, - 'Invalid Epoch' - ) + app.post(publicSignals, proof, 'Invalid Epoch') ).to.be.revertedWithCustomError(app, 'InvalidEpoch') userState.stop() diff --git a/packages/contracts/test/VHelpers.test.ts b/packages/contracts/test/VHelpers.test.ts index cb61c173..288929a6 100644 --- a/packages/contracts/test/VHelpers.test.ts +++ b/packages/contracts/test/VHelpers.test.ts @@ -1,7 +1,7 @@ //@ts-ignore -import { genEpochKey } from '@unirep/utils' -import { expect } from 'chai' import { ethers } from 'hardhat' +import { expect } from 'chai' +import { genEpochKey } from '@unirep/utils' import { describe } from 'node:test' import { deployApp } from '../scripts/utils/deployUnirepSocialTw' import { Unirep, UnirepApp } from '../typechain-types' @@ -15,7 +15,7 @@ import { genReportNullifierCircuitInput, } from './utils' -describe('Verifier Helper Test', function () { +describe('Verifier Helper Manager Test', function () { let unirep: Unirep let app: UnirepApp let reportNonNullifierVHelper: any diff --git a/packages/contracts/test/Verifiers.test.ts b/packages/contracts/test/Verifiers.test.ts index 03734429..80878c53 100644 --- a/packages/contracts/test/Verifiers.test.ts +++ b/packages/contracts/test/Verifiers.test.ts @@ -1,7 +1,7 @@ //@ts-ignore -import { genEpochKey } from '@unirep/utils' -import { expect } from 'chai' import { ethers } from 'hardhat' +import { expect } from 'chai' +import { genEpochKey } from '@unirep/utils' import { describe } from 'node:test' import { deployApp } from '../scripts/utils/deployUnirepSocialTw' import { Unirep, UnirepApp } from '../typechain-types' @@ -15,7 +15,7 @@ import { genReportNullifierCircuitInput, } from './utils' -describe('Verifier Test', function () { +describe('Verifier Helper Manager Test', function () { let unirep: Unirep let app: UnirepApp let reportNonNullifierVerifier diff --git a/packages/contracts/test/utils.ts b/packages/contracts/test/utils.ts index 7f49b761..819163f7 100644 --- a/packages/contracts/test/utils.ts +++ b/packages/contracts/test/utils.ts @@ -163,75 +163,6 @@ export async function genEpochKeyLiteProof(config: { return { publicSignals, proof } } -export async function genReputationProof(config: { - id: Identity - tree: IncrementalMerkleTree - leafIndex: number - data?: bigint[] - graffiti?: any - revealNonce?: number - attesterId: number | bigint - epoch: number - nonce: number - minRep?: number - maxRep?: number - proveZeroRep?: boolean - sigData?: bigint - chainId: number -}) { - const { - id, - tree, - leafIndex, - data, - graffiti, - revealNonce, - attesterId, - epoch, - nonce, - minRep, - maxRep, - proveZeroRep, - sigData, - chainId, - } = Object.assign(config) - - const _proof = tree.createProof(leafIndex) - - const circuitInputs = { - identity_secret: id.secret, - state_tree_indices: _proof.pathIndices, - state_tree_elements: _proof.siblings, - data, - prove_graffiti: graffiti ? 1 : 0, - graffiti: BigInt(graffiti ?? 0), - reveal_nonce: revealNonce ?? 0, - attester_id: attesterId, - epoch, - nonce, - min_rep: minRep ?? 0, - max_rep: maxRep ?? 0, - prove_min_rep: !!(minRep ?? 0) ? 1 : 0, - prove_max_rep: !!(maxRep ?? 0) ? 1 : 0, - prove_zero_rep: proveZeroRep ?? 0, - sig_data: sigData ?? 0, - chain_id: chainId, - } - - const r = await prover.genProofAndPublicSignals( - Circuit.reputation, - circuitInputs - ) - - const { publicSignals, proof } = new ReputationProof( - r.publicSignals, - r.proof, - prover - ) - - return { publicSignals, proof } -} - export const randomData = () => [ ...Array(SUM_FIELD_COUNT) .fill(0) diff --git a/packages/relay/test/checkReputation.test.ts b/packages/relay/test/checkReputation.test.ts index 0f6f7982..9d84ddb7 100644 --- a/packages/relay/test/checkReputation.test.ts +++ b/packages/relay/test/checkReputation.test.ts @@ -80,7 +80,7 @@ describe('CheckReputation', function () { revealNonce: 0, }) - const { publicSignals, proof } = await genProofAndVerify( + const { isValid, publicSignals, proof } = await genProofAndVerify( Circuit.reputation, circuitInputs )