@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,332 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BUSL-1.1
|
|
2
|
+
pragma solidity 0.8.26;
|
|
3
|
+
|
|
4
|
+
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
|
|
5
|
+
import {Script} from "forge-std/Script.sol";
|
|
6
|
+
import {console} from "forge-std/console.sol";
|
|
7
|
+
|
|
8
|
+
// Core Contracts
|
|
9
|
+
import {ComplianceTokenERC20} from "../../../packages/tokens/erc-20/src/ComplianceTokenERC20.sol";
|
|
10
|
+
import {PolicyEngine} from "@chainlink/policy-management/core/PolicyEngine.sol";
|
|
11
|
+
import {Policy} from "@chainlink/policy-management/core/Policy.sol";
|
|
12
|
+
import {IdentityRegistry} from "@chainlink/cross-chain-identity/IdentityRegistry.sol";
|
|
13
|
+
import {CredentialRegistry} from "@chainlink/cross-chain-identity/CredentialRegistry.sol";
|
|
14
|
+
|
|
15
|
+
// Policies
|
|
16
|
+
import {OnlyOwnerPolicy} from "@chainlink/policy-management/policies/OnlyOwnerPolicy.sol";
|
|
17
|
+
import {CredentialRegistryIdentityValidatorPolicy} from
|
|
18
|
+
"@chainlink/cross-chain-identity/CredentialRegistryIdentityValidatorPolicy.sol";
|
|
19
|
+
import {SanctionsPolicy} from "../../../getting_started/advanced/SanctionsPolicy.sol";
|
|
20
|
+
import {OnlyAuthorizedSenderPolicy} from "@chainlink/policy-management/policies/OnlyAuthorizedSenderPolicy.sol";
|
|
21
|
+
|
|
22
|
+
// Extractors
|
|
23
|
+
import {ERC20TransferExtractor} from "@chainlink/policy-management/extractors/ERC20TransferExtractor.sol";
|
|
24
|
+
import {ComplianceTokenMintBurnExtractor} from
|
|
25
|
+
"@chainlink/policy-management/extractors/ComplianceTokenMintBurnExtractor.sol";
|
|
26
|
+
import {ComplianceTokenFreezeUnfreezeExtractor} from
|
|
27
|
+
"@chainlink/policy-management/extractors/ComplianceTokenFreezeUnfreezeExtractor.sol";
|
|
28
|
+
import {ComplianceTokenForceTransferExtractor} from
|
|
29
|
+
"@chainlink/policy-management/extractors/ComplianceTokenForceTransferExtractor.sol";
|
|
30
|
+
|
|
31
|
+
// Interfaces
|
|
32
|
+
import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
|
|
33
|
+
import {ICredentialRequirements} from "@chainlink/cross-chain-identity/interfaces/ICredentialRequirements.sol";
|
|
34
|
+
|
|
35
|
+
contract DeployAdvancedGettingStarted is Script {
|
|
36
|
+
function run() external {
|
|
37
|
+
// --- 0. Setup ---
|
|
38
|
+
// Load the deployer's private key from the environment.
|
|
39
|
+
// This is the primary account that will own and configure the system.
|
|
40
|
+
uint256 tokenOwnerPK = vm.envUint("PRIVATE_KEY");
|
|
41
|
+
address tokenOwner = vm.addr(tokenOwnerPK);
|
|
42
|
+
|
|
43
|
+
vm.startBroadcast(tokenOwnerPK);
|
|
44
|
+
|
|
45
|
+
// --- 1. Deploy Core Infrastructure ---
|
|
46
|
+
// The PolicyEngine is the central orchestrator for all compliance rules.
|
|
47
|
+
// We set its default to allow (true) for this tutorial, meaning any action
|
|
48
|
+
// not explicitly rejected by a policy will be permitted.
|
|
49
|
+
PolicyEngine policyEngineImpl = new PolicyEngine();
|
|
50
|
+
bytes memory policyEngineData = abi.encodeWithSelector(PolicyEngine.initialize.selector, true, tokenOwner);
|
|
51
|
+
ERC1967Proxy policyEngineProxy = new ERC1967Proxy(address(policyEngineImpl), policyEngineData);
|
|
52
|
+
PolicyEngine policyEngine = PolicyEngine(address(policyEngineProxy));
|
|
53
|
+
|
|
54
|
+
// --- 2. Deploy Identity & Credential Registries and Secure Them ---
|
|
55
|
+
// These registries are the databases for our identity system.
|
|
56
|
+
// Crucially, we set the PolicyEngine as their owner, so all administrative
|
|
57
|
+
// actions MUST go through the policy system.
|
|
58
|
+
IdentityRegistry identityRegistryImpl = new IdentityRegistry();
|
|
59
|
+
bytes memory identityRegistryData =
|
|
60
|
+
abi.encodeWithSelector(IdentityRegistry.initialize.selector, address(policyEngine), tokenOwner);
|
|
61
|
+
ERC1967Proxy identityRegistryProxy = new ERC1967Proxy(address(identityRegistryImpl), identityRegistryData);
|
|
62
|
+
IdentityRegistry identityRegistry = IdentityRegistry(address(identityRegistryProxy));
|
|
63
|
+
|
|
64
|
+
CredentialRegistry credentialRegistryImpl = new CredentialRegistry();
|
|
65
|
+
bytes memory credentialRegistryData =
|
|
66
|
+
abi.encodeWithSelector(CredentialRegistry.initialize.selector, address(policyEngine), tokenOwner);
|
|
67
|
+
ERC1967Proxy credentialRegistryProxy = new ERC1967Proxy(address(credentialRegistryImpl), credentialRegistryData);
|
|
68
|
+
CredentialRegistry credentialRegistry = CredentialRegistry(address(credentialRegistryProxy));
|
|
69
|
+
|
|
70
|
+
// We use OnlyAuthorizedSenderPolicy to allow the owner to delegate registry management.
|
|
71
|
+
OnlyAuthorizedSenderPolicy identityOnlyAuthorizedSenderPolicyImpl = new OnlyAuthorizedSenderPolicy();
|
|
72
|
+
bytes memory identityOnlyAuthorizedSenderPolicyData =
|
|
73
|
+
abi.encodeWithSelector(Policy.initialize.selector, address(policyEngine), tokenOwner, new bytes(0));
|
|
74
|
+
ERC1967Proxy identityOnlyAuthorizedSenderPolicyProxy =
|
|
75
|
+
new ERC1967Proxy(address(identityOnlyAuthorizedSenderPolicyImpl), identityOnlyAuthorizedSenderPolicyData);
|
|
76
|
+
OnlyAuthorizedSenderPolicy identityOnlyAuthorizedSenderPolicy =
|
|
77
|
+
OnlyAuthorizedSenderPolicy(address(identityOnlyAuthorizedSenderPolicyProxy));
|
|
78
|
+
identityOnlyAuthorizedSenderPolicy.authorizeSender(tokenOwner); // Authorize the deployer by default
|
|
79
|
+
|
|
80
|
+
// All administrative functions on the registries will now require that the
|
|
81
|
+
// caller is on the authorized list of the identityOnlyAuthorizedSenderPolicy.
|
|
82
|
+
policyEngine.addPolicy(
|
|
83
|
+
address(identityRegistry),
|
|
84
|
+
identityRegistry.registerIdentity.selector,
|
|
85
|
+
address(identityOnlyAuthorizedSenderPolicy),
|
|
86
|
+
new bytes32[](0)
|
|
87
|
+
);
|
|
88
|
+
policyEngine.addPolicy(
|
|
89
|
+
address(identityRegistry),
|
|
90
|
+
identityRegistry.registerIdentities.selector,
|
|
91
|
+
address(identityOnlyAuthorizedSenderPolicy),
|
|
92
|
+
new bytes32[](0)
|
|
93
|
+
);
|
|
94
|
+
policyEngine.addPolicy(
|
|
95
|
+
address(identityRegistry),
|
|
96
|
+
identityRegistry.removeIdentity.selector,
|
|
97
|
+
address(identityOnlyAuthorizedSenderPolicy),
|
|
98
|
+
new bytes32[](0)
|
|
99
|
+
);
|
|
100
|
+
policyEngine.addPolicy(
|
|
101
|
+
address(credentialRegistry),
|
|
102
|
+
credentialRegistry.registerCredential.selector,
|
|
103
|
+
address(identityOnlyAuthorizedSenderPolicy),
|
|
104
|
+
new bytes32[](0)
|
|
105
|
+
);
|
|
106
|
+
policyEngine.addPolicy(
|
|
107
|
+
address(credentialRegistry),
|
|
108
|
+
credentialRegistry.registerCredentials.selector,
|
|
109
|
+
address(identityOnlyAuthorizedSenderPolicy),
|
|
110
|
+
new bytes32[](0)
|
|
111
|
+
);
|
|
112
|
+
policyEngine.addPolicy(
|
|
113
|
+
address(credentialRegistry),
|
|
114
|
+
credentialRegistry.removeCredential.selector,
|
|
115
|
+
address(identityOnlyAuthorizedSenderPolicy),
|
|
116
|
+
new bytes32[](0)
|
|
117
|
+
);
|
|
118
|
+
policyEngine.addPolicy(
|
|
119
|
+
address(credentialRegistry),
|
|
120
|
+
credentialRegistry.renewCredential.selector,
|
|
121
|
+
address(identityOnlyAuthorizedSenderPolicy),
|
|
122
|
+
new bytes32[](0)
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
// --- 3. Deploy MMF Token and Secure It ---
|
|
126
|
+
// This is our main application contract. It inherits from PolicyProtected.
|
|
127
|
+
ComplianceTokenERC20 mmfTokenImpl = new ComplianceTokenERC20();
|
|
128
|
+
bytes memory mmfTokenData = abi.encodeWithSelector(
|
|
129
|
+
ComplianceTokenERC20.initialize.selector,
|
|
130
|
+
vm.envOr("TOKEN_NAME", string("Tokenized MMF")),
|
|
131
|
+
vm.envOr("TOKEN_SYMBOL", string("MMF")),
|
|
132
|
+
18,
|
|
133
|
+
address(policyEngine)
|
|
134
|
+
);
|
|
135
|
+
ERC1967Proxy mmfTokenProxy = new ERC1967Proxy(address(mmfTokenImpl), mmfTokenData);
|
|
136
|
+
ComplianceTokenERC20 mmfToken = ComplianceTokenERC20(address(mmfTokenProxy));
|
|
137
|
+
|
|
138
|
+
// a. Protect critical admin functions (e.g., freeze, forceTransfer) with a strict OnlyOwnerPolicy.
|
|
139
|
+
OnlyOwnerPolicy tokenOnlyOwnerPolicyImpl = new OnlyOwnerPolicy();
|
|
140
|
+
bytes memory tokenOnlyOwnerPolicyData =
|
|
141
|
+
abi.encodeWithSelector(Policy.initialize.selector, address(policyEngine), tokenOwner, new bytes(0));
|
|
142
|
+
ERC1967Proxy tokenOnlyOwnerPolicyProxy =
|
|
143
|
+
new ERC1967Proxy(address(tokenOnlyOwnerPolicyImpl), tokenOnlyOwnerPolicyData);
|
|
144
|
+
OnlyOwnerPolicy tokenOnlyOwnerPolicy = OnlyOwnerPolicy(address(tokenOnlyOwnerPolicyProxy));
|
|
145
|
+
policyEngine.addPolicy(
|
|
146
|
+
address(mmfToken), mmfToken.forceTransfer.selector, address(tokenOnlyOwnerPolicy), new bytes32[](0)
|
|
147
|
+
);
|
|
148
|
+
policyEngine.addPolicy(address(mmfToken), mmfToken.freeze.selector, address(tokenOnlyOwnerPolicy), new bytes32[](0));
|
|
149
|
+
policyEngine.addPolicy(
|
|
150
|
+
address(mmfToken), mmfToken.unfreeze.selector, address(tokenOnlyOwnerPolicy), new bytes32[](0)
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
// b. Protect minting and burning with a more flexible OnlyAuthorizedSenderPolicy.
|
|
154
|
+
// This allows the owner to delegate minting rights to other contracts or addresses if needed.
|
|
155
|
+
OnlyAuthorizedSenderPolicy tokenMinterBurnerPolicyImpl = new OnlyAuthorizedSenderPolicy();
|
|
156
|
+
bytes memory tokenMinterBurnerPolicyData =
|
|
157
|
+
abi.encodeWithSelector(Policy.initialize.selector, address(policyEngine), tokenOwner, new bytes(0));
|
|
158
|
+
ERC1967Proxy tokenMinterBurnerPolicyProxy =
|
|
159
|
+
new ERC1967Proxy(address(tokenMinterBurnerPolicyImpl), tokenMinterBurnerPolicyData);
|
|
160
|
+
OnlyAuthorizedSenderPolicy tokenMinterBurnerPolicy =
|
|
161
|
+
OnlyAuthorizedSenderPolicy(address(tokenMinterBurnerPolicyProxy));
|
|
162
|
+
tokenMinterBurnerPolicy.authorizeSender(tokenOwner); // The deployer can mint/burn by default.
|
|
163
|
+
policyEngine.addPolicy(
|
|
164
|
+
address(mmfToken), mmfToken.mint.selector, address(tokenMinterBurnerPolicy), new bytes32[](0)
|
|
165
|
+
);
|
|
166
|
+
policyEngine.addPolicy(
|
|
167
|
+
address(mmfToken), mmfToken.burnFrom.selector, address(tokenMinterBurnerPolicy), new bytes32[](0)
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
// c. Protect `transfer` with KYC and Sanctions policies
|
|
171
|
+
CredentialRegistryIdentityValidatorPolicy identityValidatorPolicy =
|
|
172
|
+
createCredentialRegistryIdentityValidatorPolicy(policyEngine, tokenOwner, identityRegistry, credentialRegistry);
|
|
173
|
+
|
|
174
|
+
// Read the Sanctions List address from environment (deployed by Sanctions Provider)
|
|
175
|
+
address sanctionsListAddress = vm.envAddress("SANCTIONS_LIST_ADDRESS");
|
|
176
|
+
|
|
177
|
+
// Deploy SanctionsPolicy with the sanctions list address configured during initialization
|
|
178
|
+
SanctionsPolicy sanctionsPolicyImpl = new SanctionsPolicy();
|
|
179
|
+
bytes memory sanctionsPolicyData = abi.encodeWithSelector(
|
|
180
|
+
Policy.initialize.selector,
|
|
181
|
+
address(policyEngine),
|
|
182
|
+
tokenOwner,
|
|
183
|
+
abi.encode(sanctionsListAddress) // Pass sanctions list address via configData
|
|
184
|
+
);
|
|
185
|
+
ERC1967Proxy sanctionsPolicyProxy = new ERC1967Proxy(address(sanctionsPolicyImpl), sanctionsPolicyData);
|
|
186
|
+
SanctionsPolicy sanctionsPolicy = SanctionsPolicy(address(sanctionsPolicyProxy));
|
|
187
|
+
|
|
188
|
+
// --- Set up Extractors ---
|
|
189
|
+
// An extractor is required for any function whose parameters need to be inspected by a policy.
|
|
190
|
+
// While the Getting Started guide only adds policies to `transfer`, we set up extractors for all critical
|
|
191
|
+
// functions to make this script a more robust starting point for your own experiments.
|
|
192
|
+
|
|
193
|
+
// This extractor is used for both `transfer` and `transferFrom` functions.
|
|
194
|
+
ERC20TransferExtractor erc20TransferExtractor = new ERC20TransferExtractor();
|
|
195
|
+
policyEngine.setExtractor(mmfToken.transfer.selector, address(erc20TransferExtractor));
|
|
196
|
+
policyEngine.setExtractor(mmfToken.transferFrom.selector, address(erc20TransferExtractor));
|
|
197
|
+
|
|
198
|
+
// These extractors are included for your convenience if you wish to add policies
|
|
199
|
+
// to other functions.
|
|
200
|
+
ComplianceTokenMintBurnExtractor mintBurnExtractor = new ComplianceTokenMintBurnExtractor();
|
|
201
|
+
policyEngine.setExtractor(mmfToken.mint.selector, address(mintBurnExtractor));
|
|
202
|
+
policyEngine.setExtractor(mmfToken.burnFrom.selector, address(mintBurnExtractor));
|
|
203
|
+
|
|
204
|
+
ComplianceTokenFreezeUnfreezeExtractor freezeUnfreezeExtractor = new ComplianceTokenFreezeUnfreezeExtractor();
|
|
205
|
+
policyEngine.setExtractor(mmfToken.freeze.selector, address(freezeUnfreezeExtractor));
|
|
206
|
+
policyEngine.setExtractor(mmfToken.unfreeze.selector, address(freezeUnfreezeExtractor));
|
|
207
|
+
|
|
208
|
+
ComplianceTokenForceTransferExtractor forceTransferExtractor = new ComplianceTokenForceTransferExtractor();
|
|
209
|
+
policyEngine.setExtractor(mmfToken.forceTransfer.selector, address(forceTransferExtractor));
|
|
210
|
+
|
|
211
|
+
/*
|
|
212
|
+
================================================================
|
|
213
|
+
Extractor Parameter Reference
|
|
214
|
+
================================================================
|
|
215
|
+
For your convenience, here are the parameter names available
|
|
216
|
+
from the extractors configured above. You will need these names
|
|
217
|
+
when calling `policyEngine.addPolicy(...)` for these functions.
|
|
218
|
+
|
|
219
|
+
- ERC20TransferExtractor:
|
|
220
|
+
- For `transfer`:
|
|
221
|
+
- "to" (address)
|
|
222
|
+
- "amount" (uint256)
|
|
223
|
+
- For `transferFrom`:
|
|
224
|
+
- "from" (address)
|
|
225
|
+
- "to" (address)
|
|
226
|
+
- "amount" (uint256)
|
|
227
|
+
|
|
228
|
+
- ComplianceTokenMintBurnExtractor (`mint`, `burnFrom`):
|
|
229
|
+
- "account" (address)
|
|
230
|
+
- "amount" (uint256)
|
|
231
|
+
|
|
232
|
+
- ComplianceTokenFreezeUnfreezeExtractor (`freeze`, `unfreeze`):
|
|
233
|
+
- "account" (address)
|
|
234
|
+
- "amount" (uint256)
|
|
235
|
+
|
|
236
|
+
- ComplianceTokenForceTransferExtractor (`forceTransfer`):
|
|
237
|
+
- "from" (address)
|
|
238
|
+
- "to" (address)
|
|
239
|
+
- "amount" (uint256)
|
|
240
|
+
*/
|
|
241
|
+
|
|
242
|
+
// --- Configure Policies for `transfer` and `transferFrom` ---
|
|
243
|
+
// Now we can configure policies that use the extracted parameters.
|
|
244
|
+
// Our KYC and Sanctions policies need to know the `to` address from inside the transfer() calldata.
|
|
245
|
+
bytes32[] memory transferParams = new bytes32[](1);
|
|
246
|
+
transferParams[0] = erc20TransferExtractor.PARAM_TO(); // Get the "to" parameter name from the extractor
|
|
247
|
+
|
|
248
|
+
policyEngine.addPolicy(
|
|
249
|
+
address(mmfToken), mmfToken.transfer.selector, address(identityValidatorPolicy), transferParams
|
|
250
|
+
);
|
|
251
|
+
policyEngine.addPolicy(address(mmfToken), mmfToken.transfer.selector, address(sanctionsPolicy), transferParams);
|
|
252
|
+
|
|
253
|
+
// Apply the same policies to transferFrom
|
|
254
|
+
policyEngine.addPolicy(
|
|
255
|
+
address(mmfToken), mmfToken.transferFrom.selector, address(identityValidatorPolicy), transferParams
|
|
256
|
+
);
|
|
257
|
+
policyEngine.addPolicy(address(mmfToken), mmfToken.transferFrom.selector, address(sanctionsPolicy), transferParams);
|
|
258
|
+
|
|
259
|
+
vm.stopBroadcast();
|
|
260
|
+
|
|
261
|
+
// --- 4. Log Deployed Addresses ---
|
|
262
|
+
console.log("--- Core Contracts ---");
|
|
263
|
+
console.log("MMF Token deployed at:", address(mmfToken));
|
|
264
|
+
console.log("Policy Engine deployed at:", address(policyEngine));
|
|
265
|
+
console.log("Identity Registry deployed at:", address(identityRegistry));
|
|
266
|
+
console.log("Credential Registry deployed at:", address(credentialRegistry));
|
|
267
|
+
console.log("Sanctions List configured at:", sanctionsListAddress);
|
|
268
|
+
console.log("\n--- Policies ---");
|
|
269
|
+
console.log("Token OnlyOwnerPolicy (for admin functions) deployed at:", address(tokenOnlyOwnerPolicy));
|
|
270
|
+
console.log("Token Minter/Burner Policy deployed at:", address(tokenMinterBurnerPolicy));
|
|
271
|
+
console.log("Identity OnlyAuthorizedSenderPolicy deployed at:", address(identityOnlyAuthorizedSenderPolicy));
|
|
272
|
+
console.log("CredentialRegistryIdentityValidatorPolicy deployed at:", address(identityValidatorPolicy));
|
|
273
|
+
console.log("SanctionsPolicy deployed at:", address(sanctionsPolicy));
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/// @notice Helper function to create and configure the CredentialRegistryIdentityValidatorPolicy.
|
|
277
|
+
function createCredentialRegistryIdentityValidatorPolicy(
|
|
278
|
+
PolicyEngine policyEngine,
|
|
279
|
+
address tokenOwner,
|
|
280
|
+
IdentityRegistry identityRegistry,
|
|
281
|
+
CredentialRegistry credentialRegistry
|
|
282
|
+
)
|
|
283
|
+
internal
|
|
284
|
+
returns (CredentialRegistryIdentityValidatorPolicy)
|
|
285
|
+
{
|
|
286
|
+
// This policy will require that any recipient has a valid KYC credential.
|
|
287
|
+
bytes32 kycCredential = keccak256("common.kyc");
|
|
288
|
+
|
|
289
|
+
// Define the source: where to look for credentials.
|
|
290
|
+
ICredentialRequirements.CredentialSourceInput[] memory sources =
|
|
291
|
+
new ICredentialRequirements.CredentialSourceInput[](1);
|
|
292
|
+
sources[0] = ICredentialRequirements.CredentialSourceInput(
|
|
293
|
+
kycCredential, address(identityRegistry), address(credentialRegistry), address(0)
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
// Define the requirement: what credentials must be present.
|
|
297
|
+
bytes32[] memory requiredCredentials = new bytes32[](1);
|
|
298
|
+
requiredCredentials[0] = kycCredential;
|
|
299
|
+
ICredentialRequirements.CredentialRequirementInput[] memory requirements =
|
|
300
|
+
new ICredentialRequirements.CredentialRequirementInput[](1);
|
|
301
|
+
requirements[0] =
|
|
302
|
+
ICredentialRequirements.CredentialRequirementInput(keccak256("requirement.KYC"), requiredCredentials, 1, false);
|
|
303
|
+
|
|
304
|
+
CredentialRegistryIdentityValidatorPolicy identityValidatorPolicyImpl =
|
|
305
|
+
new CredentialRegistryIdentityValidatorPolicy();
|
|
306
|
+
bytes memory identityValidatorPolicyData = abi.encodeWithSelector(
|
|
307
|
+
Policy.initialize.selector, address(policyEngine), tokenOwner, abi.encode(sources, requirements)
|
|
308
|
+
);
|
|
309
|
+
ERC1967Proxy identityValidatorPolicyProxy =
|
|
310
|
+
new ERC1967Proxy(address(identityValidatorPolicyImpl), identityValidatorPolicyData);
|
|
311
|
+
CredentialRegistryIdentityValidatorPolicy identityValidatorPolicy =
|
|
312
|
+
CredentialRegistryIdentityValidatorPolicy(address(identityValidatorPolicyProxy));
|
|
313
|
+
return identityValidatorPolicy;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function deployPolicy(
|
|
317
|
+
address impl,
|
|
318
|
+
address policyEngine,
|
|
319
|
+
address initialOwner,
|
|
320
|
+
bytes memory configData
|
|
321
|
+
)
|
|
322
|
+
internal
|
|
323
|
+
returns (address)
|
|
324
|
+
{
|
|
325
|
+
return deployProxy(impl, abi.encodeWithSelector(Policy.initialize.selector, policyEngine, initialOwner, configData));
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function deployProxy(address impl, bytes memory initData) internal returns (address) {
|
|
329
|
+
ERC1967Proxy proxy = new ERC1967Proxy(impl, initData);
|
|
330
|
+
return address(proxy);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BUSL-1.1
|
|
2
|
+
pragma solidity 0.8.26;
|
|
3
|
+
|
|
4
|
+
import {Script} from "forge-std/Script.sol";
|
|
5
|
+
import {console} from "forge-std/console.sol";
|
|
6
|
+
import {SanctionsList} from "../../../getting_started/advanced/SanctionsList.sol";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @title DeploySanctionsList (Part of the Advanced Getting Started Guide)
|
|
10
|
+
* @notice Deployment script for the Sanctions Provider to deploy their independent SanctionsList.
|
|
11
|
+
* @dev This script is run by the Sanctions Provider using their own private key.
|
|
12
|
+
* The deployed address is then used by the Fund Manager's compliance system.
|
|
13
|
+
*/
|
|
14
|
+
contract DeploySanctionsList is Script {
|
|
15
|
+
function run() external {
|
|
16
|
+
uint256 deployerPK = vm.envUint("PRIVATE_KEY");
|
|
17
|
+
|
|
18
|
+
vm.startBroadcast(deployerPK);
|
|
19
|
+
|
|
20
|
+
SanctionsList sanctionsList = new SanctionsList();
|
|
21
|
+
|
|
22
|
+
vm.stopBroadcast();
|
|
23
|
+
|
|
24
|
+
console.log("SanctionsList deployed at:", address(sanctionsList));
|
|
25
|
+
}
|
|
26
|
+
}
|