@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.
Files changed (150) hide show
  1. package/.foundry-version +1 -0
  2. package/.github/CODEOWNERS +1 -0
  3. package/.github/workflows/auto-release-version.yml +107 -0
  4. package/.github/workflows/create-version-pr.yml +95 -0
  5. package/.github/workflows/forge-docs.yml +90 -0
  6. package/.github/workflows/forge-test.yml +59 -0
  7. package/.solhint-test.json +18 -0
  8. package/.solhint.json +16 -0
  9. package/.solhintignore +3 -0
  10. package/.solhintignore-test +2 -0
  11. package/Glossary.md +141 -0
  12. package/LICENSE +59 -0
  13. package/README.md +218 -0
  14. package/assets/chainlink-logo.svg +21 -0
  15. package/chainlink-ace-License-grants +2 -0
  16. package/foundry.toml +33 -0
  17. package/getting_started/GETTING_STARTED.md +477 -0
  18. package/getting_started/MyVault.sol +48 -0
  19. package/getting_started/advanced/.env.example +36 -0
  20. package/getting_started/advanced/GETTING_STARTED_ADVANCED.md +431 -0
  21. package/getting_started/advanced/SanctionsList.sol +25 -0
  22. package/getting_started/advanced/SanctionsPolicy.sol +58 -0
  23. package/package.json +41 -0
  24. package/packages/cross-chain-identity/README.md +148 -0
  25. package/packages/cross-chain-identity/docs/API_GUIDE.md +120 -0
  26. package/packages/cross-chain-identity/docs/API_REFERENCE.md +271 -0
  27. package/packages/cross-chain-identity/docs/CONCEPTS.md +253 -0
  28. package/packages/cross-chain-identity/docs/CREDENTIAL_FLOW.md +195 -0
  29. package/packages/cross-chain-identity/docs/SECURITY.md +70 -0
  30. package/packages/cross-chain-identity/src/CredentialRegistry.sol +245 -0
  31. package/packages/cross-chain-identity/src/CredentialRegistryIdentityValidator.sol +339 -0
  32. package/packages/cross-chain-identity/src/CredentialRegistryIdentityValidatorPolicy.sol +71 -0
  33. package/packages/cross-chain-identity/src/IdentityRegistry.sol +123 -0
  34. package/packages/cross-chain-identity/src/TrustedIssuerRegistry.sol +140 -0
  35. package/packages/cross-chain-identity/src/interfaces/ICredentialDataValidator.sol +30 -0
  36. package/packages/cross-chain-identity/src/interfaces/ICredentialRegistry.sol +170 -0
  37. package/packages/cross-chain-identity/src/interfaces/ICredentialRequirements.sol +192 -0
  38. package/packages/cross-chain-identity/src/interfaces/ICredentialValidator.sol +37 -0
  39. package/packages/cross-chain-identity/src/interfaces/IIdentityRegistry.sol +85 -0
  40. package/packages/cross-chain-identity/src/interfaces/IIdentityValidator.sol +18 -0
  41. package/packages/cross-chain-identity/src/interfaces/ITrustedIssuerRegistry.sol +61 -0
  42. package/packages/cross-chain-identity/test/CredentialRegistry.t.sol +220 -0
  43. package/packages/cross-chain-identity/test/CredentialRegistryIdentityValidator.t.sol +554 -0
  44. package/packages/cross-chain-identity/test/CredentialRegistryIdentityValidatorPolicy.t.sol +114 -0
  45. package/packages/cross-chain-identity/test/IdentityRegistry.t.sol +106 -0
  46. package/packages/cross-chain-identity/test/IdentityValidator.t.sol +969 -0
  47. package/packages/cross-chain-identity/test/TrustedIssuerRegistry.t.sol +123 -0
  48. package/packages/cross-chain-identity/test/helpers/BaseProxyTest.sol +112 -0
  49. package/packages/cross-chain-identity/test/helpers/MockCredentialDataValidator.sol +26 -0
  50. package/packages/cross-chain-identity/test/helpers/MockCredentialRegistryReverting.sol +131 -0
  51. package/packages/policy-management/README.md +197 -0
  52. package/packages/policy-management/docs/API_GUIDE.md +290 -0
  53. package/packages/policy-management/docs/API_REFERENCE.md +173 -0
  54. package/packages/policy-management/docs/CONCEPTS.md +156 -0
  55. package/packages/policy-management/docs/CUSTOM_POLICIES_TUTORIAL.md +195 -0
  56. package/packages/policy-management/docs/POLICY_ORDERING_GUIDE.md +91 -0
  57. package/packages/policy-management/docs/SECURITY.md +57 -0
  58. package/packages/policy-management/src/core/Policy.sol +124 -0
  59. package/packages/policy-management/src/core/PolicyEngine.sol +382 -0
  60. package/packages/policy-management/src/core/PolicyFactory.sol +92 -0
  61. package/packages/policy-management/src/core/PolicyProtected.sol +126 -0
  62. package/packages/policy-management/src/extractors/ComplianceTokenForceTransferExtractor.sol +57 -0
  63. package/packages/policy-management/src/extractors/ComplianceTokenFreezeUnfreezeExtractor.sol +54 -0
  64. package/packages/policy-management/src/extractors/ComplianceTokenMintBurnExtractor.sol +61 -0
  65. package/packages/policy-management/src/extractors/ERC20ApproveExtractor.sol +57 -0
  66. package/packages/policy-management/src/extractors/ERC20TransferExtractor.sol +62 -0
  67. package/packages/policy-management/src/extractors/ERC3643ForcedTransferExtractor.sol +56 -0
  68. package/packages/policy-management/src/extractors/ERC3643FreezeUnfreezeExtractor.sol +55 -0
  69. package/packages/policy-management/src/extractors/ERC3643MintBurnExtractor.sol +51 -0
  70. package/packages/policy-management/src/extractors/ERC3643SetAddressFrozenExtractor.sol +51 -0
  71. package/packages/policy-management/src/interfaces/IExtractor.sol +17 -0
  72. package/packages/policy-management/src/interfaces/IMapper.sol +17 -0
  73. package/packages/policy-management/src/interfaces/IPolicy.sol +61 -0
  74. package/packages/policy-management/src/interfaces/IPolicyEngine.sol +264 -0
  75. package/packages/policy-management/src/interfaces/IPolicyProtected.sol +48 -0
  76. package/packages/policy-management/src/policies/AllowPolicy.sol +104 -0
  77. package/packages/policy-management/src/policies/BypassPolicy.sol +90 -0
  78. package/packages/policy-management/src/policies/IntervalPolicy.sol +223 -0
  79. package/packages/policy-management/src/policies/MaxPolicy.sol +73 -0
  80. package/packages/policy-management/src/policies/OnlyAuthorizedSenderPolicy.sol +84 -0
  81. package/packages/policy-management/src/policies/OnlyOwnerPolicy.sol +35 -0
  82. package/packages/policy-management/src/policies/PausePolicy.sol +82 -0
  83. package/packages/policy-management/src/policies/README.md +632 -0
  84. package/packages/policy-management/src/policies/RejectPolicy.sol +89 -0
  85. package/packages/policy-management/src/policies/RoleBasedAccessControlPolicy.sol +162 -0
  86. package/packages/policy-management/src/policies/SecureMintPolicy.sol +271 -0
  87. package/packages/policy-management/src/policies/VolumePolicy.sol +133 -0
  88. package/packages/policy-management/src/policies/VolumeRatePolicy.sol +192 -0
  89. package/packages/policy-management/test/PolicyEngine.t.sol +368 -0
  90. package/packages/policy-management/test/PolicyFactory.t.sol +114 -0
  91. package/packages/policy-management/test/PolicyProtectedToken.t.sol +75 -0
  92. package/packages/policy-management/test/extractors/ComplianceTokenForceTransferExtractor.t.sol +59 -0
  93. package/packages/policy-management/test/extractors/ComplianceTokenFreezeUnfreezeExtractor.t.sol +74 -0
  94. package/packages/policy-management/test/extractors/ComplianceTokenMintBurnExtractor.t.sol +92 -0
  95. package/packages/policy-management/test/extractors/ERC20ApproveExtractor.t.sol +58 -0
  96. package/packages/policy-management/test/extractors/ERC3643ForcedTransferExtractor.t.sol +59 -0
  97. package/packages/policy-management/test/extractors/ERC3643FreezeUnfreezeExtractor.t.sol +74 -0
  98. package/packages/policy-management/test/extractors/ERC3643MintBurnExtractor.t.sol +73 -0
  99. package/packages/policy-management/test/extractors/ERC3643SetAddressFrozenExtractor.t.sol +56 -0
  100. package/packages/policy-management/test/helpers/BaseProxyTest.sol +75 -0
  101. package/packages/policy-management/test/helpers/CustomMapper.sol +26 -0
  102. package/packages/policy-management/test/helpers/DummyExtractor.sol +11 -0
  103. package/packages/policy-management/test/helpers/ExpectedParameterPolicy.sol +39 -0
  104. package/packages/policy-management/test/helpers/MockAggregatorV3.sol +51 -0
  105. package/packages/policy-management/test/helpers/MockToken.sol +66 -0
  106. package/packages/policy-management/test/helpers/MockTokenExtractor.sol +34 -0
  107. package/packages/policy-management/test/helpers/PolicyAlwaysAllowed.sol +45 -0
  108. package/packages/policy-management/test/helpers/PolicyAlwaysContinue.sol +23 -0
  109. package/packages/policy-management/test/helpers/PolicyAlwaysRejected.sol +23 -0
  110. package/packages/policy-management/test/helpers/PolicyFailingRun.sol +22 -0
  111. package/packages/policy-management/test/policies/AllowPolicy.t.sol +174 -0
  112. package/packages/policy-management/test/policies/BypassPolicy.t.sol +159 -0
  113. package/packages/policy-management/test/policies/IntervalPolicy.t.sol +307 -0
  114. package/packages/policy-management/test/policies/MaxPolicy.t.sol +54 -0
  115. package/packages/policy-management/test/policies/OnlyAuthorizedSenderPolicy.t.sol +95 -0
  116. package/packages/policy-management/test/policies/OnlyOwnerPolicy.t.sol +47 -0
  117. package/packages/policy-management/test/policies/PausePolicy.t.sol +75 -0
  118. package/packages/policy-management/test/policies/RejectPolicy.t.sol +182 -0
  119. package/packages/policy-management/test/policies/RoleBasedAccessControlPolicy.t.sol +223 -0
  120. package/packages/policy-management/test/policies/SecureMintPolicy.t.sol +442 -0
  121. package/packages/policy-management/test/policies/VolumePolicy.t.sol +158 -0
  122. package/packages/policy-management/test/policies/VolumeRatePolicy.t.sol +165 -0
  123. package/packages/tokens/erc-20/src/ComplianceTokenERC20.sol +345 -0
  124. package/packages/tokens/erc-20/src/ComplianceTokenStoreERC20.sol +29 -0
  125. package/packages/tokens/erc-20/test/ComplianceTokenERC20.t.sol +556 -0
  126. package/packages/tokens/erc-20/test/helpers/BaseProxyTest.sol +75 -0
  127. package/packages/tokens/erc-3643/README.md +24 -0
  128. package/packages/tokens/erc-3643/src/ComplianceTokenERC3643.sol +564 -0
  129. package/packages/tokens/erc-3643/src/ComplianceTokenStoreERC3643.sol +30 -0
  130. package/packages/tokens/erc-3643/test/ComplianceTokenERC3643.t.sol +815 -0
  131. package/packages/tokens/erc-3643/test/helpers/BaseProxyTest.sol +76 -0
  132. package/packages/tokens/erc-3643/test/helpers/ExpectedContextPolicy.sol +32 -0
  133. package/packages/vendor/erc-3643/compliance/modular/IModularCompliance.sol +220 -0
  134. package/packages/vendor/erc-3643/registry/interface/IClaimTopicsRegistry.sol +101 -0
  135. package/packages/vendor/erc-3643/registry/interface/IIdentityRegistry.sol +251 -0
  136. package/packages/vendor/erc-3643/registry/interface/IIdentityRegistryStorage.sol +191 -0
  137. package/packages/vendor/erc-3643/registry/interface/ITrustedIssuersRegistry.sol +161 -0
  138. package/packages/vendor/erc-3643/token/IToken.sol +457 -0
  139. package/packages/vendor/onchain-id/interface/IClaimIssuer.sol +53 -0
  140. package/packages/vendor/onchain-id/interface/IERC734.sol +110 -0
  141. package/packages/vendor/onchain-id/interface/IERC735.sol +105 -0
  142. package/packages/vendor/onchain-id/interface/IIdentity.sol +26 -0
  143. package/packages/vendor/onchain-id/interface/IImplementationAuthority.sol +21 -0
  144. package/remappings.txt +6 -0
  145. package/script/DeployComplianceTokenERC20.s.sol +191 -0
  146. package/script/DeployComplianceTokenERC3643.s.sol +208 -0
  147. package/script/DeploySimpleComplianceToken.s.sol +38 -0
  148. package/script/getting_started/DeployGettingStarted.s.sol +74 -0
  149. package/script/getting_started/advanced/DeployAdvancedGettingStarted.s.sol +332 -0
  150. package/script/getting_started/advanced/DeploySanctionsList.s.sol +26 -0
