diff --git a/on-chain-verification/contracts/ERC20Verifier.sol b/on-chain-verification/contracts/ERC20Verifier.sol index 506d3f6..5c5ee3a 100644 --- a/on-chain-verification/contracts/ERC20Verifier.sol +++ b/on-chain-verification/contracts/ERC20Verifier.sol @@ -45,10 +45,10 @@ contract ERC20Verifier is ERC20, ZKPVerifier { "proof can not be submitted more than once" ); - // address didn't get airdrop tokens - uint256 id = inputs[validator.getChallengeInputIndex()]; + // get user id + uint256 id = inputs[1]; // additional check didn't get airdrop tokens before - if (idToAddress[id] == address(0)) { + if (idToAddress[id] == address(0) && addressToId[_msgSender()] == 0 ) { super._mint(_msgSender(), TOKEN_AMOUNT_FOR_AIRDROP_PER_ID); addressToId[_msgSender()] = id; idToAddress[id] = _msgSender(); diff --git a/on-chain-verification/contracts/interfaces/IState.sol b/on-chain-verification/contracts/interfaces/IState.sol index e95af7f..679b03d 100644 --- a/on-chain-verification/contracts/interfaces/IState.sol +++ b/on-chain-verification/contracts/interfaces/IState.sol @@ -1,9 +1,13 @@ -pragma solidity ^0.8.0; +// SPDX-License-Identifier: GPL-3.0 +pragma solidity 0.8.16; + +uint256 constant MAX_SMT_DEPTH = 64; interface IState { /** * @dev Struct for public interfaces to represent a state information. - * @param id identity. + * @param id An identity. + * @param state A state. * @param replacedByState A state, which replaced this state for the identity. * @param createdAtTimestamp A time when the state was created. * @param replacedAtTimestamp A time when the state was replaced by the next identity state. @@ -19,16 +23,17 @@ interface IState { uint256 createdAtBlock; uint256 replacedAtBlock; } + /** - * @dev Struct for public interfaces to represent SMT root info. - * @param root This SMT root. + * @dev Struct for public interfaces to represent GIST root information. + * @param root This GIST root. * @param replacedByRoot A root, which replaced this root. * @param createdAtTimestamp A time, when the root was saved to blockchain. * @param replacedAtTimestamp A time, when the root was replaced by the next root in blockchain. * @param createdAtBlock A number of block, when the root was saved to blockchain. * @param replacedAtBlock A number of block, when the root was replaced by the next root in blockchain. */ - struct RootInfo { + struct GistRootInfo { uint256 root; uint256 replacedByRoot; uint256 createdAtTimestamp; @@ -37,25 +42,50 @@ interface IState { uint256 replacedAtBlock; } - function getStateInfoById( - uint256 id - ) external view returns (StateInfo memory); + /** + * @dev Struct for public interfaces to represent GIST proof information. + * @param root This GIST root. + * @param existence A flag, which shows if the leaf index exists in the GIST. + * @param siblings An array of GIST sibling node hashes. + * @param index An index of the leaf in the GIST. + * @param value A value of the leaf in the GIST. + * @param auxExistence A flag, which shows if the auxiliary leaf exists in the GIST. + * @param auxIndex An index of the auxiliary leaf in the GIST. + * @param auxValue An value of the auxiliary leaf in the GIST. + */ + struct GistProof { + uint256 root; + bool existence; + uint256[MAX_SMT_DEPTH] siblings; + uint256 index; + uint256 value; + bool auxExistence; + uint256 auxIndex; + uint256 auxValue; + } /** - * @dev Retrieve the specific GIST root information. - * @param root GIST root - * @return The GIST root info + * @dev Retrieve last state information of specific id. + * @param id An identity. + * @return The state info. */ - function getGISTRootInfo( - uint256 root - ) external view returns (RootInfo memory); + function getStateInfoById(uint256 id) external view returns (StateInfo memory); /** - * @dev Retrieve state information by state. - * @param state A state - * @return The state info + * @dev Retrieve state information by id and state. + * @param id An identity. + * @param state A state. + * @return The state info. */ - function getStateInfoByState( + function getStateInfoByIdAndState( + uint256 id, uint256 state ) external view returns (StateInfo memory); -} + + /** + * @dev Retrieve the specific GIST root information. + * @param root GIST root. + * @return The GIST root info. + */ + function getGISTRootInfo(uint256 root) external view returns (GistRootInfo memory); +} \ No newline at end of file diff --git a/on-chain-verification/contracts/validators/CredentialAtomicQueryMTPValidator.sol b/on-chain-verification/contracts/validators/CredentialAtomicQueryMTPValidator.sol index 32708aa..e3e4835 100644 --- a/on-chain-verification/contracts/validators/CredentialAtomicQueryMTPValidator.sol +++ b/on-chain-verification/contracts/validators/CredentialAtomicQueryMTPValidator.sol @@ -56,7 +56,7 @@ contract CredentialAtomicQueryMTPValidator is OwnableUpgradeable, ICircuitValida uint256 issuerClaimIdenState = inputs[7]; uint256 issuerClaimNonRevState = inputs[9]; - IState.RootInfo memory rootInfo = state.getGISTRootInfo(gistRoot); + IState.GistRootInfo memory rootInfo = state.getGISTRootInfo(gistRoot); require(rootInfo.root == gistRoot, "Gist root state isn't in state contract"); @@ -64,8 +64,8 @@ contract CredentialAtomicQueryMTPValidator is OwnableUpgradeable, ICircuitValida bool isIssuerStateGenesis = GenesisUtils.isGenesisState(issuerId, issuerClaimIdenState); if (!isIssuerStateGenesis) { - IState.StateInfo memory issuerStateInfo = state.getStateInfoByState( - issuerClaimIdenState + IState.StateInfo memory issuerStateInfo = state.getStateInfoByIdAndState( + issuerId, issuerClaimIdenState ); require(issuerId == issuerStateInfo.id, "Issuer state doesn't exist in state contract"); } @@ -80,9 +80,9 @@ contract CredentialAtomicQueryMTPValidator is OwnableUpgradeable, ICircuitValida } else { // The non-empty state is returned, and it's not equal to the state that the user has provided. if (issuerClaimNonRevStateInfo.state != issuerClaimNonRevState) { - // Get the time of the latest state and compare it to the transition time of state provided by the user. + // Get the time of the latest state and compare it to the transition time of state provided by the user. IState.StateInfo memory issuerClaimNonRevLatestStateInfo = state - .getStateInfoByState(issuerClaimNonRevState); + .getStateInfoByIdAndState(issuerId,issuerClaimNonRevState); if ( issuerClaimNonRevLatestStateInfo.id == 0 || @@ -106,4 +106,4 @@ contract CredentialAtomicQueryMTPValidator is OwnableUpgradeable, ICircuitValida return (true); } -} +} \ No newline at end of file diff --git a/on-chain-verification/contracts/validators/CredentialAtomicQuerySigValidator.sol b/on-chain-verification/contracts/validators/CredentialAtomicQuerySigValidator.sol index 1a96798..183e633 100644 --- a/on-chain-verification/contracts/validators/CredentialAtomicQuerySigValidator.sol +++ b/on-chain-verification/contracts/validators/CredentialAtomicQuerySigValidator.sol @@ -54,7 +54,7 @@ contract CredentialAtomicQuerySigValidator is OwnableUpgradeable, ICircuitValida uint256 issuerId = inputs[7]; uint256 issuerClaimNonRevState = inputs[9]; - IState.RootInfo memory rootInfo = state.getGISTRootInfo(gistRoot); + IState.GistRootInfo memory rootInfo = state.getGISTRootInfo(gistRoot); require(rootInfo.root == gistRoot, "Gist root state isn't in state contract"); @@ -62,8 +62,8 @@ contract CredentialAtomicQuerySigValidator is OwnableUpgradeable, ICircuitValida bool isIssuerStateGenesis = GenesisUtils.isGenesisState(issuerId, issuerClaimAuthState); if (!isIssuerStateGenesis) { - IState.StateInfo memory issuerStateInfo = state.getStateInfoByState( - issuerClaimAuthState + IState.StateInfo memory issuerStateInfo = state.getStateInfoByIdAndState( + issuerId, issuerClaimAuthState ); require(issuerId == issuerStateInfo.id, "Issuer state doesn't exist in state contract"); } @@ -80,7 +80,7 @@ contract CredentialAtomicQuerySigValidator is OwnableUpgradeable, ICircuitValida if (issuerClaimNonRevStateInfo.state != issuerClaimNonRevState) { // Get the time of the latest state and compare it to the transition time of state provided by the user. IState.StateInfo memory issuerClaimNonRevLatestStateInfo = state - .getStateInfoByState(issuerClaimNonRevState); + .getStateInfoByIdAndState(issuerId, issuerClaimNonRevState); if ( issuerClaimNonRevLatestStateInfo.id == 0 || diff --git a/on-chain-verification/contracts/verifiers/ZKPVerifier.sol b/on-chain-verification/contracts/verifiers/ZKPVerifier.sol index fe9bdeb..8f11f8e 100644 --- a/on-chain-verification/contracts/verifiers/ZKPVerifier.sol +++ b/on-chain-verification/contracts/verifiers/ZKPVerifier.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "../lib/GenesisUtils.sol"; import "../lib/SpongePoseidon.sol";