@chainlink/ace 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.foundry-version +1 -0
- package/.github/CODEOWNERS +1 -0
- package/.github/workflows/auto-release-version.yml +107 -0
- package/.github/workflows/create-version-pr.yml +95 -0
- package/.github/workflows/forge-docs.yml +90 -0
- package/.github/workflows/forge-test.yml +59 -0
- package/.solhint-test.json +18 -0
- package/.solhint.json +16 -0
- package/.solhintignore +3 -0
- package/.solhintignore-test +2 -0
- package/Glossary.md +141 -0
- package/LICENSE +59 -0
- package/README.md +218 -0
- package/assets/chainlink-logo.svg +21 -0
- package/chainlink-ace-License-grants +2 -0
- package/foundry.toml +33 -0
- package/getting_started/GETTING_STARTED.md +477 -0
- package/getting_started/MyVault.sol +48 -0
- package/getting_started/advanced/.env.example +36 -0
- package/getting_started/advanced/GETTING_STARTED_ADVANCED.md +431 -0
- package/getting_started/advanced/SanctionsList.sol +25 -0
- package/getting_started/advanced/SanctionsPolicy.sol +58 -0
- package/package.json +41 -0
- package/packages/cross-chain-identity/README.md +148 -0
- package/packages/cross-chain-identity/docs/API_GUIDE.md +120 -0
- package/packages/cross-chain-identity/docs/API_REFERENCE.md +271 -0
- package/packages/cross-chain-identity/docs/CONCEPTS.md +253 -0
- package/packages/cross-chain-identity/docs/CREDENTIAL_FLOW.md +195 -0
- package/packages/cross-chain-identity/docs/SECURITY.md +70 -0
- package/packages/cross-chain-identity/src/CredentialRegistry.sol +245 -0
- package/packages/cross-chain-identity/src/CredentialRegistryIdentityValidator.sol +339 -0
- package/packages/cross-chain-identity/src/CredentialRegistryIdentityValidatorPolicy.sol +71 -0
- package/packages/cross-chain-identity/src/IdentityRegistry.sol +123 -0
- package/packages/cross-chain-identity/src/TrustedIssuerRegistry.sol +140 -0
- package/packages/cross-chain-identity/src/interfaces/ICredentialDataValidator.sol +30 -0
- package/packages/cross-chain-identity/src/interfaces/ICredentialRegistry.sol +170 -0
- package/packages/cross-chain-identity/src/interfaces/ICredentialRequirements.sol +192 -0
- package/packages/cross-chain-identity/src/interfaces/ICredentialValidator.sol +37 -0
- package/packages/cross-chain-identity/src/interfaces/IIdentityRegistry.sol +85 -0
- package/packages/cross-chain-identity/src/interfaces/IIdentityValidator.sol +18 -0
- package/packages/cross-chain-identity/src/interfaces/ITrustedIssuerRegistry.sol +61 -0
- package/packages/cross-chain-identity/test/CredentialRegistry.t.sol +220 -0
- package/packages/cross-chain-identity/test/CredentialRegistryIdentityValidator.t.sol +554 -0
- package/packages/cross-chain-identity/test/CredentialRegistryIdentityValidatorPolicy.t.sol +114 -0
- package/packages/cross-chain-identity/test/IdentityRegistry.t.sol +106 -0
- package/packages/cross-chain-identity/test/IdentityValidator.t.sol +969 -0
- package/packages/cross-chain-identity/test/TrustedIssuerRegistry.t.sol +123 -0
- package/packages/cross-chain-identity/test/helpers/BaseProxyTest.sol +112 -0
- package/packages/cross-chain-identity/test/helpers/MockCredentialDataValidator.sol +26 -0
- package/packages/cross-chain-identity/test/helpers/MockCredentialRegistryReverting.sol +131 -0
- package/packages/policy-management/README.md +197 -0
- package/packages/policy-management/docs/API_GUIDE.md +290 -0
- package/packages/policy-management/docs/API_REFERENCE.md +173 -0
- package/packages/policy-management/docs/CONCEPTS.md +156 -0
- package/packages/policy-management/docs/CUSTOM_POLICIES_TUTORIAL.md +195 -0
- package/packages/policy-management/docs/POLICY_ORDERING_GUIDE.md +91 -0
- package/packages/policy-management/docs/SECURITY.md +57 -0
- package/packages/policy-management/src/core/Policy.sol +124 -0
- package/packages/policy-management/src/core/PolicyEngine.sol +382 -0
- package/packages/policy-management/src/core/PolicyFactory.sol +92 -0
- package/packages/policy-management/src/core/PolicyProtected.sol +126 -0
- package/packages/policy-management/src/extractors/ComplianceTokenForceTransferExtractor.sol +57 -0
- package/packages/policy-management/src/extractors/ComplianceTokenFreezeUnfreezeExtractor.sol +54 -0
- package/packages/policy-management/src/extractors/ComplianceTokenMintBurnExtractor.sol +61 -0
- package/packages/policy-management/src/extractors/ERC20ApproveExtractor.sol +57 -0
- package/packages/policy-management/src/extractors/ERC20TransferExtractor.sol +62 -0
- package/packages/policy-management/src/extractors/ERC3643ForcedTransferExtractor.sol +56 -0
- package/packages/policy-management/src/extractors/ERC3643FreezeUnfreezeExtractor.sol +55 -0
- package/packages/policy-management/src/extractors/ERC3643MintBurnExtractor.sol +51 -0
- package/packages/policy-management/src/extractors/ERC3643SetAddressFrozenExtractor.sol +51 -0
- package/packages/policy-management/src/interfaces/IExtractor.sol +17 -0
- package/packages/policy-management/src/interfaces/IMapper.sol +17 -0
- package/packages/policy-management/src/interfaces/IPolicy.sol +61 -0
- package/packages/policy-management/src/interfaces/IPolicyEngine.sol +264 -0
- package/packages/policy-management/src/interfaces/IPolicyProtected.sol +48 -0
- package/packages/policy-management/src/policies/AllowPolicy.sol +104 -0
- package/packages/policy-management/src/policies/BypassPolicy.sol +90 -0
- package/packages/policy-management/src/policies/IntervalPolicy.sol +223 -0
- package/packages/policy-management/src/policies/MaxPolicy.sol +73 -0
- package/packages/policy-management/src/policies/OnlyAuthorizedSenderPolicy.sol +84 -0
- package/packages/policy-management/src/policies/OnlyOwnerPolicy.sol +35 -0
- package/packages/policy-management/src/policies/PausePolicy.sol +82 -0
- package/packages/policy-management/src/policies/README.md +632 -0
- package/packages/policy-management/src/policies/RejectPolicy.sol +89 -0
- package/packages/policy-management/src/policies/RoleBasedAccessControlPolicy.sol +162 -0
- package/packages/policy-management/src/policies/SecureMintPolicy.sol +271 -0
- package/packages/policy-management/src/policies/VolumePolicy.sol +133 -0
- package/packages/policy-management/src/policies/VolumeRatePolicy.sol +192 -0
- package/packages/policy-management/test/PolicyEngine.t.sol +368 -0
- package/packages/policy-management/test/PolicyFactory.t.sol +114 -0
- package/packages/policy-management/test/PolicyProtectedToken.t.sol +75 -0
- package/packages/policy-management/test/extractors/ComplianceTokenForceTransferExtractor.t.sol +59 -0
- package/packages/policy-management/test/extractors/ComplianceTokenFreezeUnfreezeExtractor.t.sol +74 -0
- package/packages/policy-management/test/extractors/ComplianceTokenMintBurnExtractor.t.sol +92 -0
- package/packages/policy-management/test/extractors/ERC20ApproveExtractor.t.sol +58 -0
- package/packages/policy-management/test/extractors/ERC3643ForcedTransferExtractor.t.sol +59 -0
- package/packages/policy-management/test/extractors/ERC3643FreezeUnfreezeExtractor.t.sol +74 -0
- package/packages/policy-management/test/extractors/ERC3643MintBurnExtractor.t.sol +73 -0
- package/packages/policy-management/test/extractors/ERC3643SetAddressFrozenExtractor.t.sol +56 -0
- package/packages/policy-management/test/helpers/BaseProxyTest.sol +75 -0
- package/packages/policy-management/test/helpers/CustomMapper.sol +26 -0
- package/packages/policy-management/test/helpers/DummyExtractor.sol +11 -0
- package/packages/policy-management/test/helpers/ExpectedParameterPolicy.sol +39 -0
- package/packages/policy-management/test/helpers/MockAggregatorV3.sol +51 -0
- package/packages/policy-management/test/helpers/MockToken.sol +66 -0
- package/packages/policy-management/test/helpers/MockTokenExtractor.sol +34 -0
- package/packages/policy-management/test/helpers/PolicyAlwaysAllowed.sol +45 -0
- package/packages/policy-management/test/helpers/PolicyAlwaysContinue.sol +23 -0
- package/packages/policy-management/test/helpers/PolicyAlwaysRejected.sol +23 -0
- package/packages/policy-management/test/helpers/PolicyFailingRun.sol +22 -0
- package/packages/policy-management/test/policies/AllowPolicy.t.sol +174 -0
- package/packages/policy-management/test/policies/BypassPolicy.t.sol +159 -0
- package/packages/policy-management/test/policies/IntervalPolicy.t.sol +307 -0
- package/packages/policy-management/test/policies/MaxPolicy.t.sol +54 -0
- package/packages/policy-management/test/policies/OnlyAuthorizedSenderPolicy.t.sol +95 -0
- package/packages/policy-management/test/policies/OnlyOwnerPolicy.t.sol +47 -0
- package/packages/policy-management/test/policies/PausePolicy.t.sol +75 -0
- package/packages/policy-management/test/policies/RejectPolicy.t.sol +182 -0
- package/packages/policy-management/test/policies/RoleBasedAccessControlPolicy.t.sol +223 -0
- package/packages/policy-management/test/policies/SecureMintPolicy.t.sol +442 -0
- package/packages/policy-management/test/policies/VolumePolicy.t.sol +158 -0
- package/packages/policy-management/test/policies/VolumeRatePolicy.t.sol +165 -0
- package/packages/tokens/erc-20/src/ComplianceTokenERC20.sol +345 -0
- package/packages/tokens/erc-20/src/ComplianceTokenStoreERC20.sol +29 -0
- package/packages/tokens/erc-20/test/ComplianceTokenERC20.t.sol +556 -0
- package/packages/tokens/erc-20/test/helpers/BaseProxyTest.sol +75 -0
- package/packages/tokens/erc-3643/README.md +24 -0
- package/packages/tokens/erc-3643/src/ComplianceTokenERC3643.sol +564 -0
- package/packages/tokens/erc-3643/src/ComplianceTokenStoreERC3643.sol +30 -0
- package/packages/tokens/erc-3643/test/ComplianceTokenERC3643.t.sol +815 -0
- package/packages/tokens/erc-3643/test/helpers/BaseProxyTest.sol +76 -0
- package/packages/tokens/erc-3643/test/helpers/ExpectedContextPolicy.sol +32 -0
- package/packages/vendor/erc-3643/compliance/modular/IModularCompliance.sol +220 -0
- package/packages/vendor/erc-3643/registry/interface/IClaimTopicsRegistry.sol +101 -0
- package/packages/vendor/erc-3643/registry/interface/IIdentityRegistry.sol +251 -0
- package/packages/vendor/erc-3643/registry/interface/IIdentityRegistryStorage.sol +191 -0
- package/packages/vendor/erc-3643/registry/interface/ITrustedIssuersRegistry.sol +161 -0
- package/packages/vendor/erc-3643/token/IToken.sol +457 -0
- package/packages/vendor/onchain-id/interface/IClaimIssuer.sol +53 -0
- package/packages/vendor/onchain-id/interface/IERC734.sol +110 -0
- package/packages/vendor/onchain-id/interface/IERC735.sol +105 -0
- package/packages/vendor/onchain-id/interface/IIdentity.sol +26 -0
- package/packages/vendor/onchain-id/interface/IImplementationAuthority.sol +21 -0
- package/remappings.txt +6 -0
- package/script/DeployComplianceTokenERC20.s.sol +191 -0
- package/script/DeployComplianceTokenERC3643.s.sol +208 -0
- package/script/DeploySimpleComplianceToken.s.sol +38 -0
- package/script/getting_started/DeployGettingStarted.s.sol +74 -0
- package/script/getting_started/advanced/DeployAdvancedGettingStarted.s.sol +332 -0
- package/script/getting_started/advanced/DeploySanctionsList.s.sol +26 -0
|
@@ -0,0 +1,969 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BUSL-1.1
|
|
2
|
+
pragma solidity 0.8.26;
|
|
3
|
+
|
|
4
|
+
import {ICredentialRequirements} from "../src/interfaces/ICredentialRequirements.sol";
|
|
5
|
+
import {ICredentialRegistry} from "../src/interfaces/ICredentialRegistry.sol";
|
|
6
|
+
import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
|
|
7
|
+
import {IdentityRegistry} from "../src/IdentityRegistry.sol";
|
|
8
|
+
import {CredentialRegistry} from "../src/CredentialRegistry.sol";
|
|
9
|
+
import {CredentialRegistryIdentityValidator} from "../src/CredentialRegistryIdentityValidator.sol";
|
|
10
|
+
import {PolicyEngine} from "@chainlink/policy-management/core/PolicyEngine.sol";
|
|
11
|
+
import {MockCredentialDataValidator} from "./helpers/MockCredentialDataValidator.sol";
|
|
12
|
+
import {BaseProxyTest} from "./helpers/BaseProxyTest.sol";
|
|
13
|
+
|
|
14
|
+
contract CredentialRegistryIdentityValidatorTest is BaseProxyTest {
|
|
15
|
+
bytes32 public constant REQUIREMENT_KYC = keccak256("KYC");
|
|
16
|
+
bytes32 public constant REQUIREMENT_ACCREDITED = keccak256("ACCREDITED");
|
|
17
|
+
bytes32 public constant CREDENTIAL_KYC = keccak256("common.kyc");
|
|
18
|
+
bytes32 public constant CREDENTIAL_PEP = keccak256("common.pep");
|
|
19
|
+
bytes32 public constant CREDENTIAL_ACCREDITED = keccak256("common.accredited");
|
|
20
|
+
bytes32 public constant CREDENTIAL_INVALID_NATIONALITY = keccak256("common.invalid.nationality");
|
|
21
|
+
bytes32 public constant CREDENTIAL_BANK_1_KYC = keccak256("com.bank1.KYC");
|
|
22
|
+
bytes32 public constant CREDENTIAL_BANK_2_KYC = keccak256("com.bank2.KYC");
|
|
23
|
+
bytes32 public constant CREDENTIAL_BANK_1_PEP = keccak256("com.bank1.PEP");
|
|
24
|
+
bytes32 public constant CREDENTIAL_BANK_2_PEP = keccak256("com.bank2.PEP");
|
|
25
|
+
bytes32 public constant CREDENTIAL_SOURCE1_COUNTRY_A = keccak256("source1.residence.CountryA");
|
|
26
|
+
bytes32 public constant CREDENTIAL_SOURCE2_COUNTRY_A = keccak256("source2.residence.CountryA");
|
|
27
|
+
bytes32 public constant CREDENTIAL_SOURCE1_COUNTRY_B = keccak256("source1.residence.CountryB");
|
|
28
|
+
bytes32 public constant CREDENTIAL_SOURCE2_COUNTRY_B = keccak256("source2.residence.CountryB");
|
|
29
|
+
bytes32 public constant CREDENTIAL_SOURCE1_COUNTRY_C = keccak256("source1.residence.CountryC");
|
|
30
|
+
bytes32 public constant CREDENTIAL_SOURCE2_COUNTRY_C = keccak256("source2.residence.CountryC");
|
|
31
|
+
bytes32 public constant CREDENTIAL_SOURCE1_COUNTRY_D = keccak256("source1.residence.CountryD");
|
|
32
|
+
bytes32 public constant CREDENTIAL_SOURCE2_COUNTRY_D = keccak256("source2.residence.CountryD");
|
|
33
|
+
bytes32 public constant CREDENTIAL_COMMON_COUNTRY_E = keccak256("common.residence.CountryE");
|
|
34
|
+
bytes32 public constant CREDENTIAL_COMMON_COUNTRY_F = keccak256("common.residence.CountryF");
|
|
35
|
+
bytes32 public constant CREDENTIAL_COMMON_COUNTRY_G = keccak256("common.residence.CountryG");
|
|
36
|
+
|
|
37
|
+
bytes32[] internal s_credentials_kyc;
|
|
38
|
+
bytes32[] internal s_credentials_accredited;
|
|
39
|
+
bytes32[] internal s_credentials_invalid_nationality;
|
|
40
|
+
|
|
41
|
+
PolicyEngine internal s_policyEngine;
|
|
42
|
+
IdentityRegistry internal s_identityRegistry;
|
|
43
|
+
CredentialRegistry internal s_credentialRegistry;
|
|
44
|
+
CredentialRegistryIdentityValidator internal s_identityValidator;
|
|
45
|
+
address internal s_owner;
|
|
46
|
+
|
|
47
|
+
function setUp() public {
|
|
48
|
+
s_owner = makeAddr("owner");
|
|
49
|
+
|
|
50
|
+
vm.startPrank(s_owner);
|
|
51
|
+
|
|
52
|
+
s_credentials_kyc = new bytes32[](1);
|
|
53
|
+
s_credentials_kyc[0] = CREDENTIAL_KYC;
|
|
54
|
+
|
|
55
|
+
s_credentials_accredited = new bytes32[](1);
|
|
56
|
+
s_credentials_accredited[0] = CREDENTIAL_ACCREDITED;
|
|
57
|
+
|
|
58
|
+
s_credentials_invalid_nationality = new bytes32[](1);
|
|
59
|
+
s_credentials_invalid_nationality[0] = CREDENTIAL_INVALID_NATIONALITY;
|
|
60
|
+
|
|
61
|
+
// Deploy PolicyEngine through proxy
|
|
62
|
+
s_policyEngine = _deployPolicyEngine(true, address(this));
|
|
63
|
+
|
|
64
|
+
// Deploy IdentityRegistry through proxy
|
|
65
|
+
s_identityRegistry = _deployIdentityRegistry(address(s_policyEngine));
|
|
66
|
+
|
|
67
|
+
// Deploy CredentialRegistry through proxy
|
|
68
|
+
s_credentialRegistry = _deployCredentialRegistry(address(s_policyEngine));
|
|
69
|
+
|
|
70
|
+
// Deploy CredentialRegistryIdentityValidator through proxy
|
|
71
|
+
s_identityValidator = _deployCredentialRegistryIdentityValidator(
|
|
72
|
+
new ICredentialRequirements.CredentialSourceInput[](0),
|
|
73
|
+
new ICredentialRequirements.CredentialRequirementInput[](0)
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
s_identityValidator.addCredentialRequirement(
|
|
77
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_KYC, s_credentials_kyc, 1, false)
|
|
78
|
+
);
|
|
79
|
+
s_identityValidator.addCredentialSource(
|
|
80
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
81
|
+
CREDENTIAL_KYC, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
82
|
+
)
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function test_validate_success() public {
|
|
87
|
+
address account1 = makeAddr("account1");
|
|
88
|
+
bytes32 ccid = keccak256("account1");
|
|
89
|
+
|
|
90
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
91
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, 0, "", "");
|
|
92
|
+
|
|
93
|
+
assertTrue(s_identityValidator.validate(account1, ""));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function test_validate_altKyc_success() public {
|
|
97
|
+
address account1 = makeAddr("account1");
|
|
98
|
+
bytes32 ccid = keccak256("account1");
|
|
99
|
+
|
|
100
|
+
// switch credentialValidator requirement to be either type of KYC
|
|
101
|
+
s_credentials_kyc = new bytes32[](2);
|
|
102
|
+
s_credentials_kyc[0] = CREDENTIAL_KYC;
|
|
103
|
+
s_credentials_kyc[1] = CREDENTIAL_BANK_2_KYC;
|
|
104
|
+
s_identityValidator.removeCredentialRequirement(REQUIREMENT_KYC);
|
|
105
|
+
s_identityValidator.addCredentialRequirement(
|
|
106
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_KYC, s_credentials_kyc, 1, false)
|
|
107
|
+
);
|
|
108
|
+
// new kyc type can also be validated at the same registry
|
|
109
|
+
s_identityValidator.addCredentialSource(
|
|
110
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
111
|
+
CREDENTIAL_BANK_2_KYC, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
112
|
+
)
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
116
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_BANK_2_KYC, 0, "", "");
|
|
117
|
+
|
|
118
|
+
assertTrue(s_identityValidator.validate(account1, ""));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function test_validate_futureExpires_success() public {
|
|
122
|
+
address account1 = makeAddr("account1");
|
|
123
|
+
bytes32 ccid = keccak256("account1");
|
|
124
|
+
|
|
125
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
126
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, uint40(block.timestamp + 30), "", "");
|
|
127
|
+
|
|
128
|
+
vm.warp(block.timestamp + 10);
|
|
129
|
+
|
|
130
|
+
assertTrue(s_identityValidator.validate(account1, ""));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function test_validate_expired_invalid() public {
|
|
134
|
+
address account1 = makeAddr("account1");
|
|
135
|
+
bytes32 ccid = keccak256("account1");
|
|
136
|
+
|
|
137
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
138
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, uint40(block.timestamp + 2), "", "");
|
|
139
|
+
|
|
140
|
+
vm.warp(block.timestamp + 10);
|
|
141
|
+
|
|
142
|
+
assertFalse(s_identityValidator.validate(account1, ""));
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function test_validate_renew_success() public {
|
|
146
|
+
address account1 = makeAddr("account1");
|
|
147
|
+
bytes32 ccid = keccak256("account1");
|
|
148
|
+
|
|
149
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
150
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, uint40(block.timestamp + 2), "", "");
|
|
151
|
+
|
|
152
|
+
vm.warp(block.timestamp + 10);
|
|
153
|
+
|
|
154
|
+
assertFalse(s_identityValidator.validate(account1, ""));
|
|
155
|
+
|
|
156
|
+
s_credentialRegistry.renewCredential(ccid, CREDENTIAL_KYC, uint40(block.timestamp + 30), "");
|
|
157
|
+
vm.warp(block.timestamp + 10);
|
|
158
|
+
|
|
159
|
+
assertTrue(s_identityValidator.validate(account1, ""));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function test_validate_unknownIdentity_invalid() public {
|
|
163
|
+
address account1 = makeAddr("account1");
|
|
164
|
+
|
|
165
|
+
assertFalse(s_identityValidator.validate(account1, ""));
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function test_validate_missingCredential_invalid() public {
|
|
169
|
+
address account1 = makeAddr("account1");
|
|
170
|
+
bytes32 ccid = keccak256("account1");
|
|
171
|
+
|
|
172
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
173
|
+
|
|
174
|
+
assertFalse(s_identityValidator.validate(account1, ""));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function test_validate_multiSource_success() public {
|
|
178
|
+
address account1 = makeAddr("account1");
|
|
179
|
+
bytes32 ccid = keccak256("account1");
|
|
180
|
+
|
|
181
|
+
s_identityValidator.addCredentialRequirement(
|
|
182
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_ACCREDITED, s_credentials_accredited, 1, false)
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
IdentityRegistry identityRegistry2 = _deployIdentityRegistry(address(s_policyEngine));
|
|
186
|
+
vm.label(address(identityRegistry2), "IdentityRegistry2");
|
|
187
|
+
CredentialRegistry credentialRegistry2 = _deployCredentialRegistry(address(s_policyEngine));
|
|
188
|
+
vm.label(address(credentialRegistry2), "CredentialRegistry2");
|
|
189
|
+
|
|
190
|
+
s_identityValidator.addCredentialSource(
|
|
191
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
192
|
+
CREDENTIAL_ACCREDITED, address(identityRegistry2), address(credentialRegistry2), address(0)
|
|
193
|
+
)
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
197
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, 0, "", "");
|
|
198
|
+
|
|
199
|
+
identityRegistry2.registerIdentity(ccid, account1, "");
|
|
200
|
+
credentialRegistry2.registerCredential(ccid, CREDENTIAL_ACCREDITED, 0, "", "");
|
|
201
|
+
|
|
202
|
+
assertTrue(s_identityValidator.validate(account1, ""));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function test_validate_multiSourceMissingCredential_invalid() public {
|
|
206
|
+
address account1 = makeAddr("account1");
|
|
207
|
+
bytes32 ccid = keccak256("account1");
|
|
208
|
+
|
|
209
|
+
s_identityValidator.addCredentialRequirement(
|
|
210
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_ACCREDITED, s_credentials_accredited, 1, false)
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
IdentityRegistry identityRegistry2 = _deployIdentityRegistry(address(s_policyEngine));
|
|
214
|
+
vm.label(address(identityRegistry2), "IdentityRegistry2");
|
|
215
|
+
CredentialRegistry credentialRegistry2 = _deployCredentialRegistry(address(s_policyEngine));
|
|
216
|
+
vm.label(address(credentialRegistry2), "CredentialRegistry2");
|
|
217
|
+
|
|
218
|
+
s_identityValidator.addCredentialSource(
|
|
219
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
220
|
+
CREDENTIAL_ACCREDITED, address(identityRegistry2), address(credentialRegistry2), address(0)
|
|
221
|
+
)
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
identityRegistry2.registerIdentity(ccid, account1, "");
|
|
225
|
+
credentialRegistry2.registerCredential(ccid, CREDENTIAL_ACCREDITED, 0, "", "");
|
|
226
|
+
|
|
227
|
+
assertFalse(s_identityValidator.validate(account1, ""));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function test_validate_multiSource_multiCredential_success() public {
|
|
231
|
+
address account1 = makeAddr("account1");
|
|
232
|
+
bytes32 ccid = keccak256("account1");
|
|
233
|
+
|
|
234
|
+
s_identityValidator.addCredentialRequirement(
|
|
235
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_ACCREDITED, s_credentials_accredited, 2, false)
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
IdentityRegistry identityRegistry2 = _deployIdentityRegistry(address(s_policyEngine));
|
|
239
|
+
vm.label(address(identityRegistry2), "IdentityRegistry2");
|
|
240
|
+
CredentialRegistry credentialRegistry2 = _deployCredentialRegistry(address(s_policyEngine));
|
|
241
|
+
vm.label(address(credentialRegistry2), "CredentialRegistry2");
|
|
242
|
+
|
|
243
|
+
s_identityValidator.addCredentialSource(
|
|
244
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
245
|
+
CREDENTIAL_ACCREDITED, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
246
|
+
)
|
|
247
|
+
);
|
|
248
|
+
s_identityValidator.addCredentialSource(
|
|
249
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
250
|
+
CREDENTIAL_ACCREDITED, address(identityRegistry2), address(credentialRegistry2), address(0)
|
|
251
|
+
)
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
255
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, 0, "", "");
|
|
256
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_ACCREDITED, 0, "", "");
|
|
257
|
+
|
|
258
|
+
identityRegistry2.registerIdentity(ccid, account1, "");
|
|
259
|
+
credentialRegistry2.registerCredential(ccid, CREDENTIAL_ACCREDITED, 0, "", "");
|
|
260
|
+
|
|
261
|
+
assertTrue(s_identityValidator.validate(account1, ""));
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function test_validate_multiSource_multiCredentialMissing_invalid() public {
|
|
265
|
+
address account1 = makeAddr("account1");
|
|
266
|
+
bytes32 ccid = keccak256("account1");
|
|
267
|
+
|
|
268
|
+
s_identityValidator.addCredentialRequirement(
|
|
269
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_ACCREDITED, s_credentials_accredited, 2, false)
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
IdentityRegistry identityRegistry2 = _deployIdentityRegistry(address(s_policyEngine));
|
|
273
|
+
vm.label(address(identityRegistry2), "IdentityRegistry2");
|
|
274
|
+
CredentialRegistry credentialRegistry2 = _deployCredentialRegistry(address(s_policyEngine));
|
|
275
|
+
vm.label(address(credentialRegistry2), "CredentialRegistry2");
|
|
276
|
+
|
|
277
|
+
s_identityValidator.addCredentialSource(
|
|
278
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
279
|
+
CREDENTIAL_ACCREDITED, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
280
|
+
)
|
|
281
|
+
);
|
|
282
|
+
s_identityValidator.addCredentialSource(
|
|
283
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
284
|
+
CREDENTIAL_ACCREDITED, address(identityRegistry2), address(credentialRegistry2), address(0)
|
|
285
|
+
)
|
|
286
|
+
);
|
|
287
|
+
|
|
288
|
+
// no ACCREDITED credential in this registry
|
|
289
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
290
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, 0, "", "");
|
|
291
|
+
|
|
292
|
+
identityRegistry2.registerIdentity(ccid, account1, "");
|
|
293
|
+
credentialRegistry2.registerCredential(ccid, CREDENTIAL_ACCREDITED, 0, "", "");
|
|
294
|
+
|
|
295
|
+
assertFalse(s_identityValidator.validate(account1, ""));
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function test_credentialRole_success() public {
|
|
299
|
+
bytes32 ccid = keccak256("account1");
|
|
300
|
+
|
|
301
|
+
CredentialRegistry credentialRegistry2 = _deployCredentialRegistry(address(s_policyEngine));
|
|
302
|
+
vm.label(address(credentialRegistry2), "CredentialRegistry2");
|
|
303
|
+
|
|
304
|
+
vm.expectEmit();
|
|
305
|
+
emit ICredentialRegistry.CredentialRegistered(ccid, CREDENTIAL_ACCREDITED, 0, "");
|
|
306
|
+
|
|
307
|
+
credentialRegistry2.registerCredential(ccid, CREDENTIAL_ACCREDITED, 0, "", "");
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
function test_validate_credentialRequirementInvert_invalid() public {
|
|
311
|
+
address account1 = makeAddr("account1");
|
|
312
|
+
bytes32 ccid = keccak256("account1");
|
|
313
|
+
|
|
314
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
315
|
+
|
|
316
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, 0, "", "");
|
|
317
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_INVALID_NATIONALITY, 0, "", "");
|
|
318
|
+
|
|
319
|
+
s_identityValidator.addCredentialRequirement(
|
|
320
|
+
ICredentialRequirements.CredentialRequirementInput(
|
|
321
|
+
CREDENTIAL_INVALID_NATIONALITY, s_credentials_invalid_nationality, 1, true
|
|
322
|
+
)
|
|
323
|
+
);
|
|
324
|
+
s_identityValidator.addCredentialSource(
|
|
325
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
326
|
+
CREDENTIAL_INVALID_NATIONALITY, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
327
|
+
)
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
assertFalse(s_identityValidator.validate(account1, ""));
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function test_validate_credentialRequirementInvertCredentialExists_invalid() public {
|
|
334
|
+
address account1 = makeAddr("account1");
|
|
335
|
+
bytes32 ccid = keccak256("account1");
|
|
336
|
+
|
|
337
|
+
bytes32 requirement = keccak256("mock requirement");
|
|
338
|
+
bytes32[] memory credential_ids = new bytes32[](1);
|
|
339
|
+
credential_ids[0] = keccak256("mock credential type");
|
|
340
|
+
|
|
341
|
+
s_identityValidator.addCredentialRequirement(
|
|
342
|
+
ICredentialRequirements.CredentialRequirementInput(requirement, credential_ids, 1, true)
|
|
343
|
+
);
|
|
344
|
+
s_identityValidator.addCredentialSource(
|
|
345
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
346
|
+
credential_ids[0], address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
347
|
+
)
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
351
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, 0, "", "");
|
|
352
|
+
s_credentialRegistry.registerCredential(ccid, credential_ids[0], 0, abi.encode("mock data"), "");
|
|
353
|
+
|
|
354
|
+
// For inverted credentials: if credential exists in registry, validation fails (no data validation performed)
|
|
355
|
+
assertFalse(s_identityValidator.validate(account1, ""));
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function test_validate_credentialRequirementInvertNotPresent_succeeds() public {
|
|
359
|
+
address account1 = makeAddr("account1");
|
|
360
|
+
bytes32 ccid = keccak256("account1");
|
|
361
|
+
|
|
362
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
363
|
+
|
|
364
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, 0, "", "");
|
|
365
|
+
|
|
366
|
+
s_identityValidator.addCredentialRequirement(
|
|
367
|
+
ICredentialRequirements.CredentialRequirementInput(
|
|
368
|
+
CREDENTIAL_INVALID_NATIONALITY, s_credentials_invalid_nationality, 1, true
|
|
369
|
+
)
|
|
370
|
+
);
|
|
371
|
+
s_identityValidator.addCredentialSource(
|
|
372
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
373
|
+
CREDENTIAL_INVALID_NATIONALITY, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
374
|
+
)
|
|
375
|
+
);
|
|
376
|
+
|
|
377
|
+
assertTrue(s_identityValidator.validate(account1, ""));
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
function test_validate_invertCredentialRequirementNotPresentButOtherCredentialMissing_invalid() public {
|
|
381
|
+
address account1 = makeAddr("account1");
|
|
382
|
+
bytes32 ccid = keccak256("account1");
|
|
383
|
+
|
|
384
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
385
|
+
|
|
386
|
+
s_identityValidator.addCredentialRequirement(
|
|
387
|
+
ICredentialRequirements.CredentialRequirementInput(
|
|
388
|
+
CREDENTIAL_INVALID_NATIONALITY, s_credentials_invalid_nationality, 1, true
|
|
389
|
+
)
|
|
390
|
+
);
|
|
391
|
+
s_identityValidator.addCredentialSource(
|
|
392
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
393
|
+
CREDENTIAL_INVALID_NATIONALITY, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
394
|
+
)
|
|
395
|
+
);
|
|
396
|
+
|
|
397
|
+
assertFalse(s_identityValidator.validate(account1, ""));
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
function test_addCredentialRequirement_zeroMinValidations_invalid() public {
|
|
401
|
+
vm.expectRevert();
|
|
402
|
+
s_identityValidator.addCredentialRequirement(
|
|
403
|
+
ICredentialRequirements.CredentialRequirementInput(
|
|
404
|
+
CREDENTIAL_INVALID_NATIONALITY, s_credentials_invalid_nationality, 0, false
|
|
405
|
+
)
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
function test_getCredentialRequirement_success() public {
|
|
410
|
+
s_credentials_kyc = new bytes32[](2);
|
|
411
|
+
s_credentials_kyc[0] = CREDENTIAL_KYC;
|
|
412
|
+
s_credentials_kyc[1] = CREDENTIAL_BANK_2_KYC;
|
|
413
|
+
s_identityValidator.removeCredentialRequirement(REQUIREMENT_KYC);
|
|
414
|
+
s_identityValidator.addCredentialRequirement(
|
|
415
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_KYC, s_credentials_kyc, 1, false)
|
|
416
|
+
);
|
|
417
|
+
|
|
418
|
+
ICredentialRequirements.CredentialRequirement memory credRequirement =
|
|
419
|
+
s_identityValidator.getCredentialRequirement(REQUIREMENT_KYC);
|
|
420
|
+
assert(credRequirement.minValidations == 1);
|
|
421
|
+
assert(credRequirement.credentialTypeIds[0] == CREDENTIAL_KYC);
|
|
422
|
+
assert(credRequirement.credentialTypeIds[1] == CREDENTIAL_BANK_2_KYC);
|
|
423
|
+
assert(credRequirement.invert == false);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
function test_getCredentialRequirement_duplicated_failure() public {
|
|
427
|
+
s_credentials_kyc = new bytes32[](2);
|
|
428
|
+
s_credentials_kyc[0] = CREDENTIAL_KYC;
|
|
429
|
+
s_credentials_kyc[1] = CREDENTIAL_BANK_2_KYC;
|
|
430
|
+
|
|
431
|
+
vm.expectPartialRevert(ICredentialRequirements.RequirementExists.selector);
|
|
432
|
+
s_identityValidator.addCredentialRequirement(
|
|
433
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_KYC, s_credentials_kyc, 1, false)
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
function test_getCredentialRequirementIds_success() public {
|
|
438
|
+
s_credentials_kyc = new bytes32[](2);
|
|
439
|
+
s_credentials_kyc[0] = CREDENTIAL_KYC;
|
|
440
|
+
s_credentials_kyc[1] = CREDENTIAL_BANK_2_KYC;
|
|
441
|
+
s_identityValidator.removeCredentialRequirement(REQUIREMENT_KYC);
|
|
442
|
+
s_identityValidator.addCredentialRequirement(
|
|
443
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_KYC, s_credentials_kyc, 1, false)
|
|
444
|
+
);
|
|
445
|
+
|
|
446
|
+
bytes32[] memory requirementIds = s_identityValidator.getCredentialRequirementIds();
|
|
447
|
+
assert(requirementIds.length == 1);
|
|
448
|
+
assert(requirementIds[0] == REQUIREMENT_KYC);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
function test_addCredentialSource_success() public {
|
|
452
|
+
s_identityValidator.addCredentialSource(
|
|
453
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
454
|
+
CREDENTIAL_BANK_2_KYC, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
455
|
+
)
|
|
456
|
+
);
|
|
457
|
+
|
|
458
|
+
ICredentialRequirements.CredentialSource[] memory credSourcesBeforeRemoval =
|
|
459
|
+
s_identityValidator.getCredentialSources(CREDENTIAL_BANK_2_KYC);
|
|
460
|
+
assert(credSourcesBeforeRemoval.length == 1);
|
|
461
|
+
|
|
462
|
+
s_identityValidator.removeCredentialSource(
|
|
463
|
+
CREDENTIAL_BANK_2_KYC, address(s_identityRegistry), address(s_credentialRegistry)
|
|
464
|
+
);
|
|
465
|
+
|
|
466
|
+
ICredentialRequirements.CredentialSource[] memory credSourcesAfterRemoval =
|
|
467
|
+
s_identityValidator.getCredentialSources(CREDENTIAL_BANK_2_KYC);
|
|
468
|
+
assert(credSourcesAfterRemoval.length == 0);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
function test_addCredentialSource_duplicated_failure() public {
|
|
472
|
+
s_identityValidator.addCredentialSource(
|
|
473
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
474
|
+
CREDENTIAL_BANK_2_KYC, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
475
|
+
)
|
|
476
|
+
);
|
|
477
|
+
|
|
478
|
+
vm.expectPartialRevert(ICredentialRequirements.SourceExists.selector);
|
|
479
|
+
s_identityValidator.addCredentialSource(
|
|
480
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
481
|
+
CREDENTIAL_BANK_2_KYC, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
482
|
+
)
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
function test_removeCredentialRequirement_notFound_failure() public {
|
|
487
|
+
vm.expectPartialRevert(ICredentialRequirements.RequirementNotFound.selector);
|
|
488
|
+
s_identityValidator.removeCredentialRequirement(keccak256("unknown"));
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
function test_removeCredentialSource_notFound_failure() public {
|
|
492
|
+
vm.expectPartialRevert(ICredentialRequirements.CredentialSourceNotFound.selector);
|
|
493
|
+
s_identityValidator.removeCredentialSource(
|
|
494
|
+
CREDENTIAL_BANK_2_KYC, address(s_identityRegistry), address(s_credentialRegistry)
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
function test_requireKYC_and_rejectPEP() public {
|
|
499
|
+
CredentialRegistryIdentityValidator validator = _deployCredentialRegistryIdentityValidator(
|
|
500
|
+
new ICredentialRequirements.CredentialSourceInput[](0),
|
|
501
|
+
new ICredentialRequirements.CredentialRequirementInput[](0)
|
|
502
|
+
);
|
|
503
|
+
|
|
504
|
+
IdentityRegistry identityReg = _deployIdentityRegistry(address(s_policyEngine));
|
|
505
|
+
CredentialRegistry credentialReg = _deployCredentialRegistry(address(s_policyEngine));
|
|
506
|
+
|
|
507
|
+
bytes32[] memory kycCredentials = new bytes32[](1);
|
|
508
|
+
kycCredentials[0] = CREDENTIAL_KYC;
|
|
509
|
+
bytes32 REQUIREMENT_REQUIRE_KYC = keccak256("Require to have KYC");
|
|
510
|
+
|
|
511
|
+
validator.addCredentialSource(
|
|
512
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
513
|
+
CREDENTIAL_KYC, address(identityReg), address(credentialReg), address(0)
|
|
514
|
+
)
|
|
515
|
+
);
|
|
516
|
+
|
|
517
|
+
validator.addCredentialRequirement(
|
|
518
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_REQUIRE_KYC, kycCredentials, 1, false)
|
|
519
|
+
);
|
|
520
|
+
|
|
521
|
+
bytes32[] memory pepCredentials = new bytes32[](1);
|
|
522
|
+
pepCredentials[0] = CREDENTIAL_PEP;
|
|
523
|
+
bytes32 REQUIREMENT_REJECT_PEP = keccak256("Reject if PEP");
|
|
524
|
+
|
|
525
|
+
validator.addCredentialSource(
|
|
526
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
527
|
+
CREDENTIAL_PEP, address(identityReg), address(credentialReg), address(0)
|
|
528
|
+
)
|
|
529
|
+
);
|
|
530
|
+
|
|
531
|
+
validator.addCredentialRequirement(
|
|
532
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_REJECT_PEP, pepCredentials, 1, true)
|
|
533
|
+
);
|
|
534
|
+
|
|
535
|
+
address user1 = makeAddr("user1");
|
|
536
|
+
address user2 = makeAddr("user2");
|
|
537
|
+
address user3 = makeAddr("user3");
|
|
538
|
+
bytes32 ccid1 = keccak256("user1");
|
|
539
|
+
bytes32 ccid2 = keccak256("user2");
|
|
540
|
+
bytes32 ccid3 = keccak256("user3");
|
|
541
|
+
|
|
542
|
+
// User has KYC but is PEP, should fail
|
|
543
|
+
identityReg.registerIdentity(ccid1, user1, "");
|
|
544
|
+
credentialReg.registerCredential(ccid1, CREDENTIAL_KYC, 0, "", "");
|
|
545
|
+
credentialReg.registerCredential(ccid1, CREDENTIAL_PEP, 0, "", "");
|
|
546
|
+
assertFalse(validator.validate(user1, ""), "User with KYC but is PEP should fail");
|
|
547
|
+
|
|
548
|
+
// User has KYC and is not PEP, should pass
|
|
549
|
+
identityReg.registerIdentity(ccid2, user2, "");
|
|
550
|
+
credentialReg.registerCredential(ccid2, CREDENTIAL_KYC, 0, "", "");
|
|
551
|
+
assertTrue(validator.validate(user2, ""), "User with KYC and not PEP should pass");
|
|
552
|
+
|
|
553
|
+
// User is not PEP but has no KYC, should fail
|
|
554
|
+
identityReg.registerIdentity(ccid3, user3, "");
|
|
555
|
+
assertFalse(validator.validate(user3, ""), "User without KYC should fail even if not PEP");
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/// Same logical credential, multiple sources, whitelist
|
|
559
|
+
/// Accept if user has KYC in any listed bank
|
|
560
|
+
/// Config: One requirement. credentialTypeIds = [com.bank1.KYC, com.bank2.KYC], invert = false, minValidations = 1
|
|
561
|
+
function test_sameLogicalCredential_multilpleSources_whitelist() public {
|
|
562
|
+
CredentialRegistryIdentityValidator validator = _deployCredentialRegistryIdentityValidator(
|
|
563
|
+
new ICredentialRequirements.CredentialSourceInput[](0),
|
|
564
|
+
new ICredentialRequirements.CredentialRequirementInput[](0)
|
|
565
|
+
);
|
|
566
|
+
|
|
567
|
+
IdentityRegistry bank1IdentityRegistry = _deployIdentityRegistry(address(s_policyEngine));
|
|
568
|
+
vm.label(address(bank1IdentityRegistry), "Bank1IdentityRegistry");
|
|
569
|
+
CredentialRegistry bank1CredentialRegistry = _deployCredentialRegistry(address(s_policyEngine));
|
|
570
|
+
vm.label(address(bank1CredentialRegistry), "Bank1CredentialRegistry");
|
|
571
|
+
|
|
572
|
+
IdentityRegistry bank2IdentityRegistry = _deployIdentityRegistry(address(s_policyEngine));
|
|
573
|
+
vm.label(address(bank2IdentityRegistry), "Bank2IdentityRegistry");
|
|
574
|
+
CredentialRegistry bank2CredentialRegistry = _deployCredentialRegistry(address(s_policyEngine));
|
|
575
|
+
vm.label(address(bank2CredentialRegistry), "Bank2CredentialRegistry");
|
|
576
|
+
|
|
577
|
+
bytes32[] memory kycCredentials = new bytes32[](2);
|
|
578
|
+
kycCredentials[0] = CREDENTIAL_BANK_1_KYC;
|
|
579
|
+
kycCredentials[1] = CREDENTIAL_BANK_2_KYC;
|
|
580
|
+
|
|
581
|
+
bytes32 REQUIREMENT_REQUIRE_ANY_KYC = keccak256("Require KYC from Bank 1 or Bank 2");
|
|
582
|
+
|
|
583
|
+
validator.addCredentialSource(
|
|
584
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
585
|
+
CREDENTIAL_BANK_1_KYC, address(bank1IdentityRegistry), address(bank1CredentialRegistry), address(0)
|
|
586
|
+
)
|
|
587
|
+
);
|
|
588
|
+
validator.addCredentialSource(
|
|
589
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
590
|
+
CREDENTIAL_BANK_2_KYC, address(bank2IdentityRegistry), address(bank2CredentialRegistry), address(0)
|
|
591
|
+
)
|
|
592
|
+
);
|
|
593
|
+
|
|
594
|
+
validator.addCredentialRequirement(
|
|
595
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_REQUIRE_ANY_KYC, kycCredentials, 1, false)
|
|
596
|
+
);
|
|
597
|
+
|
|
598
|
+
address user1 = makeAddr("user1");
|
|
599
|
+
address user2 = makeAddr("user2");
|
|
600
|
+
address user3 = makeAddr("user3");
|
|
601
|
+
bytes32 ccid1 = keccak256("user1");
|
|
602
|
+
bytes32 ccid2 = keccak256("user2");
|
|
603
|
+
bytes32 ccid3 = keccak256("user3");
|
|
604
|
+
|
|
605
|
+
//User has KYC only from 1, should pass
|
|
606
|
+
bank1IdentityRegistry.registerIdentity(ccid1, user1, "");
|
|
607
|
+
bank1CredentialRegistry.registerCredential(ccid1, CREDENTIAL_BANK_1_KYC, 0, "", "");
|
|
608
|
+
assertTrue(validator.validate(user1, ""), "User with only Bank 1 KYC should pass");
|
|
609
|
+
|
|
610
|
+
// User has KYC only from Bank 2, should pass
|
|
611
|
+
bank2IdentityRegistry.registerIdentity(ccid2, user2, "");
|
|
612
|
+
bank2CredentialRegistry.registerCredential(ccid2, CREDENTIAL_BANK_2_KYC, 0, "", "");
|
|
613
|
+
assertTrue(validator.validate(user2, ""), "User with only Bank 2 KYC should pass");
|
|
614
|
+
|
|
615
|
+
// User has KYC from both, should pass
|
|
616
|
+
bank1IdentityRegistry.registerIdentity(ccid3, user3, "");
|
|
617
|
+
bank1CredentialRegistry.registerCredential(ccid3, CREDENTIAL_BANK_1_KYC, 0, "", "");
|
|
618
|
+
bank2IdentityRegistry.registerIdentity(ccid3, user3, "");
|
|
619
|
+
bank2CredentialRegistry.registerCredential(ccid3, CREDENTIAL_BANK_2_KYC, 0, "", "");
|
|
620
|
+
assertTrue(validator.validate(user3, ""), "User with both Bank 1 and Bank 2 KYC should pass");
|
|
621
|
+
|
|
622
|
+
// User has no KYC, should fail
|
|
623
|
+
address user4 = makeAddr("user4");
|
|
624
|
+
assertFalse(validator.validate(user4, ""), "User with no KYC should fail");
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
function test_sameLogicalCredential_multilpleSources_whitelist_bothSourcesRequired() public {
|
|
628
|
+
CredentialRegistryIdentityValidator validator = _deployCredentialRegistryIdentityValidator(
|
|
629
|
+
new ICredentialRequirements.CredentialSourceInput[](0),
|
|
630
|
+
new ICredentialRequirements.CredentialRequirementInput[](0)
|
|
631
|
+
);
|
|
632
|
+
|
|
633
|
+
IdentityRegistry bank1IdentityRegistry = _deployIdentityRegistry(address(s_policyEngine));
|
|
634
|
+
vm.label(address(bank1IdentityRegistry), "Bank1IdentityRegistry");
|
|
635
|
+
CredentialRegistry bank1CredentialRegistry = _deployCredentialRegistry(address(s_policyEngine));
|
|
636
|
+
vm.label(address(bank1CredentialRegistry), "Bank1CredentialRegistry");
|
|
637
|
+
|
|
638
|
+
IdentityRegistry bank2IdentityRegistry = _deployIdentityRegistry(address(s_policyEngine));
|
|
639
|
+
vm.label(address(bank2IdentityRegistry), "Bank2IdentityRegistry");
|
|
640
|
+
CredentialRegistry bank2CredentialRegistry = _deployCredentialRegistry(address(s_policyEngine));
|
|
641
|
+
vm.label(address(bank2CredentialRegistry), "Bank2CredentialRegistry");
|
|
642
|
+
|
|
643
|
+
bytes32[] memory kycCredentials = new bytes32[](2);
|
|
644
|
+
kycCredentials[0] = CREDENTIAL_BANK_1_KYC;
|
|
645
|
+
kycCredentials[1] = CREDENTIAL_BANK_2_KYC;
|
|
646
|
+
|
|
647
|
+
bytes32 REQUIREMENT_REQUIRE_BOTH_KYCs = keccak256("Require KYC from Bank 1 and Bank 2");
|
|
648
|
+
|
|
649
|
+
validator.addCredentialSource(
|
|
650
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
651
|
+
CREDENTIAL_BANK_1_KYC, address(bank1IdentityRegistry), address(bank1CredentialRegistry), address(0)
|
|
652
|
+
)
|
|
653
|
+
);
|
|
654
|
+
validator.addCredentialSource(
|
|
655
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
656
|
+
CREDENTIAL_BANK_2_KYC, address(bank2IdentityRegistry), address(bank2CredentialRegistry), address(0)
|
|
657
|
+
)
|
|
658
|
+
);
|
|
659
|
+
|
|
660
|
+
validator.addCredentialRequirement(
|
|
661
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_REQUIRE_BOTH_KYCs, kycCredentials, 2, false)
|
|
662
|
+
);
|
|
663
|
+
|
|
664
|
+
address user1 = makeAddr("user1");
|
|
665
|
+
address user2 = makeAddr("user2");
|
|
666
|
+
bytes32 ccid1 = keccak256("user1");
|
|
667
|
+
bytes32 ccid2 = keccak256("user2");
|
|
668
|
+
|
|
669
|
+
// User has KYC only from Bank 1, should fail
|
|
670
|
+
bank1IdentityRegistry.registerIdentity(ccid1, user1, "");
|
|
671
|
+
bank1CredentialRegistry.registerCredential(ccid1, CREDENTIAL_BANK_1_KYC, 0, "", "");
|
|
672
|
+
assertFalse(validator.validate(user1, ""), "User with only 1 source should fail when minValidations = 2");
|
|
673
|
+
|
|
674
|
+
// User has KYC from both Bank 1 and Bank 2, should pass
|
|
675
|
+
bank1IdentityRegistry.registerIdentity(ccid2, user2, "");
|
|
676
|
+
bank1CredentialRegistry.registerCredential(ccid2, CREDENTIAL_BANK_1_KYC, 0, "", "");
|
|
677
|
+
bank2IdentityRegistry.registerIdentity(ccid2, user2, "");
|
|
678
|
+
bank2CredentialRegistry.registerCredential(ccid2, CREDENTIAL_BANK_2_KYC, 0, "", "");
|
|
679
|
+
assertTrue(validator.validate(user2, ""), "User with 2 sources should pass when minValidations = 2");
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
/// Denylist across multiple sources
|
|
683
|
+
/// Reject if user is PEP in any source
|
|
684
|
+
/// Config: One requirement. credentialTypeIds = [bank1.PEP, bank2.PEP], invert = true, minValidations = 2
|
|
685
|
+
function test_denylistWithMultipleSources_mustBeCleanInAllSources() public {
|
|
686
|
+
CredentialRegistryIdentityValidator validator = _deployCredentialRegistryIdentityValidator(
|
|
687
|
+
new ICredentialRequirements.CredentialSourceInput[](0),
|
|
688
|
+
new ICredentialRequirements.CredentialRequirementInput[](0)
|
|
689
|
+
);
|
|
690
|
+
|
|
691
|
+
IdentityRegistry bank1IdentityRegistry = _deployIdentityRegistry(address(s_policyEngine));
|
|
692
|
+
vm.label(address(bank1IdentityRegistry), "Bank1IdentityRegistry");
|
|
693
|
+
CredentialRegistry bank1CredentialRegistry = _deployCredentialRegistry(address(s_policyEngine));
|
|
694
|
+
vm.label(address(bank1CredentialRegistry), "Bank1CredentialRegistry");
|
|
695
|
+
|
|
696
|
+
IdentityRegistry bank2IdentityRegistry = _deployIdentityRegistry(address(s_policyEngine));
|
|
697
|
+
vm.label(address(bank2IdentityRegistry), "Bank2IdentityRegistry");
|
|
698
|
+
CredentialRegistry bank2CredentialRegistry = _deployCredentialRegistry(address(s_policyEngine));
|
|
699
|
+
vm.label(address(bank2CredentialRegistry), "Bank2CredentialRegistry");
|
|
700
|
+
|
|
701
|
+
bytes32[] memory pepCredentials = new bytes32[](2);
|
|
702
|
+
pepCredentials[0] = CREDENTIAL_BANK_1_PEP;
|
|
703
|
+
pepCredentials[1] = CREDENTIAL_BANK_2_PEP;
|
|
704
|
+
|
|
705
|
+
bytes32 REQUIREMENT_NOT_PEP = keccak256("Require not to have PEP");
|
|
706
|
+
|
|
707
|
+
validator.addCredentialSource(
|
|
708
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
709
|
+
CREDENTIAL_BANK_1_PEP, address(bank1IdentityRegistry), address(bank1CredentialRegistry), address(0)
|
|
710
|
+
)
|
|
711
|
+
);
|
|
712
|
+
validator.addCredentialSource(
|
|
713
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
714
|
+
CREDENTIAL_BANK_2_PEP, address(bank2IdentityRegistry), address(bank2CredentialRegistry), address(0)
|
|
715
|
+
)
|
|
716
|
+
);
|
|
717
|
+
|
|
718
|
+
validator.addCredentialRequirement(
|
|
719
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_NOT_PEP, pepCredentials, 2, true)
|
|
720
|
+
);
|
|
721
|
+
|
|
722
|
+
address user1 = makeAddr("user1");
|
|
723
|
+
address user2 = makeAddr("user2");
|
|
724
|
+
address user3 = makeAddr("user3");
|
|
725
|
+
address user4 = makeAddr("user4");
|
|
726
|
+
bytes32 ccid1 = keccak256("user1");
|
|
727
|
+
bytes32 ccid2 = keccak256("user2");
|
|
728
|
+
bytes32 ccid3 = keccak256("user3");
|
|
729
|
+
bytes32 ccid4 = keccak256("user4");
|
|
730
|
+
|
|
731
|
+
// User is PEP in Bank 1, should fail
|
|
732
|
+
bank1IdentityRegistry.registerIdentity(ccid1, user1, "");
|
|
733
|
+
bank1CredentialRegistry.registerCredential(ccid1, CREDENTIAL_BANK_1_PEP, 0, "", "");
|
|
734
|
+
bank2IdentityRegistry.registerIdentity(ccid1, user1, "");
|
|
735
|
+
assertFalse(validator.validate(user1, ""), "User who is PEP in Bank 1 should fail");
|
|
736
|
+
|
|
737
|
+
// User is PEP in Bank 2, should fail
|
|
738
|
+
bank1IdentityRegistry.registerIdentity(ccid2, user2, "");
|
|
739
|
+
bank2IdentityRegistry.registerIdentity(ccid2, user2, "");
|
|
740
|
+
bank2CredentialRegistry.registerCredential(ccid2, CREDENTIAL_BANK_2_PEP, 0, "", "");
|
|
741
|
+
assertFalse(validator.validate(user2, ""), "User who is PEP in Bank 2 should fail");
|
|
742
|
+
|
|
743
|
+
// User is PEP in both, should fail
|
|
744
|
+
bank1IdentityRegistry.registerIdentity(ccid3, user3, "");
|
|
745
|
+
bank1CredentialRegistry.registerCredential(ccid3, CREDENTIAL_BANK_1_PEP, 0, "", "");
|
|
746
|
+
bank2IdentityRegistry.registerIdentity(ccid3, user3, "");
|
|
747
|
+
bank2CredentialRegistry.registerCredential(ccid3, CREDENTIAL_BANK_2_PEP, 0, "", "");
|
|
748
|
+
assertFalse(validator.validate(user3, ""), "User who is PEP in both should fail");
|
|
749
|
+
|
|
750
|
+
// User is not PEP in either source, should pass
|
|
751
|
+
bank1IdentityRegistry.registerIdentity(ccid4, user4, "");
|
|
752
|
+
bank2IdentityRegistry.registerIdentity(ccid4, user4, "");
|
|
753
|
+
assertTrue(validator.validate(user4, ""), "User who is not PEP in any source should pass");
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
/// Jurisdiction whitelist
|
|
757
|
+
/// User must belong to any allowed residence
|
|
758
|
+
/// Config: One requirement. credentialTypeIds = [common.residence.CountryE, common.residence.CountryF,
|
|
759
|
+
/// common.residence.CountryG], invert = false, minValidations = 1
|
|
760
|
+
function test_jurisdictionWhitelist_ifOneCredentialIsPresentItMustSucceed() public {
|
|
761
|
+
CredentialRegistryIdentityValidator validator = _deployCredentialRegistryIdentityValidator(
|
|
762
|
+
new ICredentialRequirements.CredentialSourceInput[](0),
|
|
763
|
+
new ICredentialRequirements.CredentialRequirementInput[](0)
|
|
764
|
+
);
|
|
765
|
+
|
|
766
|
+
IdentityRegistry identityReg = _deployIdentityRegistry(address(s_policyEngine));
|
|
767
|
+
CredentialRegistry credentialReg = _deployCredentialRegistry(address(s_policyEngine));
|
|
768
|
+
|
|
769
|
+
bytes32[] memory jurisdictionCredentials = new bytes32[](3);
|
|
770
|
+
jurisdictionCredentials[0] = CREDENTIAL_COMMON_COUNTRY_E;
|
|
771
|
+
jurisdictionCredentials[1] = CREDENTIAL_COMMON_COUNTRY_F;
|
|
772
|
+
jurisdictionCredentials[2] = CREDENTIAL_COMMON_COUNTRY_G;
|
|
773
|
+
|
|
774
|
+
bytes32 REQUIREMENT_REQUIRE_ANY_JURISDICTION = keccak256("Require any of the allowed jurisdictions");
|
|
775
|
+
|
|
776
|
+
validator.addCredentialSource(
|
|
777
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
778
|
+
CREDENTIAL_COMMON_COUNTRY_E, address(identityReg), address(credentialReg), address(0)
|
|
779
|
+
)
|
|
780
|
+
);
|
|
781
|
+
validator.addCredentialSource(
|
|
782
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
783
|
+
CREDENTIAL_COMMON_COUNTRY_F, address(identityReg), address(credentialReg), address(0)
|
|
784
|
+
)
|
|
785
|
+
);
|
|
786
|
+
validator.addCredentialSource(
|
|
787
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
788
|
+
CREDENTIAL_COMMON_COUNTRY_G, address(identityReg), address(credentialReg), address(0)
|
|
789
|
+
)
|
|
790
|
+
);
|
|
791
|
+
|
|
792
|
+
validator.addCredentialRequirement(
|
|
793
|
+
ICredentialRequirements.CredentialRequirementInput(
|
|
794
|
+
REQUIREMENT_REQUIRE_ANY_JURISDICTION, jurisdictionCredentials, 1, false
|
|
795
|
+
)
|
|
796
|
+
);
|
|
797
|
+
|
|
798
|
+
address user1 = makeAddr("user1");
|
|
799
|
+
address user2 = makeAddr("user2");
|
|
800
|
+
address user3 = makeAddr("user3");
|
|
801
|
+
bytes32 ccid1 = keccak256("user1");
|
|
802
|
+
bytes32 ccid2 = keccak256("user2");
|
|
803
|
+
bytes32 ccid3 = keccak256("user3");
|
|
804
|
+
|
|
805
|
+
// User is CountryE resident, should pass
|
|
806
|
+
identityReg.registerIdentity(ccid1, user1, "");
|
|
807
|
+
credentialReg.registerCredential(ccid1, CREDENTIAL_COMMON_COUNTRY_E, 0, "", "");
|
|
808
|
+
assertTrue(validator.validate(user1, ""), "CountryE resident should pass");
|
|
809
|
+
|
|
810
|
+
// User is CountryF resident, should pass
|
|
811
|
+
identityReg.registerIdentity(ccid2, user2, "");
|
|
812
|
+
credentialReg.registerCredential(ccid2, CREDENTIAL_COMMON_COUNTRY_F, 0, "", "");
|
|
813
|
+
assertTrue(validator.validate(user2, ""), "CountryF resident should pass");
|
|
814
|
+
|
|
815
|
+
// User is CountryG resident, should pass
|
|
816
|
+
identityReg.registerIdentity(ccid3, user3, "");
|
|
817
|
+
credentialReg.registerCredential(ccid3, CREDENTIAL_COMMON_COUNTRY_G, 0, "", "");
|
|
818
|
+
assertTrue(validator.validate(user3, ""), "CountryG resident should pass");
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
/// Jurisdiction denylist
|
|
822
|
+
/// User must not be in any of the banned jurisdictions
|
|
823
|
+
/// Config: One requirement per jurisdiction, each with its own sources
|
|
824
|
+
/// For CountryA: credentialTypeIds = [source1.CountryA, source2.CountryA], invert = true, minValidations = 2
|
|
825
|
+
/// And so on for each banned jurisdiction...
|
|
826
|
+
function test_jurisdictionDenylist_mustNotBeInAnyOfTheBannedJurisdictions() public {
|
|
827
|
+
CredentialRegistryIdentityValidator validator = _deployCredentialRegistryIdentityValidator(
|
|
828
|
+
new ICredentialRequirements.CredentialSourceInput[](0),
|
|
829
|
+
new ICredentialRequirements.CredentialRequirementInput[](0)
|
|
830
|
+
);
|
|
831
|
+
|
|
832
|
+
IdentityRegistry source1IdentityReg = _deployIdentityRegistry(address(s_policyEngine));
|
|
833
|
+
vm.label(address(source1IdentityReg), "Source1IdentityRegistry");
|
|
834
|
+
CredentialRegistry source1CredentialReg = _deployCredentialRegistry(address(s_policyEngine));
|
|
835
|
+
vm.label(address(source1CredentialReg), "Source1CredentialRegistry");
|
|
836
|
+
|
|
837
|
+
IdentityRegistry source2IdentityReg = _deployIdentityRegistry(address(s_policyEngine));
|
|
838
|
+
vm.label(address(source2IdentityReg), "Source2IdentityRegistry");
|
|
839
|
+
CredentialRegistry source2CredentialReg = _deployCredentialRegistry(address(s_policyEngine));
|
|
840
|
+
vm.label(address(source2CredentialReg), "Source2CredentialRegistry");
|
|
841
|
+
|
|
842
|
+
bytes32[] memory countryACredentials = new bytes32[](2);
|
|
843
|
+
countryACredentials[0] = CREDENTIAL_SOURCE1_COUNTRY_A;
|
|
844
|
+
countryACredentials[1] = CREDENTIAL_SOURCE2_COUNTRY_A;
|
|
845
|
+
|
|
846
|
+
bytes32 REQUIREMENT_NOT_COUNTRY_A = keccak256("Require not to be CountryA resident");
|
|
847
|
+
|
|
848
|
+
validator.addCredentialSource(
|
|
849
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
850
|
+
CREDENTIAL_SOURCE1_COUNTRY_A, address(source1IdentityReg), address(source1CredentialReg), address(0)
|
|
851
|
+
)
|
|
852
|
+
);
|
|
853
|
+
validator.addCredentialSource(
|
|
854
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
855
|
+
CREDENTIAL_SOURCE2_COUNTRY_A, address(source2IdentityReg), address(source2CredentialReg), address(0)
|
|
856
|
+
)
|
|
857
|
+
);
|
|
858
|
+
|
|
859
|
+
validator.addCredentialRequirement(
|
|
860
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_NOT_COUNTRY_A, countryACredentials, 2, true)
|
|
861
|
+
);
|
|
862
|
+
|
|
863
|
+
bytes32[] memory countryBCredentials = new bytes32[](2);
|
|
864
|
+
countryBCredentials[0] = CREDENTIAL_SOURCE1_COUNTRY_B;
|
|
865
|
+
countryBCredentials[1] = CREDENTIAL_SOURCE2_COUNTRY_B;
|
|
866
|
+
|
|
867
|
+
bytes32 REQUIREMENT_NOT_COUNTRY_B = keccak256("Require not to be CountryB resident");
|
|
868
|
+
|
|
869
|
+
validator.addCredentialSource(
|
|
870
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
871
|
+
CREDENTIAL_SOURCE1_COUNTRY_B, address(source1IdentityReg), address(source1CredentialReg), address(0)
|
|
872
|
+
)
|
|
873
|
+
);
|
|
874
|
+
validator.addCredentialSource(
|
|
875
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
876
|
+
CREDENTIAL_SOURCE2_COUNTRY_B, address(source2IdentityReg), address(source2CredentialReg), address(0)
|
|
877
|
+
)
|
|
878
|
+
);
|
|
879
|
+
|
|
880
|
+
validator.addCredentialRequirement(
|
|
881
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_NOT_COUNTRY_B, countryBCredentials, 2, true)
|
|
882
|
+
);
|
|
883
|
+
|
|
884
|
+
bytes32[] memory countryCCredentials = new bytes32[](2);
|
|
885
|
+
countryCCredentials[0] = CREDENTIAL_SOURCE1_COUNTRY_C;
|
|
886
|
+
countryCCredentials[1] = CREDENTIAL_SOURCE2_COUNTRY_C;
|
|
887
|
+
|
|
888
|
+
bytes32 REQUIREMENT_NOT_COUNTRY_C = keccak256("Require not to be CountryC resident");
|
|
889
|
+
|
|
890
|
+
validator.addCredentialSource(
|
|
891
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
892
|
+
CREDENTIAL_SOURCE1_COUNTRY_C, address(source1IdentityReg), address(source1CredentialReg), address(0)
|
|
893
|
+
)
|
|
894
|
+
);
|
|
895
|
+
|
|
896
|
+
validator.addCredentialSource(
|
|
897
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
898
|
+
CREDENTIAL_SOURCE2_COUNTRY_C, address(source2IdentityReg), address(source2CredentialReg), address(0)
|
|
899
|
+
)
|
|
900
|
+
);
|
|
901
|
+
|
|
902
|
+
validator.addCredentialRequirement(
|
|
903
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_NOT_COUNTRY_C, countryCCredentials, 2, true)
|
|
904
|
+
);
|
|
905
|
+
|
|
906
|
+
bytes32[] memory countryDCredentials = new bytes32[](2);
|
|
907
|
+
countryDCredentials[0] = CREDENTIAL_SOURCE1_COUNTRY_D;
|
|
908
|
+
countryDCredentials[1] = CREDENTIAL_SOURCE2_COUNTRY_D;
|
|
909
|
+
|
|
910
|
+
bytes32 REQUIREMENT_NOT_COUNTRY_D = keccak256("Require not to be CountryD resident");
|
|
911
|
+
|
|
912
|
+
validator.addCredentialSource(
|
|
913
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
914
|
+
CREDENTIAL_SOURCE1_COUNTRY_D, address(source1IdentityReg), address(source1CredentialReg), address(0)
|
|
915
|
+
)
|
|
916
|
+
);
|
|
917
|
+
|
|
918
|
+
validator.addCredentialSource(
|
|
919
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
920
|
+
CREDENTIAL_SOURCE2_COUNTRY_D, address(source2IdentityReg), address(source2CredentialReg), address(0)
|
|
921
|
+
)
|
|
922
|
+
);
|
|
923
|
+
|
|
924
|
+
validator.addCredentialRequirement(
|
|
925
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_NOT_COUNTRY_D, countryDCredentials, 2, true)
|
|
926
|
+
);
|
|
927
|
+
|
|
928
|
+
address user1 = makeAddr("user1");
|
|
929
|
+
address user2 = makeAddr("user2");
|
|
930
|
+
address user3 = makeAddr("user3");
|
|
931
|
+
address user4 = makeAddr("user4");
|
|
932
|
+
address user5 = makeAddr("user5");
|
|
933
|
+
bytes32 ccid1 = keccak256("user1");
|
|
934
|
+
bytes32 ccid2 = keccak256("user2");
|
|
935
|
+
bytes32 ccid3 = keccak256("user3");
|
|
936
|
+
bytes32 ccid4 = keccak256("user4");
|
|
937
|
+
bytes32 ccid5 = keccak256("user5");
|
|
938
|
+
|
|
939
|
+
// User is CountryA resident in source1, should fail
|
|
940
|
+
source1IdentityReg.registerIdentity(ccid1, user1, "");
|
|
941
|
+
source1CredentialReg.registerCredential(ccid1, CREDENTIAL_SOURCE1_COUNTRY_A, 0, "", "");
|
|
942
|
+
source2IdentityReg.registerIdentity(ccid1, user1, "");
|
|
943
|
+
assertFalse(validator.validate(user1, ""), "CountryA resident should fail");
|
|
944
|
+
|
|
945
|
+
// User is CountryB resident in source2, should fail
|
|
946
|
+
source1IdentityReg.registerIdentity(ccid2, user2, "");
|
|
947
|
+
source2IdentityReg.registerIdentity(ccid2, user2, "");
|
|
948
|
+
source2CredentialReg.registerCredential(ccid2, CREDENTIAL_SOURCE2_COUNTRY_B, 0, "", "");
|
|
949
|
+
assertFalse(validator.validate(user2, ""), "CountryB resident should fail");
|
|
950
|
+
|
|
951
|
+
// User is CountryC resident in both sources, should fail
|
|
952
|
+
source1IdentityReg.registerIdentity(ccid3, user3, "");
|
|
953
|
+
source1CredentialReg.registerCredential(ccid3, CREDENTIAL_SOURCE1_COUNTRY_C, 0, "", "");
|
|
954
|
+
source2IdentityReg.registerIdentity(ccid3, user3, "");
|
|
955
|
+
source2CredentialReg.registerCredential(ccid3, CREDENTIAL_SOURCE2_COUNTRY_C, 0, "", "");
|
|
956
|
+
assertFalse(validator.validate(user3, ""), "CountryC resident should fail");
|
|
957
|
+
|
|
958
|
+
// User is CountryD resident in source1, should fail
|
|
959
|
+
source1IdentityReg.registerIdentity(ccid4, user4, "");
|
|
960
|
+
source1CredentialReg.registerCredential(ccid4, CREDENTIAL_SOURCE1_COUNTRY_D, 0, "", "");
|
|
961
|
+
source2IdentityReg.registerIdentity(ccid4, user4, "");
|
|
962
|
+
assertFalse(validator.validate(user4, ""), "CountryD resident should fail");
|
|
963
|
+
|
|
964
|
+
// User is not in banned jurisdictions, should PASS
|
|
965
|
+
source1IdentityReg.registerIdentity(ccid5, user5, "");
|
|
966
|
+
source2IdentityReg.registerIdentity(ccid5, user5, "");
|
|
967
|
+
assertTrue(validator.validate(user5, ""), "Clean user should pass");
|
|
968
|
+
}
|
|
969
|
+
}
|