@@ -0,0 +1,105 @@
1
+ // SPDX-License-Identifier: GPL-3.0
2
+ pragma solidity ^0.8.23;
3
+
4
+ /**
5
+ * @dev interface of the ERC735 (Claim Holder) standard as defined in the EIP.
6
+ */
7
+ interface IERC735 {
8
+ /**
9
+ * @dev Emitted when a claim was added.
10
+ *
11
+ * Specification: MUST be triggered when a claim was successfully added.
12
+ */
13
+ event ClaimAdded(
14
+ bytes32 indexed claimId,
15
+ uint256 indexed topicId,
16
+ uint256 scheme,
17
+ address indexed issuer,
18
+ bytes signature,
19
+ bytes data,
20
+ string uri
21
+ );
22
+
23
+ /**
24
+ * @dev Emitted when a claim was removed.
25
+ *
26
+ * Specification: MUST be triggered when removeClaim was successfully called.
27
+ */
28
+ event ClaimRemoved(
29
+ bytes32 indexed claimId,
30
+ uint256 indexed topicId,
31
+ uint256 scheme,
32
+ address indexed issuer,
33
+ bytes signature,
34
+ bytes data,
35
+ string uri
36
+ );
37
+
38
+ /**
39
+ * @dev Emitted when a claim was changed.
40
+ *
41
+ * Specification: MUST be triggered when addClaim was successfully called on an existing claimId.
42
+ */
43
+ event ClaimChanged(
44
+ bytes32 indexed claimId,
45
+ uint256 indexed topicId,
46
+ uint256 scheme,
47
+ address indexed issuer,
48
+ bytes signature,
49
+ bytes data,
50
+ string uri
51
+ );
52
+
53
+ /**
54
+ * @dev Add or update a claim.
55
+ *
56
+ * Triggers Event: `ClaimAdded`, `ClaimChanged`
57
+ *
58
+ * Specification: Add or update a claim from an issuer.
59
+ *
60
+ * _signature is a signed message of the following structure:
61
+ * `keccak256(abi.encode(address identityHolder_address, uint256 topic, bytes data))`.
62
+ * Claim IDs are generated using `keccak256(abi.encode(address issuer_address + uint256 topic))`.
63
+ */
64
+ function addClaim(
65
+ uint256 _topic,
66
+ uint256 _scheme,
67
+ address issuer,
68
+ bytes calldata _signature,
69
+ bytes calldata _data,
70
+ string calldata _uri
71
+ )
72
+ external
73
+ returns (bytes32 claimRequestId);
74
+
75
+ /**
76
+ * @dev Removes a claim.
77
+ *
78
+ * Triggers Event: `ClaimRemoved`
79
+ *
80
+ * Claim IDs are generated using `keccak256(abi.encode(address issuer_address, uint256 topic))`.
81
+ */
82
+ function removeClaim(bytes32 _claimId) external returns (bool success);
83
+
84
+ /**
85
+ * @dev Get a claim by its ID.
86
+ *
87
+ * Claim IDs are generated using `keccak256(abi.encode(address issuer_address, uint256 topic))`.
88
+ */
89
+ function getClaim(bytes32 _claimId)
90
+ external
91
+ view
92
+ returns (
93
+ uint256 topic,
94
+ uint256 scheme,
95
+ address issuer,
96
+ bytes memory signature,
97
+ bytes memory data,
98
+ string memory uri
99
+ );
100
+
101
+ /**
102
+ * @dev Returns an array of claim IDs by topic.
103
+ */
104
+ function getClaimIdsByTopic(uint256 _topic) external view returns (bytes32[] memory claimIds);
105
+ }
@@ -0,0 +1,26 @@
1
+ // SPDX-License-Identifier: GPL-3.0
2
+ pragma solidity ^0.8.23;
3
+
4
+ import "./IERC734.sol";
5
+ import "./IERC735.sol";
6
+
7
+ // solhint-disable-next-line no-empty-blocks
8
+ interface IIdentity is IERC734, IERC735 {
9
+ /**
10
+ * @dev Checks if a claim is valid.
11
+ * @param _identity the identity contract related to the claim
12
+ * @param claimTopic the claim topic of the claim
13
+ * @param sig the signature of the claim
14
+ * @param data the data field of the claim
15
+ * @return claimValid true if the claim is valid, false otherwise
16
+ */
17
+ function isClaimValid(
18
+ IIdentity _identity,
19
+ uint256 claimTopic,
20
+ bytes calldata sig,
21
+ bytes calldata data
22
+ )
23
+ external
24
+ view
25
+ returns (bool);
26
+ }
@@ -0,0 +1,21 @@
1
+ // SPDX-License-Identifier: GPL-3.0
2
+
3
+ pragma solidity ^0.8.23;
4
+
5
+ interface IImplementationAuthority {
6
+ // event emitted when the implementation contract is updated
7
+ event UpdatedImplementation(address newAddress);
8
+
9
+ /**
10
+ * @dev updates the address used as implementation by the proxies linked
11
+ * to this ImplementationAuthority contract
12
+ * @param _newImplementation the address of the new implementation contract
13
+ * only Owner can call
14
+ */
15
+ function updateImplementation(address _newImplementation) external;
16
+
17
+ /**
18
+ * @dev returns the address of the implementation
19
+ */
20
+ function getImplementation() external view returns (address);
21
+ }
package/remappings.txt ADDED
@@ -0,0 +1,6 @@
1
+ @openzeppelin/contracts/=node_modules/@openzeppelin/contracts/
2
+ @openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/
3
+ @chainlink/policy-management/=packages/policy-management/src/
4
+ @chainlink/cross-chain-identity/=packages/cross-chain-identity/src/
5
+ forge-std/=node_modules/forge-std/src/
6
+ @chainlink/contracts/=node_modules/@chainlink/contracts
@@ -0,0 +1,191 @@
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 {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
6
+ import {ComplianceTokenERC20} from "../packages/tokens/erc-20/src/ComplianceTokenERC20.sol";
7
+ import {PolicyEngine} from "@chainlink/policy-management/core/PolicyEngine.sol";
8
+ import {Policy} from "@chainlink/policy-management/core/Policy.sol";
9
+ import {OnlyOwnerPolicy} from "@chainlink/policy-management/policies/OnlyOwnerPolicy.sol";
10
+ import {IdentityRegistry} from "@chainlink/cross-chain-identity/IdentityRegistry.sol";
11
+ import {CredentialRegistry} from "@chainlink/cross-chain-identity/CredentialRegistry.sol";
12
+ import {CredentialRegistryIdentityValidatorPolicy} from
13
+ "@chainlink/cross-chain-identity/CredentialRegistryIdentityValidatorPolicy.sol";
14
+ import {ICredentialRequirements} from "@chainlink/cross-chain-identity/interfaces/ICredentialRequirements.sol";
15
+
16
+ import {ERC20TransferExtractor} from "@chainlink/policy-management/extractors/ERC20TransferExtractor.sol";
17
+ import {Script} from "forge-std/Script.sol";
18
+ import {console} from "forge-std/console.sol";
19
+
20
+ contract DeployComplianceTokenERC20 is Script {
21
+ function run() external {
22
+ uint256 tokenOwnerPK = vm.envUint("PRIVATE_KEY");
23
+ address tokenOwner = vm.addr(tokenOwnerPK);
24
+
25
+ vm.startBroadcast(tokenOwnerPK);
26
+
27
+ // Deploy a PolicyEngine through proxy for identity registries and attach OnlyOwnerPolicy to administrative methods
28
+ PolicyEngine policyEngineImpl = new PolicyEngine();
29
+ bytes memory policyEngineData =
30
+ abi.encodeWithSelector(PolicyEngine.initialize.selector, IPolicyEngine.PolicyResult.Allowed);
31
+ ERC1967Proxy policyEngineProxy = new ERC1967Proxy(address(policyEngineImpl), policyEngineData);
32
+ PolicyEngine policyEngine = PolicyEngine(address(policyEngineProxy));
33
+
34
+ // Deploy IdentityRegistry/CredentialRegistry through proxies for use by the
35
+ // CredentialRegistryIdentityValidatorPolicy
36
+ IdentityRegistry identityRegistryImpl = new IdentityRegistry();
37
+ bytes memory identityRegistryData =
38
+ abi.encodeWithSelector(IdentityRegistry.initialize.selector, address(policyEngine));
39
+ ERC1967Proxy identityRegistryProxy = new ERC1967Proxy(address(identityRegistryImpl), identityRegistryData);
40
+ IdentityRegistry identityRegistry = IdentityRegistry(address(identityRegistryProxy));
41
+
42
+ CredentialRegistry credentialRegistryImpl = new CredentialRegistry();
43
+ bytes memory credentialRegistryData =
44
+ abi.encodeWithSelector(CredentialRegistry.initialize.selector, address(policyEngine));
45
+ ERC1967Proxy credentialRegistryProxy = new ERC1967Proxy(address(credentialRegistryImpl), credentialRegistryData);
46
+ CredentialRegistry credentialRegistry = CredentialRegistry(address(credentialRegistryProxy));
47
+
48
+ bytes32 CREDENTIAL_KYC = keccak256("common.KYC");
49
+ bytes32[] memory requiredCredentials = new bytes32[](1);
50
+ requiredCredentials[0] = CREDENTIAL_KYC;
51
+
52
+ ICredentialRequirements.CredentialRequirementInput[] memory credentialRequirementInputs =
53
+ new ICredentialRequirements.CredentialRequirementInput[](1);
54
+ credentialRequirementInputs[0] =
55
+ ICredentialRequirements.CredentialRequirementInput(keccak256("requirement.KYC"), requiredCredentials, 1, false);
56
+
57
+ ICredentialRequirements.CredentialSourceInput[] memory credentialSourceInputs =
58
+ new ICredentialRequirements.CredentialSourceInput[](1);
59
+ credentialSourceInputs[0] = ICredentialRequirements.CredentialSourceInput(
60
+ CREDENTIAL_KYC, address(identityRegistry), address(credentialRegistry), address(0)
61
+ );
62
+
63
+ OnlyOwnerPolicy identityOnlyOwnerPolicyImpl = new OnlyOwnerPolicy();
64
+ bytes memory onlyOwnerPolicyData =
65
+ abi.encodeWithSelector(Policy.initialize.selector, address(policyEngine), tokenOwner, new bytes(0));
66
+ ERC1967Proxy identityOnlyOwnerPolicyProxy =
67
+ new ERC1967Proxy(address(identityOnlyOwnerPolicyImpl), onlyOwnerPolicyData);
68
+ OnlyOwnerPolicy identityOnlyOwnerPolicy = OnlyOwnerPolicy(address(identityOnlyOwnerPolicyProxy));
69
+ policyEngine.addPolicy(
70
+ address(identityRegistry),
71
+ IdentityRegistry.registerIdentity.selector,
72
+ address(identityOnlyOwnerPolicy),
73
+ new bytes32[](0)
74
+ );
75
+ policyEngine.addPolicy(
76
+ address(identityRegistry),
77
+ IdentityRegistry.registerIdentities.selector,
78
+ address(identityOnlyOwnerPolicy),
79
+ new bytes32[](0)
80
+ );
81
+ policyEngine.addPolicy(
82
+ address(identityRegistry),
83
+ IdentityRegistry.removeIdentity.selector,
84
+ address(identityOnlyOwnerPolicy),
85
+ new bytes32[](0)
86
+ );
87
+ policyEngine.addPolicy(
88
+ address(credentialRegistry),
89
+ CredentialRegistry.registerCredential.selector,
90
+ address(identityOnlyOwnerPolicy),
91
+ new bytes32[](0)
92
+ );
93
+ policyEngine.addPolicy(
94
+ address(credentialRegistry),
95
+ CredentialRegistry.registerCredentials.selector,
96
+ address(identityOnlyOwnerPolicy),
97
+ new bytes32[](0)
98
+ );
99
+ policyEngine.addPolicy(
100
+ address(credentialRegistry),
101
+ CredentialRegistry.removeCredential.selector,
102
+ address(identityOnlyOwnerPolicy),
103
+ new bytes32[](0)
104
+ );
105
+ policyEngine.addPolicy(
106
+ address(credentialRegistry),
107
+ CredentialRegistry.renewCredential.selector,
108
+ address(identityOnlyOwnerPolicy),
109
+ new bytes32[](0)
110
+ );
111
+
112
+ // Deploy the ComplianceTokenERC20 through proxy
113
+ ComplianceTokenERC20 tokenImpl = new ComplianceTokenERC20();
114
+ bytes memory tokenData = abi.encodeWithSelector(
115
+ ComplianceTokenERC20.initialize.selector,
116
+ vm.envOr("TOKEN_NAME", string("Token")),
117
+ vm.envOr("TOKEN_SYMBOL", string("TOKEN")),
118
+ 18,
119
+ address(policyEngine)
120
+ );
121
+ ERC1967Proxy tokenProxy = new ERC1967Proxy(address(tokenImpl), tokenData);
122
+ ComplianceTokenERC20 token = ComplianceTokenERC20(address(tokenProxy));
123
+
124
+ OnlyOwnerPolicy tokenOnlyOwnerPolicyImpl = new OnlyOwnerPolicy();
125
+ bytes memory tokenOnlyOwnerPolicyData =
126
+ abi.encodeWithSelector(Policy.initialize.selector, address(policyEngine), tokenOwner, new bytes(0));
127
+ ERC1967Proxy tokenOnlyOwnerPolicyProxy =
128
+ new ERC1967Proxy(address(tokenOnlyOwnerPolicyImpl), tokenOnlyOwnerPolicyData);
129
+ OnlyOwnerPolicy tokenOnlyOwnerPolicy = OnlyOwnerPolicy(address(tokenOnlyOwnerPolicyProxy));
130
+ policyEngine.addPolicy(
131
+ address(token), ComplianceTokenERC20.mint.selector, address(tokenOnlyOwnerPolicy), new bytes32[](0)
132
+ );
133
+ policyEngine.addPolicy(
134
+ address(token), ComplianceTokenERC20.burnFrom.selector, address(tokenOnlyOwnerPolicy), new bytes32[](0)
135
+ );
136
+ policyEngine.addPolicy(
137
+ address(token), ComplianceTokenERC20.forceTransfer.selector, address(tokenOnlyOwnerPolicy), new bytes32[](0)
138
+ );
139
+ policyEngine.addPolicy(
140
+ address(token), ComplianceTokenERC20.freeze.selector, address(tokenOnlyOwnerPolicy), new bytes32[](0)
141
+ );
142
+ policyEngine.addPolicy(
143
+ address(token), ComplianceTokenERC20.unfreeze.selector, address(tokenOnlyOwnerPolicy), new bytes32[](0)
144
+ );
145
+
146
+ // Attach an CredentialRegistryIdentityValidatorPolicy to validate the 'to' address of ERC20 transfers
147
+ ERC20TransferExtractor erc20TransferExtractor = new ERC20TransferExtractor();
148
+ policyEngine.setExtractor(ComplianceTokenERC20.transfer.selector, address(erc20TransferExtractor));
149
+ policyEngine.setExtractor(ComplianceTokenERC20.transferFrom.selector, address(erc20TransferExtractor));
150
+
151
+ CredentialRegistryIdentityValidatorPolicy identityValidatorPolicyImpl =
152
+ new CredentialRegistryIdentityValidatorPolicy();
153
+ bytes memory identityValidatorPolicyData = abi.encodeWithSelector(
154
+ Policy.initialize.selector,
155
+ address(policyEngine),
156
+ address(tokenOwner),
157
+ abi.encode(credentialSourceInputs, credentialRequirementInputs)
158
+ );
159
+ ERC1967Proxy identityValidatorPolicyProxy =
160
+ new ERC1967Proxy(address(identityValidatorPolicyImpl), identityValidatorPolicyData);
161
+ CredentialRegistryIdentityValidatorPolicy identityValidatorPolicy =
162
+ CredentialRegistryIdentityValidatorPolicy(address(identityValidatorPolicyProxy));
163
+ bytes32[] memory identityValidatorPolicyParameters = new bytes32[](1);
164
+ identityValidatorPolicyParameters[0] = erc20TransferExtractor.PARAM_TO();
165
+ // Attach the CredentialRegistryIdentityValidatorPolicy to the transfer methods, using the IdentityValidator for
166
+ // validations
167
+ policyEngine.addPolicy(
168
+ address(token),
169
+ ComplianceTokenERC20.transfer.selector,
170
+ address(identityValidatorPolicy),
171
+ identityValidatorPolicyParameters
172
+ );
173
+ policyEngine.addPolicy(
174
+ address(token),
175
+ ComplianceTokenERC20.transferFrom.selector,
176
+ address(identityValidatorPolicy),
177
+ identityValidatorPolicyParameters
178
+ );
179
+
180
+ vm.stopBroadcast();
181
+
182
+ console.log("Deployed ComplianceTokenERC20 at:", address(token));
183
+ console.log("Deployed PolicyEngine at:", address(policyEngine));
184
+ console.log("Deployed IdentityRegistry at:", address(identityRegistry));
185
+ console.log("Deployed CredentialRegistry at:", address(credentialRegistry));
186
+ console.log("Deployed Identity OnlyOwnerPolicy at:", address(identityOnlyOwnerPolicy));
187
+ console.log("Deployed Token OnlyOwnerPolicy at:", address(tokenOnlyOwnerPolicy));
188
+ console.log("Deployed ERC20TransferExtractor at:", address(erc20TransferExtractor));
189
+ console.log("Deployed CredentialRegistryIdentityValidatorPolicy at:", address(identityValidatorPolicy));
190
+ }
191
+ }
@@ -0,0 +1,208 @@
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 {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
6
+ import {ComplianceTokenERC3643} from "../packages/tokens/erc-3643/src/ComplianceTokenERC3643.sol";
7
+ import {PolicyEngine} from "@chainlink/policy-management/core/PolicyEngine.sol";
8
+ import {Policy} from "@chainlink/policy-management/core/Policy.sol";
9
+ import {OnlyOwnerPolicy} from "@chainlink/policy-management/policies/OnlyOwnerPolicy.sol";
10
+ import {IdentityRegistry} from "@chainlink/cross-chain-identity/IdentityRegistry.sol";
11
+ import {CredentialRegistry} from "@chainlink/cross-chain-identity/CredentialRegistry.sol";
12
+ import {CredentialRegistryIdentityValidatorPolicy} from
13
+ "@chainlink/cross-chain-identity/CredentialRegistryIdentityValidatorPolicy.sol";
14
+ import {ICredentialRequirements} from "@chainlink/cross-chain-identity/interfaces/ICredentialRequirements.sol";
15
+
16
+ import {ERC20TransferExtractor} from "@chainlink/policy-management/extractors/ERC20TransferExtractor.sol";
17
+ import {Script} from "forge-std/Script.sol";
18
+ import {console} from "forge-std/console.sol";
19
+
20
+ contract DeployComplianceTokenERC3643 is Script {
21
+ function run() external {
22
+ uint256 tokenOwnerPK = vm.envUint("PRIVATE_KEY");
23
+ address tokenOwner = vm.addr(tokenOwnerPK);
24
+
25
+ vm.startBroadcast(tokenOwnerPK);
26
+
27
+ // Deploy a PolicyEngine through proxy for identity registries and attach OnlyOwnerPolicy to administrative methods
28
+ PolicyEngine policyEngineImpl = new PolicyEngine();
29
+ bytes memory policyEngineData =
30
+ abi.encodeWithSelector(PolicyEngine.initialize.selector, IPolicyEngine.PolicyResult.Allowed);
31
+ ERC1967Proxy policyEngineProxy = new ERC1967Proxy(address(policyEngineImpl), policyEngineData);
32
+ PolicyEngine policyEngine = PolicyEngine(address(policyEngineProxy));
33
+
34
+ // Deploy IdentityRegistry/CredentialRegistry through proxies and an IdentityValidator for use by the
35
+ // CredentialRegistryIdentityValidatorPolicy
36
+ IdentityRegistry identityRegistryImpl = new IdentityRegistry();
37
+ bytes memory identityRegistryData =
38
+ abi.encodeWithSelector(IdentityRegistry.initialize.selector, address(policyEngine));
39
+ ERC1967Proxy identityRegistryProxy = new ERC1967Proxy(address(identityRegistryImpl), identityRegistryData);
40
+ IdentityRegistry identityRegistry = IdentityRegistry(address(identityRegistryProxy));
41
+
42
+ CredentialRegistry credentialRegistryImpl = new CredentialRegistry();
43
+ bytes memory credentialRegistryData =
44
+ abi.encodeWithSelector(CredentialRegistry.initialize.selector, address(policyEngine));
45
+ ERC1967Proxy credentialRegistryProxy = new ERC1967Proxy(address(credentialRegistryImpl), credentialRegistryData);
46
+ CredentialRegistry credentialRegistry = CredentialRegistry(address(credentialRegistryProxy));
47
+ bytes32 CREDENTIAL_KYC = keccak256("common.KYC");
48
+ bytes32[] memory requiredCredentials = new bytes32[](1);
49
+ requiredCredentials[0] = CREDENTIAL_KYC;
50
+
51
+ ICredentialRequirements.CredentialRequirementInput[] memory credentialRequirementInputs =
52
+ new ICredentialRequirements.CredentialRequirementInput[](1);
53
+ credentialRequirementInputs[0] =
54
+ ICredentialRequirements.CredentialRequirementInput(keccak256("requirement.KYC"), requiredCredentials, 1, false);
55
+
56
+ ICredentialRequirements.CredentialSourceInput[] memory credentialSourceInputs =
57
+ new ICredentialRequirements.CredentialSourceInput[](1);
58
+ credentialSourceInputs[0] = ICredentialRequirements.CredentialSourceInput(
59
+ CREDENTIAL_KYC, address(identityRegistry), address(credentialRegistry), address(0)
60
+ );
61
+
62
+ OnlyOwnerPolicy identityOnlyOwnerPolicyImpl = new OnlyOwnerPolicy();
63
+ bytes memory onlyOwnerPolicyData =
64
+ abi.encodeWithSelector(Policy.initialize.selector, address(policyEngine), tokenOwner, new bytes(0));
65
+ ERC1967Proxy identityOnlyOwnerPolicyProxy =
66
+ new ERC1967Proxy(address(identityOnlyOwnerPolicyImpl), onlyOwnerPolicyData);
67
+ OnlyOwnerPolicy identityOnlyOwnerPolicy = OnlyOwnerPolicy(address(identityOnlyOwnerPolicyProxy));
68
+ policyEngine.addPolicy(
69
+ address(identityRegistry),
70
+ IdentityRegistry.registerIdentity.selector,
71
+ address(identityOnlyOwnerPolicy),
72
+ new bytes32[](0)
73
+ );
74
+ policyEngine.addPolicy(
75
+ address(identityRegistry),
76
+ IdentityRegistry.registerIdentities.selector,
77
+ address(identityOnlyOwnerPolicy),
78
+ new bytes32[](0)
79
+ );
80
+ policyEngine.addPolicy(
81
+ address(identityRegistry),
82
+ IdentityRegistry.removeIdentity.selector,
83
+ address(identityOnlyOwnerPolicy),
84
+ new bytes32[](0)
85
+ );
86
+ policyEngine.addPolicy(
87
+ address(credentialRegistry),
88
+ CredentialRegistry.registerCredential.selector,
89
+ address(identityOnlyOwnerPolicy),
90
+ new bytes32[](0)
91
+ );
92
+ policyEngine.addPolicy(
93
+ address(credentialRegistry),
94
+ CredentialRegistry.registerCredentials.selector,
95
+ address(identityOnlyOwnerPolicy),
96
+ new bytes32[](0)
97
+ );
98
+ policyEngine.addPolicy(
99
+ address(credentialRegistry),
100
+ CredentialRegistry.removeCredential.selector,
101
+ address(identityOnlyOwnerPolicy),
102
+ new bytes32[](0)
103
+ );
104
+ policyEngine.addPolicy(
105
+ address(credentialRegistry),
106
+ CredentialRegistry.renewCredential.selector,
107
+ address(identityOnlyOwnerPolicy),
108
+ new bytes32[](0)
109
+ );
110
+
111
+ // Deploy the ComplianceTokenERC3643 through proxy
112
+ ComplianceTokenERC3643 tokenImpl = new ComplianceTokenERC3643();
113
+ bytes memory tokenData = abi.encodeWithSelector(
114
+ ComplianceTokenERC3643.initialize.selector,
115
+ vm.envOr("TOKEN_NAME", string("Token")),
116
+ vm.envOr("TOKEN_SYMBOL", string("TOKEN")),
117
+ 18,
118
+ address(policyEngine)
119
+ );
120
+ ERC1967Proxy tokenProxy = new ERC1967Proxy(address(tokenImpl), tokenData);
121
+ ComplianceTokenERC3643 token = ComplianceTokenERC3643(address(tokenProxy));
122
+
123
+ OnlyOwnerPolicy tokenOnlyOwnerPolicyImpl = new OnlyOwnerPolicy();
124
+ bytes memory tokenOnlyOwnerPolicyData =
125
+ abi.encodeWithSelector(Policy.initialize.selector, address(policyEngine), tokenOwner, new bytes(0));
126
+ ERC1967Proxy tokenOnlyOwnerPolicyProxy =
127
+ new ERC1967Proxy(address(tokenOnlyOwnerPolicyImpl), tokenOnlyOwnerPolicyData);
128
+ OnlyOwnerPolicy tokenOnlyOwnerPolicy = OnlyOwnerPolicy(address(tokenOnlyOwnerPolicyProxy));
129
+ policyEngine.addPolicy(
130
+ address(token), ComplianceTokenERC3643.mint.selector, address(tokenOnlyOwnerPolicy), new bytes32[](0)
131
+ );
132
+ policyEngine.addPolicy(
133
+ address(token), ComplianceTokenERC3643.pause.selector, address(tokenOnlyOwnerPolicy), new bytes32[](0)
134
+ );
135
+ policyEngine.addPolicy(
136
+ address(token), ComplianceTokenERC3643.unpause.selector, address(tokenOnlyOwnerPolicy), new bytes32[](0)
137
+ );
138
+ policyEngine.addPolicy(
139
+ address(token), ComplianceTokenERC3643.setAddressFrozen.selector, address(tokenOnlyOwnerPolicy), new bytes32[](0)
140
+ );
141
+ policyEngine.addPolicy(
142
+ address(token), ComplianceTokenERC3643.forcedTransfer.selector, address(tokenOnlyOwnerPolicy), new bytes32[](0)
143
+ );
144
+ policyEngine.addPolicy(
145
+ address(token),
146
+ ComplianceTokenERC3643.freezePartialTokens.selector,
147
+ address(tokenOnlyOwnerPolicy),
148
+ new bytes32[](0)
149
+ );
150
+ policyEngine.addPolicy(
151
+ address(token),
152
+ ComplianceTokenERC3643.unfreezePartialTokens.selector,
153
+ address(tokenOnlyOwnerPolicy),
154
+ new bytes32[](0)
155
+ );
156
+ policyEngine.addPolicy(
157
+ address(token), ComplianceTokenERC3643.setName.selector, address(tokenOnlyOwnerPolicy), new bytes32[](0)
158
+ );
159
+ policyEngine.addPolicy(
160
+ address(token), ComplianceTokenERC3643.setSymbol.selector, address(tokenOnlyOwnerPolicy), new bytes32[](0)
161
+ );
162
+
163
+ // Attach an CredentialRegistryIdentityValidatorPolicy to validate the 'to' address of ERC20 transfers
164
+ ERC20TransferExtractor erc20TransferExtractor = new ERC20TransferExtractor();
165
+ policyEngine.setExtractor(ComplianceTokenERC3643.transfer.selector, address(erc20TransferExtractor));
166
+ policyEngine.setExtractor(ComplianceTokenERC3643.transferFrom.selector, address(erc20TransferExtractor));
167
+
168
+ CredentialRegistryIdentityValidatorPolicy identityValidatorPolicyImpl =
169
+ new CredentialRegistryIdentityValidatorPolicy();
170
+ bytes memory identityValidatorPolicyData = abi.encodeWithSelector(
171
+ Policy.initialize.selector,
172
+ address(policyEngine),
173
+ address(tokenOwner),
174
+ abi.encode(credentialSourceInputs, credentialRequirementInputs)
175
+ );
176
+ ERC1967Proxy identityValidatorPolicyProxy =
177
+ new ERC1967Proxy(address(identityValidatorPolicyImpl), identityValidatorPolicyData);
178
+ CredentialRegistryIdentityValidatorPolicy identityValidatorPolicy =
179
+ CredentialRegistryIdentityValidatorPolicy(address(identityValidatorPolicyProxy));
180
+ bytes32[] memory identityValidatorPolicyParameters = new bytes32[](1);
181
+ identityValidatorPolicyParameters[0] = erc20TransferExtractor.PARAM_TO();
182
+ // Attach the CredentialRegistryIdentityValidatorPolicy to the transfer methods, using the IdentityValidator for
183
+ // validations
184
+ policyEngine.addPolicy(
185
+ address(token),
186
+ ComplianceTokenERC3643.transfer.selector,
187
+ address(identityValidatorPolicy),
188
+ identityValidatorPolicyParameters
189
+ );
190
+ policyEngine.addPolicy(
191
+ address(token),
192
+ ComplianceTokenERC3643.transferFrom.selector,
193
+ address(identityValidatorPolicy),
194
+ identityValidatorPolicyParameters
195
+ );
196
+
197
+ vm.stopBroadcast();
198
+
199
+ console.log("Deployed ComplianceTokenERC3643 at:", address(token));
200
+ console.log("Deployed PolicyEngine at:", address(policyEngine));
201
+ console.log("Deployed IdentityRegistry at:", address(identityRegistry));
202
+ console.log("Deployed CredentialRegistry at:", address(credentialRegistry));
203
+ console.log("Deployed Identity OnlyOwnerPolicy at:", address(identityOnlyOwnerPolicy));
204
+ console.log("Deployed Token OnlyOwnerPolicy at:", address(tokenOnlyOwnerPolicy));
205
+ console.log("Deployed ERC20TransferExtractor at:", address(erc20TransferExtractor));
206
+ console.log("Deployed CredentialRegistryIdentityValidatorPolicy at:", address(identityValidatorPolicy));
207
+ }
208
+ }
@@ -0,0 +1,38 @@
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 {ComplianceTokenERC3643} from "../packages/tokens/erc-3643/src/ComplianceTokenERC3643.sol";
6
+ import {Script} from "forge-std/Script.sol";
7
+ import {console} from "forge-std/console.sol";
8
+
9
+ contract DeploySimpleComplianceToken is Script {
10
+ function run() external {
11
+ uint256 tokenOwnerPK = vm.envUint("PRIVATE_KEY");
12
+ address tokenOwner = vm.addr(tokenOwnerPK);
13
+
14
+ vm.startBroadcast(tokenOwnerPK);
15
+
16
+ // Deploy the ComplianceToken through proxy
17
+ ComplianceTokenERC3643 tokenImpl = new ComplianceTokenERC3643();
18
+ bytes memory tokenData = abi.encodeWithSelector(
19
+ ComplianceTokenERC3643.initialize.selector,
20
+ vm.envOr("TOKEN_NAME", string("Token")),
21
+ vm.envOr("TOKEN_SYMBOL", string("TOKEN")),
22
+ 18,
23
+ vm.envAddress("POLICY_ENGINE")
24
+ );
25
+ ERC1967Proxy tokenProxy = new ERC1967Proxy(address(tokenImpl), tokenData);
26
+ ComplianceTokenERC3643 token = ComplianceTokenERC3643(address(tokenProxy));
27
+
28
+ uint256 initialSupply = vm.envOr("INITIAL_SUPPLY", uint256(1000000));
29
+ address initialHolder = vm.envOr("INITIAL_HOLDER", address(0));
30
+ if (initialHolder != address(0)) {
31
+ token.mint(initialHolder, initialSupply * 10 ** token.decimals());
32
+ }
33
+
34
+ vm.stopBroadcast();
35
+
36
+ console.log("ComplianceToken deployed at:", address(token));
37
+ }
38
+ }
@@ -0,0 +1,74 @@
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
+ import {MyVault} from "../../getting_started/MyVault.sol";
8
+ import {PolicyEngine} from "@chainlink/policy-management/core/PolicyEngine.sol";
9
+ import {Policy} from "@chainlink/policy-management/core/Policy.sol";
10
+ import {PausePolicy} from "@chainlink/policy-management/policies/PausePolicy.sol";
11
+ import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
12
+
13
+ /**
14
+ * @title DeployGettingStarted
15
+ * @notice Deployment script for the Getting Started guide example.
16
+ * @dev This script demonstrates the complete setup process:
17
+ * 1. Deploy and initialize a PolicyEngine through a proxy
18
+ * 2. Deploy the vault contract (connected to PolicyEngine via constructor)
19
+ * 3. Deploy and configure a PausePolicy
20
+ * 4. Attach the policy to the vault's deposit and withdraw functions
21
+ */
22
+ contract DeployGettingStarted is Script {
23
+ function run() external {
24
+ uint256 deployerPK = vm.envUint("PRIVATE_KEY");
25
+ address deployer = vm.addr(deployerPK);
26
+
27
+ vm.startBroadcast(deployerPK);
28
+
29
+ // 1. Deploy the PolicyEngine through a proxy
30
+ PolicyEngine policyEngineImpl = new PolicyEngine();
31
+ bytes memory policyEngineData = abi.encodeWithSelector(PolicyEngine.initialize.selector, true, deployer);
32
+ ERC1967Proxy policyEngineProxy = new ERC1967Proxy(address(policyEngineImpl), policyEngineData);
33
+ PolicyEngine policyEngine = PolicyEngine(address(policyEngineProxy));
34
+
35
+ // 2. Deploy your vault through a proxy
36
+ MyVault vaultImpl = new MyVault();
37
+ bytes memory vaultData = abi.encodeWithSelector(MyVault.initialize.selector, deployer, address(policyEngine));
38
+ ERC1967Proxy vaultProxy = new ERC1967Proxy(address(vaultImpl), vaultData);
39
+ MyVault vault = MyVault(address(vaultProxy));
40
+
41
+ // 3. Deploy the PausePolicy through a proxy
42
+ PausePolicy pausePolicyImpl = new PausePolicy();
43
+ bytes memory pausePolicyConfig = abi.encode(false); // Not paused by default
44
+ bytes memory pausePolicyData =
45
+ abi.encodeWithSelector(Policy.initialize.selector, address(policyEngine), deployer, pausePolicyConfig);
46
+ ERC1967Proxy pausePolicyProxy = new ERC1967Proxy(address(pausePolicyImpl), pausePolicyData);
47
+ PausePolicy pausePolicy = PausePolicy(address(pausePolicyProxy));
48
+
49
+ // 4. Add the PausePolicy to the vault's deposit function
50
+ policyEngine.addPolicy(
51
+ address(vault),
52
+ vault.deposit.selector,
53
+ address(pausePolicy),
54
+ new bytes32[](0) // No parameters needed for
55
+ // PausePolicy
56
+ );
57
+
58
+ // 5. Add the PausePolicy to the vault's withdraw function
59
+ policyEngine.addPolicy(
60
+ address(vault),
61
+ vault.withdraw.selector,
62
+ address(pausePolicy),
63
+ new bytes32[](0) // No parameters needed for
64
+ // PausePolicy
65
+ );
66
+
67
+ vm.stopBroadcast();
68
+
69
+ console.log("--- Deployed Contracts ---");
70
+ console.log("MyVault deployed at:", address(vault));
71
+ console.log("PolicyEngine deployed at:", address(policyEngine));
72
+ console.log("PausePolicy deployed at:", address(pausePolicy));
73
+ }
74
+ }