@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,554 @@
|
|
|
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 {MockCredentialRegistryReverting} from "./helpers/MockCredentialRegistryReverting.sol";
|
|
13
|
+
import {BaseProxyTest} from "./helpers/BaseProxyTest.sol";
|
|
14
|
+
|
|
15
|
+
contract CredentialRegistryIdentityValidatorTest is BaseProxyTest {
|
|
16
|
+
bytes32 public constant REQUIREMENT_KYC = keccak256("KYC");
|
|
17
|
+
bytes32 public constant REQUIREMENT_ACCREDITED = keccak256("ACCREDITED");
|
|
18
|
+
bytes32 public constant CREDENTIAL_KYC = keccak256("common.kyc");
|
|
19
|
+
bytes32 public constant CREDENTIAL_ACCREDITED = keccak256("common.accredited");
|
|
20
|
+
bytes32 public constant CREDENTIAL_INVALID_NATIONALITY = keccak256("common.invalid.nationality");
|
|
21
|
+
|
|
22
|
+
bytes32[] internal s_credentials_kyc;
|
|
23
|
+
bytes32[] internal s_credentials_accredited;
|
|
24
|
+
bytes32[] internal s_credentials_invalid_nationality;
|
|
25
|
+
|
|
26
|
+
PolicyEngine internal s_policyEngine;
|
|
27
|
+
IdentityRegistry internal s_identityRegistry;
|
|
28
|
+
CredentialRegistry internal s_credentialRegistry;
|
|
29
|
+
CredentialRegistryIdentityValidator internal s_identityValidator;
|
|
30
|
+
address internal s_owner;
|
|
31
|
+
|
|
32
|
+
function setUp() public {
|
|
33
|
+
s_owner = makeAddr("owner");
|
|
34
|
+
|
|
35
|
+
vm.startPrank(s_owner);
|
|
36
|
+
|
|
37
|
+
s_credentials_kyc = new bytes32[](1);
|
|
38
|
+
s_credentials_kyc[0] = CREDENTIAL_KYC;
|
|
39
|
+
|
|
40
|
+
s_credentials_accredited = new bytes32[](1);
|
|
41
|
+
s_credentials_accredited[0] = CREDENTIAL_ACCREDITED;
|
|
42
|
+
|
|
43
|
+
s_credentials_invalid_nationality = new bytes32[](1);
|
|
44
|
+
s_credentials_invalid_nationality[0] = CREDENTIAL_INVALID_NATIONALITY;
|
|
45
|
+
|
|
46
|
+
// Deploy PolicyEngine through proxy
|
|
47
|
+
s_policyEngine = _deployPolicyEngine(true, address(this));
|
|
48
|
+
|
|
49
|
+
// Deploy IdentityRegistry through proxy
|
|
50
|
+
s_identityRegistry = _deployIdentityRegistry(address(s_policyEngine));
|
|
51
|
+
|
|
52
|
+
// Deploy CredentialRegistry through proxy
|
|
53
|
+
s_credentialRegistry = _deployCredentialRegistry(address(s_policyEngine));
|
|
54
|
+
|
|
55
|
+
// Deploy CredentialRegistryIdentityValidator through proxy
|
|
56
|
+
s_identityValidator = _deployCredentialRegistryIdentityValidator(
|
|
57
|
+
new ICredentialRequirements.CredentialSourceInput[](0),
|
|
58
|
+
new ICredentialRequirements.CredentialRequirementInput[](0)
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
s_identityValidator.addCredentialRequirement(
|
|
62
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_KYC, s_credentials_kyc, 1, false)
|
|
63
|
+
);
|
|
64
|
+
s_identityValidator.addCredentialSource(
|
|
65
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
66
|
+
CREDENTIAL_KYC, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
67
|
+
)
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function test_validate_success() public {
|
|
72
|
+
address account1 = makeAddr("account1");
|
|
73
|
+
bytes32 ccid = keccak256("account1");
|
|
74
|
+
|
|
75
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
76
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, 0, "", "");
|
|
77
|
+
|
|
78
|
+
assertTrue(s_identityValidator.validate(account1, ""));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function test_validate_altKyc_success() public {
|
|
82
|
+
address account1 = makeAddr("account1");
|
|
83
|
+
bytes32 ccid = keccak256("account1");
|
|
84
|
+
|
|
85
|
+
bytes32 CREDENTIAL_BANK2_KYC = keccak256("com.bank2.kyc");
|
|
86
|
+
|
|
87
|
+
// switch credentialValidator requirement to be either type of KYC
|
|
88
|
+
s_credentials_kyc = new bytes32[](2);
|
|
89
|
+
s_credentials_kyc[0] = CREDENTIAL_KYC;
|
|
90
|
+
s_credentials_kyc[1] = CREDENTIAL_BANK2_KYC;
|
|
91
|
+
s_identityValidator.removeCredentialRequirement(REQUIREMENT_KYC);
|
|
92
|
+
s_identityValidator.addCredentialRequirement(
|
|
93
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_KYC, s_credentials_kyc, 1, false)
|
|
94
|
+
);
|
|
95
|
+
// new kyc type can also be validated at the same registry
|
|
96
|
+
s_identityValidator.addCredentialSource(
|
|
97
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
98
|
+
CREDENTIAL_BANK2_KYC, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
99
|
+
)
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
103
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_BANK2_KYC, 0, "", "");
|
|
104
|
+
|
|
105
|
+
assertTrue(s_identityValidator.validate(account1, ""));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function test_validate_futureExpires_success() public {
|
|
109
|
+
address account1 = makeAddr("account1");
|
|
110
|
+
bytes32 ccid = keccak256("account1");
|
|
111
|
+
|
|
112
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
113
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, uint40(block.timestamp + 30), "", "");
|
|
114
|
+
|
|
115
|
+
vm.warp(block.timestamp + 10);
|
|
116
|
+
|
|
117
|
+
assertTrue(s_identityValidator.validate(account1, ""));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function test_validate_expired_invalid() public {
|
|
121
|
+
address account1 = makeAddr("account1");
|
|
122
|
+
bytes32 ccid = keccak256("account1");
|
|
123
|
+
|
|
124
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
125
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, uint40(block.timestamp + 2), "", "");
|
|
126
|
+
|
|
127
|
+
vm.warp(block.timestamp + 10);
|
|
128
|
+
|
|
129
|
+
assertFalse(s_identityValidator.validate(account1, ""));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function test_validate_renew_success() public {
|
|
133
|
+
address account1 = makeAddr("account1");
|
|
134
|
+
bytes32 ccid = keccak256("account1");
|
|
135
|
+
|
|
136
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
137
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, uint40(block.timestamp + 2), "", "");
|
|
138
|
+
|
|
139
|
+
vm.warp(block.timestamp + 10);
|
|
140
|
+
|
|
141
|
+
assertFalse(s_identityValidator.validate(account1, ""));
|
|
142
|
+
|
|
143
|
+
s_credentialRegistry.renewCredential(ccid, CREDENTIAL_KYC, uint40(block.timestamp + 30), "");
|
|
144
|
+
vm.warp(block.timestamp + 10);
|
|
145
|
+
|
|
146
|
+
assertTrue(s_identityValidator.validate(account1, ""));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function test_validate_unknownIdentity_invalid() public {
|
|
150
|
+
address account1 = makeAddr("account1");
|
|
151
|
+
|
|
152
|
+
assertFalse(s_identityValidator.validate(account1, ""));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function test_validate_missingCredential_invalid() public {
|
|
156
|
+
address account1 = makeAddr("account1");
|
|
157
|
+
bytes32 ccid = keccak256("account1");
|
|
158
|
+
|
|
159
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
160
|
+
|
|
161
|
+
assertFalse(s_identityValidator.validate(account1, ""));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function test_validate_multiSource_success() public {
|
|
165
|
+
address account1 = makeAddr("account1");
|
|
166
|
+
bytes32 ccid = keccak256("account1");
|
|
167
|
+
|
|
168
|
+
s_identityValidator.addCredentialRequirement(
|
|
169
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_ACCREDITED, s_credentials_accredited, 1, false)
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
IdentityRegistry identityRegistry2 = _deployIdentityRegistry(address(s_policyEngine));
|
|
173
|
+
vm.label(address(identityRegistry2), "IdentityRegistry2");
|
|
174
|
+
CredentialRegistry credentialRegistry2 = _deployCredentialRegistry(address(s_policyEngine));
|
|
175
|
+
vm.label(address(credentialRegistry2), "CredentialRegistry2");
|
|
176
|
+
|
|
177
|
+
s_identityValidator.addCredentialSource(
|
|
178
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
179
|
+
CREDENTIAL_ACCREDITED, address(identityRegistry2), address(credentialRegistry2), address(0)
|
|
180
|
+
)
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
184
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, 0, "", "");
|
|
185
|
+
|
|
186
|
+
identityRegistry2.registerIdentity(ccid, account1, "");
|
|
187
|
+
credentialRegistry2.registerCredential(ccid, CREDENTIAL_ACCREDITED, 0, "", "");
|
|
188
|
+
|
|
189
|
+
assertTrue(s_identityValidator.validate(account1, ""));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function test_validate_multiSourceMissingCredential_invalid() public {
|
|
193
|
+
address account1 = makeAddr("account1");
|
|
194
|
+
bytes32 ccid = keccak256("account1");
|
|
195
|
+
|
|
196
|
+
s_identityValidator.addCredentialRequirement(
|
|
197
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_ACCREDITED, s_credentials_accredited, 1, false)
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
IdentityRegistry identityRegistry2 = _deployIdentityRegistry(address(s_policyEngine));
|
|
201
|
+
vm.label(address(identityRegistry2), "IdentityRegistry2");
|
|
202
|
+
CredentialRegistry credentialRegistry2 = _deployCredentialRegistry(address(s_policyEngine));
|
|
203
|
+
vm.label(address(credentialRegistry2), "CredentialRegistry2");
|
|
204
|
+
|
|
205
|
+
s_identityValidator.addCredentialSource(
|
|
206
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
207
|
+
CREDENTIAL_ACCREDITED, address(identityRegistry2), address(credentialRegistry2), address(0)
|
|
208
|
+
)
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
identityRegistry2.registerIdentity(ccid, account1, "");
|
|
212
|
+
credentialRegistry2.registerCredential(ccid, CREDENTIAL_ACCREDITED, 0, "", "");
|
|
213
|
+
|
|
214
|
+
assertFalse(s_identityValidator.validate(account1, ""));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function test_validate_multiSource_multiCredential_success() public {
|
|
218
|
+
address account1 = makeAddr("account1");
|
|
219
|
+
bytes32 ccid = keccak256("account1");
|
|
220
|
+
|
|
221
|
+
s_identityValidator.addCredentialRequirement(
|
|
222
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_ACCREDITED, s_credentials_accredited, 2, false)
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
IdentityRegistry identityRegistry2 = _deployIdentityRegistry(address(s_policyEngine));
|
|
226
|
+
vm.label(address(identityRegistry2), "IdentityRegistry2");
|
|
227
|
+
CredentialRegistry credentialRegistry2 = _deployCredentialRegistry(address(s_policyEngine));
|
|
228
|
+
vm.label(address(credentialRegistry2), "CredentialRegistry2");
|
|
229
|
+
|
|
230
|
+
s_identityValidator.addCredentialSource(
|
|
231
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
232
|
+
CREDENTIAL_ACCREDITED, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
233
|
+
)
|
|
234
|
+
);
|
|
235
|
+
s_identityValidator.addCredentialSource(
|
|
236
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
237
|
+
CREDENTIAL_ACCREDITED, address(identityRegistry2), address(credentialRegistry2), address(0)
|
|
238
|
+
)
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
242
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, 0, "", "");
|
|
243
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_ACCREDITED, 0, "", "");
|
|
244
|
+
|
|
245
|
+
identityRegistry2.registerIdentity(ccid, account1, "");
|
|
246
|
+
credentialRegistry2.registerCredential(ccid, CREDENTIAL_ACCREDITED, 0, "", "");
|
|
247
|
+
|
|
248
|
+
assertTrue(s_identityValidator.validate(account1, ""));
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function test_validate_multiSource_multiCredentialMissing_invalid() public {
|
|
252
|
+
address account1 = makeAddr("account1");
|
|
253
|
+
bytes32 ccid = keccak256("account1");
|
|
254
|
+
|
|
255
|
+
s_identityValidator.addCredentialRequirement(
|
|
256
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_ACCREDITED, s_credentials_accredited, 2, false)
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
IdentityRegistry identityRegistry2 = _deployIdentityRegistry(address(s_policyEngine));
|
|
260
|
+
vm.label(address(identityRegistry2), "IdentityRegistry2");
|
|
261
|
+
CredentialRegistry credentialRegistry2 = _deployCredentialRegistry(address(s_policyEngine));
|
|
262
|
+
vm.label(address(credentialRegistry2), "CredentialRegistry2");
|
|
263
|
+
|
|
264
|
+
s_identityValidator.addCredentialSource(
|
|
265
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
266
|
+
CREDENTIAL_ACCREDITED, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
267
|
+
)
|
|
268
|
+
);
|
|
269
|
+
s_identityValidator.addCredentialSource(
|
|
270
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
271
|
+
CREDENTIAL_ACCREDITED, address(identityRegistry2), address(credentialRegistry2), address(0)
|
|
272
|
+
)
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
// no ACCREDITED credential in this registry
|
|
276
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
277
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, 0, "", "");
|
|
278
|
+
|
|
279
|
+
identityRegistry2.registerIdentity(ccid, account1, "");
|
|
280
|
+
credentialRegistry2.registerCredential(ccid, CREDENTIAL_ACCREDITED, 0, "", "");
|
|
281
|
+
|
|
282
|
+
assertFalse(s_identityValidator.validate(account1, ""));
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function test_credentialRole_success() public {
|
|
286
|
+
bytes32 ccid = keccak256("account1");
|
|
287
|
+
|
|
288
|
+
CredentialRegistry credentialRegistry2 = _deployCredentialRegistry(address(s_policyEngine));
|
|
289
|
+
vm.label(address(credentialRegistry2), "CredentialRegistry2");
|
|
290
|
+
|
|
291
|
+
vm.expectEmit();
|
|
292
|
+
emit ICredentialRegistry.CredentialRegistered(ccid, CREDENTIAL_ACCREDITED, 0, "");
|
|
293
|
+
|
|
294
|
+
credentialRegistry2.registerCredential(ccid, CREDENTIAL_ACCREDITED, 0, "", "");
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function test_validate_credentialRequirementInvert_invalid() public {
|
|
298
|
+
address account1 = makeAddr("account1");
|
|
299
|
+
bytes32 ccid = keccak256("account1");
|
|
300
|
+
|
|
301
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
302
|
+
|
|
303
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, 0, "", "");
|
|
304
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_INVALID_NATIONALITY, 0, "", "");
|
|
305
|
+
|
|
306
|
+
s_identityValidator.addCredentialRequirement(
|
|
307
|
+
ICredentialRequirements.CredentialRequirementInput(
|
|
308
|
+
CREDENTIAL_INVALID_NATIONALITY, s_credentials_invalid_nationality, 1, true
|
|
309
|
+
)
|
|
310
|
+
);
|
|
311
|
+
s_identityValidator.addCredentialSource(
|
|
312
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
313
|
+
CREDENTIAL_INVALID_NATIONALITY, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
314
|
+
)
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
assertFalse(s_identityValidator.validate(account1, ""));
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function test_validate_credentialRequirementInvertCredentialExists_invalid() public {
|
|
321
|
+
address account1 = makeAddr("account1");
|
|
322
|
+
bytes32 ccid = keccak256("account1");
|
|
323
|
+
|
|
324
|
+
bytes32 requirement = keccak256("mock requirement");
|
|
325
|
+
bytes32[] memory credential_ids = new bytes32[](1);
|
|
326
|
+
credential_ids[0] = keccak256("mock credential type");
|
|
327
|
+
|
|
328
|
+
s_identityValidator.addCredentialRequirement(
|
|
329
|
+
ICredentialRequirements.CredentialRequirementInput(requirement, credential_ids, 1, true)
|
|
330
|
+
);
|
|
331
|
+
s_identityValidator.addCredentialSource(
|
|
332
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
333
|
+
credential_ids[0], address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
334
|
+
)
|
|
335
|
+
);
|
|
336
|
+
|
|
337
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
338
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, 0, "", "");
|
|
339
|
+
s_credentialRegistry.registerCredential(ccid, credential_ids[0], 0, abi.encode("mock data"), "");
|
|
340
|
+
|
|
341
|
+
// For inverted credentials: if credential exists in registry, validation fails (no data validation performed)
|
|
342
|
+
assertFalse(s_identityValidator.validate(account1, ""));
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
function test_validate_credentialRequirementInvertNotPresent_succeeds() public {
|
|
346
|
+
address account1 = makeAddr("account1");
|
|
347
|
+
bytes32 ccid = keccak256("account1");
|
|
348
|
+
|
|
349
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
350
|
+
|
|
351
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, 0, "", "");
|
|
352
|
+
|
|
353
|
+
s_identityValidator.addCredentialRequirement(
|
|
354
|
+
ICredentialRequirements.CredentialRequirementInput(
|
|
355
|
+
CREDENTIAL_INVALID_NATIONALITY, s_credentials_invalid_nationality, 1, true
|
|
356
|
+
)
|
|
357
|
+
);
|
|
358
|
+
s_identityValidator.addCredentialSource(
|
|
359
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
360
|
+
CREDENTIAL_INVALID_NATIONALITY, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
361
|
+
)
|
|
362
|
+
);
|
|
363
|
+
|
|
364
|
+
assertTrue(s_identityValidator.validate(account1, ""));
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function test_validate_invertCredentialRequirementNotPresentButOtherCredentialMissing_invalid() public {
|
|
368
|
+
address account1 = makeAddr("account1");
|
|
369
|
+
bytes32 ccid = keccak256("account1");
|
|
370
|
+
|
|
371
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
372
|
+
|
|
373
|
+
s_identityValidator.addCredentialRequirement(
|
|
374
|
+
ICredentialRequirements.CredentialRequirementInput(
|
|
375
|
+
CREDENTIAL_INVALID_NATIONALITY, s_credentials_invalid_nationality, 1, true
|
|
376
|
+
)
|
|
377
|
+
);
|
|
378
|
+
s_identityValidator.addCredentialSource(
|
|
379
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
380
|
+
CREDENTIAL_INVALID_NATIONALITY, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
381
|
+
)
|
|
382
|
+
);
|
|
383
|
+
|
|
384
|
+
assertFalse(s_identityValidator.validate(account1, ""));
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
function test_addCredentialRequirement_zeroMinValidations_invalid() public {
|
|
388
|
+
vm.expectRevert();
|
|
389
|
+
s_identityValidator.addCredentialRequirement(
|
|
390
|
+
ICredentialRequirements.CredentialRequirementInput(
|
|
391
|
+
CREDENTIAL_INVALID_NATIONALITY, s_credentials_invalid_nationality, 0, false
|
|
392
|
+
)
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
function test_getCredentialRequirement_success() public {
|
|
397
|
+
bytes32 CREDENTIAL_BANK2_KYC = keccak256("com.bank2.kyc");
|
|
398
|
+
|
|
399
|
+
s_credentials_kyc = new bytes32[](2);
|
|
400
|
+
s_credentials_kyc[0] = CREDENTIAL_KYC;
|
|
401
|
+
s_credentials_kyc[1] = CREDENTIAL_BANK2_KYC;
|
|
402
|
+
s_identityValidator.removeCredentialRequirement(REQUIREMENT_KYC);
|
|
403
|
+
s_identityValidator.addCredentialRequirement(
|
|
404
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_KYC, s_credentials_kyc, 1, false)
|
|
405
|
+
);
|
|
406
|
+
|
|
407
|
+
ICredentialRequirements.CredentialRequirement memory credRequirement =
|
|
408
|
+
s_identityValidator.getCredentialRequirement(REQUIREMENT_KYC);
|
|
409
|
+
assert(credRequirement.minValidations == 1);
|
|
410
|
+
assert(credRequirement.credentialTypeIds[0] == CREDENTIAL_KYC);
|
|
411
|
+
assert(credRequirement.credentialTypeIds[1] == CREDENTIAL_BANK2_KYC);
|
|
412
|
+
assert(credRequirement.invert == false);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function test_getCredentialRequirement_duplicated_failure() public {
|
|
416
|
+
bytes32 CREDENTIAL_BANK2_KYC = keccak256("com.bank2.kyc");
|
|
417
|
+
|
|
418
|
+
s_credentials_kyc = new bytes32[](2);
|
|
419
|
+
s_credentials_kyc[0] = CREDENTIAL_KYC;
|
|
420
|
+
s_credentials_kyc[1] = CREDENTIAL_BANK2_KYC;
|
|
421
|
+
|
|
422
|
+
vm.expectPartialRevert(ICredentialRequirements.RequirementExists.selector);
|
|
423
|
+
s_identityValidator.addCredentialRequirement(
|
|
424
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_KYC, s_credentials_kyc, 1, false)
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
function test_getCredentialRequirementIds_success() public {
|
|
429
|
+
bytes32 CREDENTIAL_BANK2_KYC = keccak256("com.bank2.kyc");
|
|
430
|
+
|
|
431
|
+
s_credentials_kyc = new bytes32[](2);
|
|
432
|
+
s_credentials_kyc[0] = CREDENTIAL_KYC;
|
|
433
|
+
s_credentials_kyc[1] = CREDENTIAL_BANK2_KYC;
|
|
434
|
+
s_identityValidator.removeCredentialRequirement(REQUIREMENT_KYC);
|
|
435
|
+
s_identityValidator.addCredentialRequirement(
|
|
436
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_KYC, s_credentials_kyc, 1, false)
|
|
437
|
+
);
|
|
438
|
+
|
|
439
|
+
bytes32[] memory requirementIds = s_identityValidator.getCredentialRequirementIds();
|
|
440
|
+
assert(requirementIds.length == 1);
|
|
441
|
+
assert(requirementIds[0] == REQUIREMENT_KYC);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
function test_addCredentialSource_success() public {
|
|
445
|
+
bytes32 CREDENTIAL_BANK2_KYC = keccak256("com.bank2.kyc");
|
|
446
|
+
|
|
447
|
+
s_identityValidator.addCredentialSource(
|
|
448
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
449
|
+
CREDENTIAL_BANK2_KYC, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
450
|
+
)
|
|
451
|
+
);
|
|
452
|
+
|
|
453
|
+
ICredentialRequirements.CredentialSource[] memory credSourcesBeforeRemoval =
|
|
454
|
+
s_identityValidator.getCredentialSources(CREDENTIAL_BANK2_KYC);
|
|
455
|
+
assert(credSourcesBeforeRemoval.length == 1);
|
|
456
|
+
|
|
457
|
+
s_identityValidator.removeCredentialSource(
|
|
458
|
+
CREDENTIAL_BANK2_KYC, address(s_identityRegistry), address(s_credentialRegistry)
|
|
459
|
+
);
|
|
460
|
+
|
|
461
|
+
ICredentialRequirements.CredentialSource[] memory credSourcesAfterRemoval =
|
|
462
|
+
s_identityValidator.getCredentialSources(CREDENTIAL_BANK2_KYC);
|
|
463
|
+
assert(credSourcesAfterRemoval.length == 0);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
function test_addCredentialSource_duplicated_failure() public {
|
|
467
|
+
bytes32 CREDENTIAL_BANK2_KYC = keccak256("com.bank2.kyc");
|
|
468
|
+
|
|
469
|
+
s_identityValidator.addCredentialSource(
|
|
470
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
471
|
+
CREDENTIAL_BANK2_KYC, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
472
|
+
)
|
|
473
|
+
);
|
|
474
|
+
|
|
475
|
+
vm.expectPartialRevert(ICredentialRequirements.SourceExists.selector);
|
|
476
|
+
s_identityValidator.addCredentialSource(
|
|
477
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
478
|
+
CREDENTIAL_BANK2_KYC, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
479
|
+
)
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
function test_removeCredentialRequirement_notFound_failure() public {
|
|
484
|
+
vm.expectPartialRevert(ICredentialRequirements.RequirementNotFound.selector);
|
|
485
|
+
s_identityValidator.removeCredentialRequirement(keccak256("unknown"));
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
function test_removeCredentialSource_notFound_failure() public {
|
|
489
|
+
bytes32 CREDENTIAL_BANK2_KYC = keccak256("com.bank2.kyc");
|
|
490
|
+
|
|
491
|
+
vm.expectPartialRevert(ICredentialRequirements.CredentialSourceNotFound.selector);
|
|
492
|
+
s_identityValidator.removeCredentialSource(
|
|
493
|
+
CREDENTIAL_BANK2_KYC, address(s_identityRegistry), address(s_credentialRegistry)
|
|
494
|
+
);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
function test_validate_credentialRegistryThrows_invalid() public {
|
|
498
|
+
address account1 = makeAddr("account1");
|
|
499
|
+
bytes32 ccid = keccak256("account1");
|
|
500
|
+
|
|
501
|
+
// Create a mock credential registry that will throw on validate()
|
|
502
|
+
MockCredentialRegistryReverting revertingRegistry = new MockCredentialRegistryReverting();
|
|
503
|
+
revertingRegistry.setShouldRevert(true);
|
|
504
|
+
revertingRegistry.setRevertMessage("Credential validation error");
|
|
505
|
+
|
|
506
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
507
|
+
|
|
508
|
+
// Add a new credential source using the reverting registry
|
|
509
|
+
bytes32 CREDENTIAL_TEST = keccak256("test.credential");
|
|
510
|
+
bytes32[] memory testCredentials = new bytes32[](1);
|
|
511
|
+
testCredentials[0] = CREDENTIAL_TEST;
|
|
512
|
+
|
|
513
|
+
s_identityValidator.addCredentialRequirement(
|
|
514
|
+
ICredentialRequirements.CredentialRequirementInput(keccak256("TEST_REQ"), testCredentials, 1, false)
|
|
515
|
+
);
|
|
516
|
+
|
|
517
|
+
s_identityValidator.addCredentialSource(
|
|
518
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
519
|
+
CREDENTIAL_TEST, address(s_identityRegistry), address(revertingRegistry), address(0)
|
|
520
|
+
)
|
|
521
|
+
);
|
|
522
|
+
|
|
523
|
+
assertFalse(s_identityValidator.validate(account1, ""), "Should fail when credential registry throws");
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
function test_validate_credentialRegistryThrowsInverted_invalid() public {
|
|
527
|
+
address account1 = makeAddr("account1");
|
|
528
|
+
bytes32 ccid = keccak256("account1");
|
|
529
|
+
|
|
530
|
+
MockCredentialRegistryReverting revertingRegistry = new MockCredentialRegistryReverting();
|
|
531
|
+
revertingRegistry.setShouldRevert(true);
|
|
532
|
+
revertingRegistry.setRevertMessage("Credential validation error");
|
|
533
|
+
|
|
534
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
535
|
+
|
|
536
|
+
bytes32 CREDENTIAL_BLACKLIST = keccak256("blacklist.credential");
|
|
537
|
+
bytes32[] memory blacklistCredentials = new bytes32[](1);
|
|
538
|
+
blacklistCredentials[0] = CREDENTIAL_BLACKLIST;
|
|
539
|
+
|
|
540
|
+
s_identityValidator.addCredentialRequirement(
|
|
541
|
+
ICredentialRequirements.CredentialRequirementInput(keccak256("NOT_BLACKLISTED"), blacklistCredentials, 1, true)
|
|
542
|
+
);
|
|
543
|
+
|
|
544
|
+
s_identityValidator.addCredentialSource(
|
|
545
|
+
ICredentialRequirements.CredentialSourceInput(
|
|
546
|
+
CREDENTIAL_BLACKLIST, address(s_identityRegistry), address(revertingRegistry), address(0)
|
|
547
|
+
)
|
|
548
|
+
);
|
|
549
|
+
|
|
550
|
+
assertFalse(
|
|
551
|
+
s_identityValidator.validate(account1, ""), "Should fail when credential registry throws, even with invert=true"
|
|
552
|
+
);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BUSL-1.1
|
|
2
|
+
pragma solidity 0.8.26;
|
|
3
|
+
|
|
4
|
+
import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
|
|
5
|
+
import {ICredentialRequirements} from "../src/interfaces/ICredentialRequirements.sol";
|
|
6
|
+
import {IdentityRegistry} from "../src/IdentityRegistry.sol";
|
|
7
|
+
import {CredentialRegistry} from "../src/CredentialRegistry.sol";
|
|
8
|
+
import {CredentialRegistryIdentityValidatorPolicy} from "../src/CredentialRegistryIdentityValidatorPolicy.sol";
|
|
9
|
+
import {PolicyEngine} from "@chainlink/policy-management/core/PolicyEngine.sol";
|
|
10
|
+
import {BaseProxyTest} from "./helpers/BaseProxyTest.sol";
|
|
11
|
+
|
|
12
|
+
contract CredentialRegistryIdentityValidatorPolicyTest is BaseProxyTest {
|
|
13
|
+
bytes32 public constant REQUIREMENT_KYC = keccak256("KYC");
|
|
14
|
+
bytes32 public constant CREDENTIAL_KYC = keccak256("common.kyc");
|
|
15
|
+
|
|
16
|
+
bytes32[] internal s_credentials_kyc;
|
|
17
|
+
|
|
18
|
+
PolicyEngine internal s_policyEngine;
|
|
19
|
+
IdentityRegistry internal s_identityRegistry;
|
|
20
|
+
CredentialRegistry internal s_credentialRegistry;
|
|
21
|
+
CredentialRegistryIdentityValidatorPolicy internal s_identityValidatorPolicy;
|
|
22
|
+
|
|
23
|
+
address internal s_owner;
|
|
24
|
+
|
|
25
|
+
function setUp() public {
|
|
26
|
+
s_owner = makeAddr("owner");
|
|
27
|
+
|
|
28
|
+
vm.startPrank(s_owner);
|
|
29
|
+
|
|
30
|
+
s_credentials_kyc = new bytes32[](1);
|
|
31
|
+
s_credentials_kyc[0] = CREDENTIAL_KYC;
|
|
32
|
+
|
|
33
|
+
s_policyEngine = _deployPolicyEngine(true, address(this));
|
|
34
|
+
s_identityRegistry = _deployIdentityRegistry(address(s_policyEngine));
|
|
35
|
+
s_credentialRegistry = _deployCredentialRegistry(address(s_policyEngine));
|
|
36
|
+
|
|
37
|
+
ICredentialRequirements.CredentialRequirementInput[] memory credentialRequirementInputs =
|
|
38
|
+
new ICredentialRequirements.CredentialRequirementInput[](1);
|
|
39
|
+
credentialRequirementInputs[0] =
|
|
40
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_KYC, s_credentials_kyc, 1, false);
|
|
41
|
+
|
|
42
|
+
ICredentialRequirements.CredentialSourceInput[] memory credentialSourceInputs =
|
|
43
|
+
new ICredentialRequirements.CredentialSourceInput[](1);
|
|
44
|
+
|
|
45
|
+
credentialSourceInputs[0] = ICredentialRequirements.CredentialSourceInput(
|
|
46
|
+
CREDENTIAL_KYC, address(s_identityRegistry), address(s_credentialRegistry), address(0)
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
s_identityValidatorPolicy = _deployCredentialRegistryCredentialRegistryIdentityValidatorPolicy(
|
|
50
|
+
address(s_policyEngine), s_owner, abi.encode(credentialSourceInputs, credentialRequirementInputs)
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function test_run_continue() public {
|
|
55
|
+
address account1 = makeAddr("account1");
|
|
56
|
+
bytes32 ccid = keccak256("account1");
|
|
57
|
+
|
|
58
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
59
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, 0, "", "");
|
|
60
|
+
|
|
61
|
+
assertTrue(s_identityValidatorPolicy.validate(account1, ""));
|
|
62
|
+
|
|
63
|
+
bytes[] memory parameters = new bytes[](1);
|
|
64
|
+
parameters[0] = abi.encode(account1);
|
|
65
|
+
|
|
66
|
+
IPolicyEngine.PolicyResult policyRes =
|
|
67
|
+
s_identityValidatorPolicy.run(address(0), address(0), 0x00000000, parameters, "");
|
|
68
|
+
assert(policyRes == IPolicyEngine.PolicyResult.Continue);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function test_run_rejected() public {
|
|
72
|
+
address account1 = makeAddr("account1");
|
|
73
|
+
bytes32 ccid = keccak256("account1");
|
|
74
|
+
|
|
75
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
76
|
+
|
|
77
|
+
assertFalse(s_identityValidatorPolicy.validate(account1, ""));
|
|
78
|
+
|
|
79
|
+
bytes[] memory parameters = new bytes[](1);
|
|
80
|
+
parameters[0] = abi.encode(account1);
|
|
81
|
+
|
|
82
|
+
vm.expectPartialRevert(IPolicyEngine.PolicyRejected.selector);
|
|
83
|
+
IPolicyEngine.PolicyResult policyRes =
|
|
84
|
+
s_identityValidatorPolicy.run(address(0), address(0), 0x00000000, parameters, "");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function test_empty_initialization_and_later_configuration_continues() public {
|
|
88
|
+
CredentialRegistryIdentityValidatorPolicy policy =
|
|
89
|
+
_deployCredentialRegistryCredentialRegistryIdentityValidatorPolicy(address(s_policyEngine), s_owner, "");
|
|
90
|
+
|
|
91
|
+
ICredentialRequirements.CredentialRequirementInput memory credentialRequirementInputs =
|
|
92
|
+
ICredentialRequirements.CredentialRequirementInput(REQUIREMENT_KYC, s_credentials_kyc, 1, false);
|
|
93
|
+
|
|
94
|
+
ICredentialRequirements.CredentialSourceInput memory credentialSourceInput = ICredentialRequirements
|
|
95
|
+
.CredentialSourceInput(CREDENTIAL_KYC, address(s_identityRegistry), address(s_credentialRegistry), address(0));
|
|
96
|
+
|
|
97
|
+
policy.addCredentialSource(credentialSourceInput);
|
|
98
|
+
policy.addCredentialRequirement(credentialRequirementInputs);
|
|
99
|
+
|
|
100
|
+
address account1 = makeAddr("account1");
|
|
101
|
+
bytes32 ccid = keccak256("account1");
|
|
102
|
+
|
|
103
|
+
s_identityRegistry.registerIdentity(ccid, account1, "");
|
|
104
|
+
s_credentialRegistry.registerCredential(ccid, CREDENTIAL_KYC, 0, "", "");
|
|
105
|
+
|
|
106
|
+
assertTrue(policy.validate(account1, ""));
|
|
107
|
+
|
|
108
|
+
bytes[] memory parameters = new bytes[](1);
|
|
109
|
+
parameters[0] = abi.encode(account1);
|
|
110
|
+
|
|
111
|
+
IPolicyEngine.PolicyResult policyRes = policy.run(address(0), address(0), 0x00000000, parameters, "");
|
|
112
|
+
assert(policyRes == IPolicyEngine.PolicyResult.Continue);
|
|
113
|
+
}
|
|
114
|
+
}
|