@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,54 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity 0.8.26;
3
+
4
+ import {IExtractor} from "@chainlink/policy-management/interfaces/IExtractor.sol";
5
+ import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
6
+ import {ComplianceTokenERC20} from "../../../tokens/erc-20/src/ComplianceTokenERC20.sol";
7
+
8
+ /**
9
+ * @title ComplianceTokenFreezeUnfreezeExtractor
10
+ * @notice Extracts parameters from Compliance Token ERC20 freeze and unfreeze function calls.
11
+ * @dev This extractor supports freeze() and unfreeze() function selectors from the ComplianceTokenERC20 contract
12
+ * and extracts the target account address and amount parameters for compliance-related freezing operations.
13
+ */
14
+ contract ComplianceTokenFreezeUnfreezeExtractor is IExtractor {
15
+ /// @notice Parameter key for the target account address in freeze/unfreeze operations
16
+ bytes32 public constant PARAM_ACCOUNT = keccak256("account");
17
+
18
+ /// @notice Parameter key for the amount being frozen or unfrozen
19
+ bytes32 public constant PARAM_AMOUNT = keccak256("amount");
20
+
21
+ /**
22
+ * @notice Extracts parameters from ComplianceTokenERC20 freeze and unfreeze function calls.
23
+ * @dev Supports freeze(address account, uint256 amount) and unfreeze(address account, uint256 amount) functions.
24
+ * Both functions have identical parameter structures.
25
+ * @param payload The policy engine payload containing the function selector and calldata
26
+ * @return An array of two parameters: PARAM_ACCOUNT and PARAM_AMOUNT
27
+ */
28
+ function extract(IPolicyEngine.Payload calldata payload)
29
+ external
30
+ pure
31
+ override
32
+ returns (IPolicyEngine.Parameter[] memory)
33
+ {
34
+ address account = address(0);
35
+ uint256 amount = 0;
36
+
37
+ // Both freeze and unfreeze functions take identical parameters: (address account, uint256 amount)
38
+ if (
39
+ payload.selector == ComplianceTokenERC20.freeze.selector
40
+ || payload.selector == ComplianceTokenERC20.unfreeze.selector
41
+ ) {
42
+ (account, amount) = abi.decode(payload.data, (address, uint256));
43
+ } else {
44
+ revert IPolicyEngine.UnsupportedSelector(payload.selector);
45
+ }
46
+
47
+ // Build the parameter array with extracted values
48
+ IPolicyEngine.Parameter[] memory result = new IPolicyEngine.Parameter[](2);
49
+ result[0] = IPolicyEngine.Parameter(PARAM_ACCOUNT, abi.encode(account));
50
+ result[1] = IPolicyEngine.Parameter(PARAM_AMOUNT, abi.encode(amount));
51
+
52
+ return result;
53
+ }
54
+ }
@@ -0,0 +1,61 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity 0.8.26;
3
+
4
+ import {IExtractor} from "@chainlink/policy-management/interfaces/IExtractor.sol";
5
+ import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
6
+ import {ComplianceTokenERC20} from "../../../tokens/erc-20/src/ComplianceTokenERC20.sol";
7
+
8
+ /**
9
+ * @title ComplianceTokenMintBurnExtractor
10
+ * @notice Extracts parameters from Compliance Token ERC20 mint and burn function calls.
11
+ * @dev This extractor supports mint(), burn(), and burnFrom() function selectors from the
12
+ * ComplianceTokenERC20 contract and extracts the account and amount parameters.
13
+ * For burn(), the account is set to msg.sender since it burns from the caller's balance.
14
+ */
15
+ contract ComplianceTokenMintBurnExtractor is IExtractor {
16
+ /// @notice Parameter key for the target account address in mint/burn operations
17
+ bytes32 public constant PARAM_ACCOUNT = keccak256("account");
18
+
19
+ /// @notice Parameter key for the amount being minted or burned
20
+ bytes32 public constant PARAM_AMOUNT = keccak256("amount");
21
+
22
+ /**
23
+ * @notice Extracts parameters from ComplianceTokenERC20 mint, burn, and burnFrom function calls.
24
+ * @dev Handles three function signatures:
25
+ * - mint(address account, uint256 amount): account and amount from calldata
26
+ * - burnFrom(address account, uint256 amount): account and amount from calldata
27
+ * - burn(uint256 amount): account = msg.sender, amount from calldata
28
+ * @param payload The policy engine payload containing the function selector and calldata
29
+ * @return An array of two parameters: PARAM_ACCOUNT and PARAM_AMOUNT
30
+ */
31
+ function extract(IPolicyEngine.Payload calldata payload)
32
+ external
33
+ pure
34
+ override
35
+ returns (IPolicyEngine.Parameter[] memory)
36
+ {
37
+ uint256 amount = 0;
38
+ address account;
39
+
40
+ // Handle mint(address account, uint256 amount) and burnFrom(address account, uint256 amount)
41
+ if (
42
+ payload.selector == ComplianceTokenERC20.mint.selector
43
+ || payload.selector == ComplianceTokenERC20.burnFrom.selector
44
+ ) {
45
+ (account, amount) = abi.decode(payload.data, (address, uint256));
46
+ // Handle burn(uint256 amount) - account is the sender
47
+ } else if (payload.selector == ComplianceTokenERC20.burn.selector) {
48
+ account = payload.sender;
49
+ (amount) = abi.decode(payload.data, (uint256));
50
+ } else {
51
+ revert IPolicyEngine.UnsupportedSelector(payload.selector);
52
+ }
53
+
54
+ // Build the parameter array with extracted values
55
+ IPolicyEngine.Parameter[] memory result = new IPolicyEngine.Parameter[](2);
56
+ result[0] = IPolicyEngine.Parameter(PARAM_ACCOUNT, abi.encode(account));
57
+ result[1] = IPolicyEngine.Parameter(PARAM_AMOUNT, abi.encode(amount));
58
+
59
+ return result;
60
+ }
61
+ }
@@ -0,0 +1,57 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity 0.8.26;
3
+
4
+ import {IExtractor} from "@chainlink/policy-management/interfaces/IExtractor.sol";
5
+ import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
6
+ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
7
+
8
+ /**
9
+ * @title ERC20ApproveExtractor
10
+ * @notice Extracts parameters from ERC20 token approve function calls.
11
+ * @dev This extractor supports the approve() function selector and extracts the account (msg.sender),
12
+ * spender address, and amount parameters from the function calldata.
13
+ */
14
+ contract ERC20ApproveExtractor is IExtractor {
15
+ /// @notice Parameter key for the account granting the approval (msg.sender)
16
+ bytes32 public constant PARAM_ACCOUNT = keccak256("account");
17
+
18
+ /// @notice Parameter key for the spender address being approved
19
+ bytes32 public constant PARAM_SPENDER = keccak256("spender");
20
+
21
+ /// @notice Parameter key for the amount being approved
22
+ bytes32 public constant PARAM_AMOUNT = keccak256("amount");
23
+
24
+ /**
25
+ * @inheritdoc IExtractor
26
+ * @dev Extracts parameters from ERC20 approve(address spender, uint256 amount) function calls.
27
+ * The account parameter is set to msg.sender since approve is called by the token owner.
28
+ * @param payload The policy engine payload containing the function selector and calldata
29
+ * @return An array of three parameters: PARAM_ACCOUNT, PARAM_SPENDER, and PARAM_AMOUNT
30
+ */
31
+ function extract(IPolicyEngine.Payload calldata payload)
32
+ public
33
+ pure
34
+ virtual
35
+ returns (IPolicyEngine.Parameter[] memory)
36
+ {
37
+ address account = address(0);
38
+ address spender = address(0);
39
+ uint256 amount = 0;
40
+
41
+ // Handle approve(address spender, uint256 amount) - account is the sender
42
+ if (payload.selector == IERC20.approve.selector) {
43
+ account = payload.sender;
44
+ (spender, amount) = abi.decode(payload.data, (address, uint256));
45
+ } else {
46
+ revert IPolicyEngine.UnsupportedSelector(payload.selector);
47
+ }
48
+
49
+ // Build the parameter array with extracted values
50
+ IPolicyEngine.Parameter[] memory result = new IPolicyEngine.Parameter[](3);
51
+ result[0] = IPolicyEngine.Parameter(PARAM_ACCOUNT, abi.encode(account));
52
+ result[1] = IPolicyEngine.Parameter(PARAM_SPENDER, abi.encode(spender));
53
+ result[2] = IPolicyEngine.Parameter(PARAM_AMOUNT, abi.encode(amount));
54
+
55
+ return result;
56
+ }
57
+ }
@@ -0,0 +1,62 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity 0.8.26;
3
+
4
+ import {IExtractor} from "@chainlink/policy-management/interfaces/IExtractor.sol";
5
+ import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
6
+ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
7
+
8
+ /**
9
+ * @title ERC20TransferExtractor
10
+ * @notice Extracts transfer parameters from ERC20 token transfer and transferFrom function calls.
11
+ * @dev This extractor supports both transfer() and transferFrom() function selectors and extracts
12
+ * the from address, to address, and amount parameters. For transfer() calls, the from address
13
+ * is set to the transaction sender (msg.sender).
14
+ */
15
+ contract ERC20TransferExtractor is IExtractor {
16
+ /// @notice Parameter key for the sender/from address in transfer operations
17
+ bytes32 public constant PARAM_FROM = keccak256("from");
18
+
19
+ /// @notice Parameter key for the recipient/to address in transfer operations
20
+ bytes32 public constant PARAM_TO = keccak256("to");
21
+
22
+ /// @notice Parameter key for the amount being transferred
23
+ bytes32 public constant PARAM_AMOUNT = keccak256("amount");
24
+
25
+ /**
26
+ * @inheritdoc IExtractor
27
+ * @dev Extracts parameters from ERC20 transfer and transferFrom function calls.
28
+ * - For transfer(address to, uint256 amount): from = msg.sender
29
+ * - For transferFrom(address from, address to, uint256 amount): from = decoded from parameter
30
+ * @param payload The policy engine payload containing the function selector and calldata
31
+ * @return An array of three parameters: PARAM_FROM, PARAM_TO, and PARAM_AMOUNT
32
+ */
33
+ function extract(IPolicyEngine.Payload calldata payload)
34
+ public
35
+ pure
36
+ virtual
37
+ returns (IPolicyEngine.Parameter[] memory)
38
+ {
39
+ address from = address(0);
40
+ address to = address(0);
41
+ uint256 amount = 0;
42
+
43
+ // Handle transfer(address to, uint256 amount) - from is the sender
44
+ if (payload.selector == IERC20.transfer.selector) {
45
+ from = payload.sender;
46
+ (to, amount) = abi.decode(payload.data, (address, uint256));
47
+ // Handle transferFrom(address from, address to, uint256 amount)
48
+ } else if (payload.selector == IERC20.transferFrom.selector) {
49
+ (from, to, amount) = abi.decode(payload.data, (address, address, uint256));
50
+ } else {
51
+ revert IPolicyEngine.UnsupportedSelector(payload.selector);
52
+ }
53
+
54
+ // Build the parameter array with extracted values
55
+ IPolicyEngine.Parameter[] memory result = new IPolicyEngine.Parameter[](3);
56
+ result[0] = IPolicyEngine.Parameter(PARAM_FROM, abi.encode(from));
57
+ result[1] = IPolicyEngine.Parameter(PARAM_TO, abi.encode(to));
58
+ result[2] = IPolicyEngine.Parameter(PARAM_AMOUNT, abi.encode(amount));
59
+
60
+ return result;
61
+ }
62
+ }
@@ -0,0 +1,56 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity 0.8.26;
3
+
4
+ import {IExtractor} from "@chainlink/policy-management/interfaces/IExtractor.sol";
5
+ import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
6
+ import {IToken} from "../../../vendor/erc-3643/token/IToken.sol";
7
+
8
+ /**
9
+ * @title ERC3643ForcedTransferExtractor
10
+ * @notice Extracts parameters from ERC3643 token forced transfer function calls.
11
+ * @dev This extractor supports the forcedTransfer() function selector from the ERC3643 token standard
12
+ * and extracts the from address, to address, and amount parameters from the function calldata.
13
+ * Forced transfers allow authorized agents to move tokens between addresses without approval.
14
+ */
15
+ contract ERC3643ForcedTransferExtractor is IExtractor {
16
+ /// @notice Parameter key for the sender/from address in forced transfer operations
17
+ bytes32 public constant PARAM_FROM = keccak256("from");
18
+
19
+ /// @notice Parameter key for the recipient/to address in forced transfer operations
20
+ bytes32 public constant PARAM_TO = keccak256("to");
21
+
22
+ /// @notice Parameter key for the amount being forcefully transferred
23
+ bytes32 public constant PARAM_AMOUNT = keccak256("amount");
24
+
25
+ /**
26
+ * @inheritdoc IExtractor
27
+ * @dev Extracts parameters from ERC3643 forcedTransfer(address from, address to, uint256 amount) function calls.
28
+ * @param payload The policy engine payload containing the function selector and calldata
29
+ * @return An array of three parameters: PARAM_FROM, PARAM_TO, and PARAM_AMOUNT
30
+ */
31
+ function extract(IPolicyEngine.Payload calldata payload)
32
+ public
33
+ pure
34
+ virtual
35
+ returns (IPolicyEngine.Parameter[] memory)
36
+ {
37
+ address from = address(0);
38
+ address to = address(0);
39
+ uint256 amount = 0;
40
+
41
+ // Handle forcedTransfer(address from, address to, uint256 amount)
42
+ if (payload.selector == IToken.forcedTransfer.selector) {
43
+ (from, to, amount) = abi.decode(payload.data, (address, address, uint256));
44
+ } else {
45
+ revert IPolicyEngine.UnsupportedSelector(payload.selector);
46
+ }
47
+
48
+ // Build the parameter array with extracted values
49
+ IPolicyEngine.Parameter[] memory result = new IPolicyEngine.Parameter[](3);
50
+ result[0] = IPolicyEngine.Parameter(PARAM_FROM, abi.encode(from));
51
+ result[1] = IPolicyEngine.Parameter(PARAM_TO, abi.encode(to));
52
+ result[2] = IPolicyEngine.Parameter(PARAM_AMOUNT, abi.encode(amount));
53
+
54
+ return result;
55
+ }
56
+ }
@@ -0,0 +1,55 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity 0.8.26;
3
+
4
+ import {IExtractor} from "@chainlink/policy-management/interfaces/IExtractor.sol";
5
+ import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
6
+ import {IToken} from "../../../vendor/erc-3643/token/IToken.sol";
7
+
8
+ /**
9
+ * @title ERC3643FreezeUnfreezeExtractor
10
+ * @notice Extracts parameters from ERC3643 token partial freeze and unfreeze function calls.
11
+ * @dev This extractor supports freezePartialTokens() and unfreezePartialTokens() function selectors
12
+ * from the ERC3643 token standard and extracts the target account address and amount parameters.
13
+ */
14
+ contract ERC3643FreezeUnfreezeExtractor is IExtractor {
15
+ /// @notice Parameter key for the target account address in freeze/unfreeze operations
16
+ bytes32 public constant PARAM_ACCOUNT = keccak256("account");
17
+
18
+ /// @notice Parameter key for the amount being frozen or unfrozen
19
+ bytes32 public constant PARAM_AMOUNT = keccak256("amount");
20
+
21
+ /**
22
+ * @notice Extracts parameters from ERC3643 partial freeze and unfreeze function calls.
23
+ * @dev Supports freezePartialTokens(address account, uint256 amount) and
24
+ * unfreezePartialTokens(address account, uint256 amount) functions.
25
+ * Both functions have identical parameter structures.
26
+ * @param payload The policy engine payload containing the function selector and calldata
27
+ * @return An array of two parameters: PARAM_ACCOUNT and PARAM_AMOUNT
28
+ */
29
+ function extract(IPolicyEngine.Payload calldata payload)
30
+ external
31
+ pure
32
+ override
33
+ returns (IPolicyEngine.Parameter[] memory)
34
+ {
35
+ address account = address(0);
36
+ uint256 amount = 0;
37
+
38
+ // Both freeze and unfreeze functions have the same signature: (address account, uint256 amount)
39
+ if (
40
+ payload.selector == IToken.freezePartialTokens.selector
41
+ || payload.selector == IToken.unfreezePartialTokens.selector
42
+ ) {
43
+ (account, amount) = abi.decode(payload.data, (address, uint256));
44
+ } else {
45
+ revert IPolicyEngine.UnsupportedSelector(payload.selector);
46
+ }
47
+
48
+ // Build the parameter array with extracted values
49
+ IPolicyEngine.Parameter[] memory result = new IPolicyEngine.Parameter[](2);
50
+ result[0] = IPolicyEngine.Parameter(PARAM_ACCOUNT, abi.encode(account));
51
+ result[1] = IPolicyEngine.Parameter(PARAM_AMOUNT, abi.encode(amount));
52
+
53
+ return result;
54
+ }
55
+ }
@@ -0,0 +1,51 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity 0.8.26;
3
+
4
+ import {IExtractor} from "@chainlink/policy-management/interfaces/IExtractor.sol";
5
+ import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
6
+ import {IToken} from "../../../vendor/erc-3643/token/IToken.sol";
7
+
8
+ /**
9
+ * @title ERC3643MintBurnExtractor
10
+ * @notice Extracts parameters from ERC3643 token mint and burn function calls.
11
+ * @dev This extractor supports both mint() and burn() function selectors from the ERC3643 token standard
12
+ * and extracts the target account address and amount parameters from the function calldata.
13
+ */
14
+ contract ERC3643MintBurnExtractor is IExtractor {
15
+ /// @notice Parameter key for the target account address in mint/burn operations
16
+ bytes32 public constant PARAM_ACCOUNT = keccak256("account");
17
+
18
+ /// @notice Parameter key for the amount being minted or burned
19
+ bytes32 public constant PARAM_AMOUNT = keccak256("amount");
20
+
21
+ /**
22
+ * @notice Extracts parameters from ERC3643 mint and burn function calls.
23
+ * @dev Supports mint(address account, uint256 amount) and burn(address account, uint256 amount) functions.
24
+ * Both functions have identical parameter structures, so they can be handled with the same decoding logic.
25
+ * @param payload The policy engine payload containing the function selector and calldata
26
+ * @return An array of two parameters: PARAM_ACCOUNT and PARAM_AMOUNT
27
+ */
28
+ function extract(IPolicyEngine.Payload calldata payload)
29
+ external
30
+ pure
31
+ override
32
+ returns (IPolicyEngine.Parameter[] memory)
33
+ {
34
+ uint256 amount = 0;
35
+ address account;
36
+
37
+ // Both mint and burn functions have the same signature: (address account, uint256 amount)
38
+ if (payload.selector == IToken.mint.selector || payload.selector == IToken.burn.selector) {
39
+ (account, amount) = abi.decode(payload.data, (address, uint256));
40
+ } else {
41
+ revert IPolicyEngine.UnsupportedSelector(payload.selector);
42
+ }
43
+
44
+ // Build the parameter array with extracted values
45
+ IPolicyEngine.Parameter[] memory result = new IPolicyEngine.Parameter[](2);
46
+ result[0] = IPolicyEngine.Parameter(PARAM_ACCOUNT, abi.encode(account));
47
+ result[1] = IPolicyEngine.Parameter(PARAM_AMOUNT, abi.encode(amount));
48
+
49
+ return result;
50
+ }
51
+ }
@@ -0,0 +1,51 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity 0.8.26;
3
+
4
+ import {IExtractor} from "@chainlink/policy-management/interfaces/IExtractor.sol";
5
+ import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
6
+ import {IToken} from "../../../vendor/erc-3643/token/IToken.sol";
7
+
8
+ /**
9
+ * @title ERC3643SetAddressFrozenExtractor
10
+ * @notice Extracts parameters from ERC3643 token address freeze/unfreeze function calls.
11
+ * @dev This extractor supports the setAddressFrozen() function selector from the ERC3643 token standard
12
+ * and extracts the target account address and freeze status (boolean value) parameters.
13
+ */
14
+ contract ERC3643SetAddressFrozenExtractor is IExtractor {
15
+ /// @notice Parameter key for the target account address in freeze/unfreeze operations
16
+ bytes32 public constant PARAM_ACCOUNT = keccak256("account");
17
+
18
+ /// @notice Parameter key for the freeze status boolean value (true = frozen, false = unfrozen)
19
+ bytes32 public constant PARAM_VALUE = keccak256("value");
20
+
21
+ /**
22
+ * @notice Extracts parameters from ERC3643 setAddressFrozen function calls.
23
+ * @dev Extracts parameters from setAddressFrozen(address account, bool value) function calls.
24
+ * The value parameter indicates whether to freeze (true) or unfreeze (false) the address.
25
+ * @param payload The policy engine payload containing the function selector and calldata
26
+ * @return An array of two parameters: PARAM_ACCOUNT and PARAM_VALUE
27
+ */
28
+ function extract(IPolicyEngine.Payload calldata payload)
29
+ external
30
+ pure
31
+ override
32
+ returns (IPolicyEngine.Parameter[] memory)
33
+ {
34
+ address account = address(0);
35
+ bool value;
36
+
37
+ // Handle setAddressFrozen(address account, bool value)
38
+ if (payload.selector == IToken.setAddressFrozen.selector) {
39
+ (account, value) = abi.decode(payload.data, (address, bool));
40
+ } else {
41
+ revert IPolicyEngine.UnsupportedSelector(payload.selector);
42
+ }
43
+
44
+ // Build the parameter array with extracted values
45
+ IPolicyEngine.Parameter[] memory result = new IPolicyEngine.Parameter[](2);
46
+ result[0] = IPolicyEngine.Parameter(PARAM_ACCOUNT, abi.encode(account));
47
+ result[1] = IPolicyEngine.Parameter(PARAM_VALUE, abi.encode(value));
48
+
49
+ return result;
50
+ }
51
+ }
@@ -0,0 +1,17 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity ^0.8.20;
3
+
4
+ import {IPolicyEngine} from "./IPolicyEngine.sol";
5
+
6
+ /**
7
+ * @title IExtractor
8
+ * @dev Interface for extracting parameters from a payload.
9
+ */
10
+ interface IExtractor {
11
+ /**
12
+ * @notice Extracts parameters from a payload.
13
+ * @param payload The payload to extract parameters from.
14
+ * @return The extracted parameters.
15
+ */
16
+ function extract(IPolicyEngine.Payload calldata payload) external view returns (IPolicyEngine.Parameter[] memory);
17
+ }
@@ -0,0 +1,17 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity ^0.8.20;
3
+
4
+ import {IPolicyEngine} from "./IPolicyEngine.sol";
5
+
6
+ /**
7
+ * @title IMapper
8
+ * @dev Interface for mapping extracted parameters to a list of policy parameters.
9
+ */
10
+ interface IMapper {
11
+ /**
12
+ * @notice Maps extracted parameters to a list of policy parameters.
13
+ * @param extractedParameters The extracted parameters.
14
+ * @return The mapped parameters.
15
+ */
16
+ function map(IPolicyEngine.Parameter[] calldata extractedParameters) external view returns (bytes[] memory);
17
+ }
@@ -0,0 +1,61 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity ^0.8.20;
3
+
4
+ import {IPolicyEngine} from "./IPolicyEngine.sol";
5
+ import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
6
+
7
+ /**
8
+ * @title IPolicy
9
+ * @dev Interface for running a policy.
10
+ */
11
+ interface IPolicy is IERC165 {
12
+ /**
13
+ * @notice Hook called upon installation of the policy.
14
+ * @param selector The selector of the policy.
15
+ */
16
+ function onInstall(bytes4 selector) external;
17
+
18
+ /**
19
+ * @notice Hook called upon uninstallation of the policy.
20
+ * @param selector The selector of the policy.
21
+ */
22
+ function onUninstall(bytes4 selector) external;
23
+
24
+ /**
25
+ * @notice Runs the policy.
26
+ * @param caller The address of the account which is calling the subject protected by the policy engine.
27
+ * @param subject The address of the contract which is being protected by the policy engine.
28
+ * @param selector The selector of the method being called on the protected contract.
29
+ * @param parameters The parameters to use for running the policy.
30
+ * @param context Additional information or authorization to perform the operation.
31
+ * @return The result of running the policy.
32
+ */
33
+ function run(
34
+ address caller,
35
+ address subject,
36
+ bytes4 selector,
37
+ bytes[] calldata parameters,
38
+ bytes calldata context
39
+ )
40
+ external
41
+ view
42
+ returns (IPolicyEngine.PolicyResult);
43
+
44
+ /**
45
+ * @notice Runs after the policy check if the check was successful, and MAY mutate state. State mutations SHOULD
46
+ * consider state relative to the target, as the policy MAY be shared across multiple targets.
47
+ * @param caller The address of the account which is calling the subject protected by the policy engine.
48
+ * @param subject The address of the contract which is being protected by the policy engine.
49
+ * @param selector The selector of the method being called on the protected contract.
50
+ * @param parameters The parameters to use for running the policy.
51
+ * @param context Additional information or authorization to perform the operation.
52
+ */
53
+ function postRun(
54
+ address caller,
55
+ address subject,
56
+ bytes4 selector,
57
+ bytes[] calldata parameters,
58
+ bytes calldata context
59
+ )
60
+ external;
61
+ }