Skip to content

Commit 1b31462

Browse files
authored
Merge pull request #9 from 0xPolygonID/fix/fix-genesis-state
Fixed behaviour for genesis revocation state
2 parents be6e0eb + b9f0df5 commit 1b31462

2 files changed

Lines changed: 141 additions & 71 deletions

File tree

contracts/validators/CredentialAtomicQueryMTPValidator.sol

Lines changed: 69 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@ import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Own
55
import {GenesisUtils} from "@iden3/contracts/lib/GenesisUtils.sol";
66
import {ICircuitValidator} from "@iden3/contracts/interfaces/ICircuitValidator.sol";
77
import {IVerifier} from "@iden3/contracts/interfaces/IVerifier.sol";
8-
import {IState} from "@iden3/contracts/interfaces/IState.sol";
8+
import {StateV2} from "@iden3/contracts/state/StateV2.sol";
99

10-
contract CredentialAtomicQueryMTPValidator is OwnableUpgradeable, ICircuitValidator {
10+
contract CredentialAtomicQueryMTPValidator is
11+
OwnableUpgradeable,
12+
ICircuitValidator
13+
{
1114
string constant CIRCUIT_ID = "credentialAtomicQueryMTPV2OnChain";
1215
uint256 constant CHALLENGE_INDEX = 4;
1316

1417
IVerifier public verifier;
15-
IState public state;
18+
StateV2 public state;
1619

1720
uint256 public revocationStateExpirationTime;
1821
uint256 public proofGenerationExpirationTime;
@@ -24,15 +27,22 @@ contract CredentialAtomicQueryMTPValidator is OwnableUpgradeable, ICircuitValida
2427
revocationStateExpirationTime = 1 hours;
2528
proofGenerationExpirationTime = 1 hours;
2629
verifier = IVerifier(_verifierContractAddr);
27-
state = IState(_stateContractAddr);
30+
state = StateV2(_stateContractAddr);
2831
__Ownable_init();
2932
}
3033

31-
function setRevocationStateExpirationTime(uint256 expirationTime) public onlyOwner {
34+
function setRevocationStateExpirationTime(uint256 expirationTime)
35+
public
36+
onlyOwner
37+
{
3238
revocationStateExpirationTime = expirationTime;
3339
}
3440

35-
function setProofGenerationExpirationTime(uint256 expirationTime) public virtual onlyOwner {
41+
function setProofGenerationExpirationTime(uint256 expirationTime)
42+
public
43+
virtual
44+
onlyOwner
45+
{
3646
proofGenerationExpirationTime = expirationTime;
3747
}
3848

@@ -52,9 +62,15 @@ contract CredentialAtomicQueryMTPValidator is OwnableUpgradeable, ICircuitValida
5262
uint256 queryHash
5363
) external view returns (bool r) {
5464
// verify that zkp is valid
55-
require(verifier.verifyProof(a, b, c, inputs), "MTP proof is not valid");
65+
require(
66+
verifier.verifyProof(a, b, c, inputs),
67+
"MTP proof is not valid"
68+
);
5669

57-
require(inputs[2] == queryHash, "query hash does not match the requested one");
70+
require(
71+
inputs[2] == queryHash,
72+
"query hash does not match the requested one"
73+
);
5874

5975
// verify user states
6076
uint256 gistRoot = inputs[5];
@@ -63,58 +79,77 @@ contract CredentialAtomicQueryMTPValidator is OwnableUpgradeable, ICircuitValida
6379
uint256 issuerClaimNonRevState = inputs[9];
6480
uint256 proofGenerationTimestamp = inputs[10];
6581

66-
IState.GistRootInfo memory rootInfo = state.getGISTRootInfo(gistRoot);
82+
StateV2.GistRootInfo memory rootInfo = state.getGISTRootInfo(gistRoot);
6783

68-
require(rootInfo.root == gistRoot, "Gist root state isn't in state contract");
84+
require(
85+
rootInfo.root == gistRoot,
86+
"Gist root state isn't in state contract"
87+
);
6988

70-
// 2. Issuer state must be registered in state contracts or be genesis
71-
bool isIssuerStateGenesis = GenesisUtils.isGenesisState(issuerId, issuerClaimIdenState);
89+
// Issuer issuance state must be registered in state contracts or be genesis
90+
bool isIssuerStateGenesis = GenesisUtils.isGenesisState(
91+
issuerId,
92+
issuerClaimIdenState
93+
);
7294

7395
if (!isIssuerStateGenesis) {
74-
IState.StateInfo memory issuerStateInfo = state.getStateInfoByIdAndState(
75-
issuerId, issuerClaimIdenState
96+
StateV2.StateInfo memory issuerStateInfo = state
97+
.getStateInfoByIdAndState(issuerId, issuerClaimIdenState);
98+
require(
99+
issuerId == issuerStateInfo.id,
100+
"Issuer state doesn't exist in state contract"
76101
);
77-
require(issuerId == issuerStateInfo.id, "Issuer state doesn't exist in state contract");
78102
}
79103

80-
IState.StateInfo memory issuerClaimNonRevStateInfo = state.getStateInfoById(issuerId);
104+
// check if identity transited any state in contract
105+
bool idExists = state.idExists(issuerId);
81106

82-
if (issuerClaimNonRevStateInfo.state == 0) {
107+
// if identity didn't transit any state it must be genesis
108+
if (!idExists) {
109+
bool isIssuerRevocationStateGenesis = GenesisUtils.isGenesisState(
110+
issuerId,
111+
issuerClaimNonRevState
112+
);
83113
require(
84-
GenesisUtils.isGenesisState(issuerId, issuerClaimNonRevState),
85-
"Non-Revocation state isn't in state contract and not genesis"
114+
isIssuerRevocationStateGenesis,
115+
"Issuer revocation state doesn't exist in state contract and is not genesis "
86116
);
87117
} else {
88-
// The non-empty state is returned, and it's not equal to the state that the user has provided.
89-
if (issuerClaimNonRevStateInfo.state != issuerClaimNonRevState) {
118+
StateV2.StateInfo memory issuerLatestStateInfo = state
119+
.getStateInfoById(issuerId);
120+
if (issuerLatestStateInfo.state != issuerClaimNonRevState) {
90121
// Get the time of the latest state and compare it to the transition time of state provided by the user.
91-
IState.StateInfo memory issuerClaimNonRevLatestStateInfo = state
92-
.getStateInfoByIdAndState(issuerId,issuerClaimNonRevState);
122+
StateV2.StateInfo memory issuerClaimNonRevStateInfo = state
123+
.getStateInfoByIdAndState(issuerId, issuerClaimNonRevState);
93124

94125
if (
95-
issuerClaimNonRevLatestStateInfo.id == 0 ||
96-
issuerClaimNonRevLatestStateInfo.id != issuerId
126+
issuerClaimNonRevStateInfo.id == 0 ||
127+
issuerClaimNonRevStateInfo.id != issuerId
97128
) {
98129
revert("state in transition info contains invalid id");
99130
}
100131

101-
if (issuerClaimNonRevLatestStateInfo.replacedAtTimestamp == 0) {
102-
revert("Non-Latest state doesn't contain replacement information");
132+
if (issuerClaimNonRevStateInfo.replacedAtTimestamp == 0) {
133+
revert(
134+
"Non-Latest state doesn't contain replacement information"
135+
);
103136
}
104137

105138
if (
106-
block.timestamp - issuerClaimNonRevLatestStateInfo.replacedAtTimestamp >
139+
block.timestamp -
140+
issuerClaimNonRevStateInfo.replacedAtTimestamp >
107141
revocationStateExpirationTime
108142
) {
109143
revert("Non-Revocation state of Issuer expired");
110144
}
111-
112-
if (block.timestamp - proofGenerationTimestamp > proofGenerationExpirationTime) {
113-
revert("Generated proof is outdated");
114-
}
115145
}
116146
}
117-
147+
if (
148+
block.timestamp - proofGenerationTimestamp >
149+
proofGenerationExpirationTime
150+
) {
151+
revert("Generated proof is outdated");
152+
}
118153
return (true);
119154
}
120-
}
155+
}

contracts/validators/CredentialAtomicQuerySigValidator.sol

Lines changed: 72 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@ import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Own
55
import {GenesisUtils} from "@iden3/contracts/lib/GenesisUtils.sol";
66
import {ICircuitValidator} from "@iden3/contracts/interfaces/ICircuitValidator.sol";
77
import {IVerifier} from "@iden3/contracts/interfaces/IVerifier.sol";
8-
import {IState} from "@iden3/contracts/interfaces/IState.sol";
8+
import {StateV2} from "@iden3/contracts/state/StateV2.sol";
99

10-
contract CredentialAtomicQuerySigValidator is OwnableUpgradeable, ICircuitValidator {
10+
contract CredentialAtomicQuerySigValidator is
11+
OwnableUpgradeable,
12+
ICircuitValidator
13+
{
1114
string constant CIRCUIT_ID = "credentialAtomicQuerySigV2OnChain";
1215
uint256 constant CHALLENGE_INDEX = 5;
1316

1417
IVerifier public verifier;
15-
IState public state;
18+
StateV2 public state;
1619

1720
uint256 public revocationStateExpirationTime;
1821
uint256 public proofGenerationExpirationTime;
@@ -24,15 +27,22 @@ contract CredentialAtomicQuerySigValidator is OwnableUpgradeable, ICircuitValida
2427
revocationStateExpirationTime = 1 hours;
2528
proofGenerationExpirationTime = 1 hours;
2629
verifier = IVerifier(_verifierContractAddr);
27-
state = IState(_stateContractAddr);
30+
state = StateV2(_stateContractAddr);
2831
__Ownable_init();
2932
}
3033

31-
function setRevocationStateExpirationTime(uint256 expirationTime) public onlyOwner {
34+
function setRevocationStateExpirationTime(uint256 expirationTime)
35+
public
36+
onlyOwner
37+
{
3238
revocationStateExpirationTime = expirationTime;
3339
}
3440

35-
function setProofGenerationExpirationTime(uint256 expirationTime) public virtual onlyOwner {
41+
function setProofGenerationExpirationTime(uint256 expirationTime)
42+
public
43+
virtual
44+
onlyOwner
45+
{
3646
proofGenerationExpirationTime = expirationTime;
3747
}
3848

@@ -52,67 +62,92 @@ contract CredentialAtomicQuerySigValidator is OwnableUpgradeable, ICircuitValida
5262
uint256 queryHash
5363
) external view returns (bool r) {
5464
// verify that zkp is valid
55-
require(verifier.verifyProof(a, b, c, inputs), "atomic query signature proof is not valid");
56-
require(inputs[2] == queryHash, "query hash does not match the requested one");
65+
require(
66+
verifier.verifyProof(a, b, c, inputs),
67+
"atomic query signature proof is not valid"
68+
);
69+
require(
70+
inputs[2] == queryHash,
71+
"query hash does not match the requested one"
72+
);
5773

5874
uint256 issuerClaimAuthState = inputs[3];
5975
uint256 gistRoot = inputs[6];
6076
uint256 issuerId = inputs[7];
6177
uint256 issuerClaimNonRevState = inputs[9];
6278
uint256 proofGenerationTimestamp = inputs[10];
6379

64-
IState.GistRootInfo memory rootInfo = state.getGISTRootInfo(gistRoot);
80+
StateV2.GistRootInfo memory rootInfo = state.getGISTRootInfo(gistRoot);
6581

66-
require(rootInfo.root == gistRoot, "Gist root state isn't in state contract");
82+
require(
83+
rootInfo.root == gistRoot,
84+
"Gist root state isn't in state contract"
85+
);
6786

68-
// 2. Issuer state must be registered in state contracts or be genesis
69-
bool isIssuerStateGenesis = GenesisUtils.isGenesisState(issuerId, issuerClaimAuthState);
87+
// Issuer auth claim issuance must be registered in state contracts or be genesis
88+
bool isIssuerStateGenesis = GenesisUtils.isGenesisState(
89+
issuerId,
90+
issuerClaimAuthState
91+
);
7092

7193
if (!isIssuerStateGenesis) {
72-
IState.StateInfo memory issuerStateInfo = state.getStateInfoByIdAndState(
73-
issuerId, issuerClaimAuthState
94+
StateV2.StateInfo memory issuerStateInfo = state
95+
.getStateInfoByIdAndState(issuerId, issuerClaimAuthState);
96+
require(
97+
issuerId == issuerStateInfo.id,
98+
"Issuer state doesn't exist in state contract"
7499
);
75-
require(issuerId == issuerStateInfo.id, "Issuer state doesn't exist in state contract");
76100
}
77-
78-
IState.StateInfo memory issuerClaimNonRevStateInfo = state.getStateInfoById(issuerId);
79-
80-
if (issuerClaimNonRevStateInfo.state == 0) {
101+
// check if identity transited any state in contract
102+
bool idExists = state.idExists(issuerId);
103+
104+
// if identity didn't transit any state it must be genesis
105+
if (!idExists) {
106+
bool isIssuerRevocationStateGenesis = GenesisUtils.isGenesisState(
107+
issuerId,
108+
issuerClaimNonRevState
109+
);
81110
require(
82-
GenesisUtils.isGenesisState(issuerId, issuerClaimNonRevState),
83-
"Non-Revocation state isn't in state contract and not genesis"
111+
isIssuerRevocationStateGenesis,
112+
"Issuer revocation state doesn't exist in state contract and is not genesis "
84113
);
85114
} else {
86-
// The non-empty state is returned, and it's not equal to the state that the user has provided.
87-
if (issuerClaimNonRevStateInfo.state != issuerClaimNonRevState) {
88-
// Get the time of the latest state and compare it to the transition time of state provided by the user.
89-
IState.StateInfo memory issuerClaimNonRevLatestStateInfo = state
90-
.getStateInfoByIdAndState(issuerId, issuerClaimNonRevState);
115+
StateV2.StateInfo memory issuerLatestStateInfo = state
116+
.getStateInfoById(issuerId);
117+
if (issuerLatestStateInfo.state != issuerClaimNonRevState) {
118+
// Get the time of the latest state and compare it to the transition time of state provided by the user.
119+
StateV2.StateInfo memory issuerClaimNonRevStateInfo = state
120+
.getStateInfoByIdAndState(issuerId, issuerClaimNonRevState);
91121

92122
if (
93-
issuerClaimNonRevLatestStateInfo.id == 0 ||
94-
issuerClaimNonRevLatestStateInfo.id != issuerId
123+
issuerClaimNonRevStateInfo.id == 0 ||
124+
issuerClaimNonRevStateInfo.id != issuerId
95125
) {
96126
revert("state in transition info contains invalid id");
97127
}
98128

99-
if (issuerClaimNonRevLatestStateInfo.replacedAtTimestamp == 0) {
100-
revert("Non-Latest state doesn't contain replacement information");
129+
if (issuerClaimNonRevStateInfo.replacedAtTimestamp == 0) {
130+
revert(
131+
"Non-Latest state doesn't contain replacement information"
132+
);
101133
}
102134

103135
if (
104-
block.timestamp - issuerClaimNonRevLatestStateInfo.replacedAtTimestamp >
136+
block.timestamp -
137+
issuerClaimNonRevStateInfo.replacedAtTimestamp >
105138
revocationStateExpirationTime
106139
) {
107140
revert("Non-Revocation state of Issuer expired");
108141
}
109-
110-
if (block.timestamp - proofGenerationTimestamp > proofGenerationExpirationTime) {
111-
revert("Generated proof is outdated");
112-
}
113-
114142
}
115143
}
144+
145+
if (
146+
block.timestamp - proofGenerationTimestamp >
147+
proofGenerationExpirationTime
148+
) {
149+
revert("Generated proof is outdated");
150+
}
116151
return (true);
117152
}
118-
}
153+
}

0 commit comments

Comments
 (0)