@chainlink/ace 0.5.0 → 1.0.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 (126) hide show
  1. package/.github/workflows/npm-publish.yml +28 -0
  2. package/README.md +9 -1
  3. package/UPGRADE_GUIDE.md +754 -0
  4. package/getting_started/GETTING_STARTED.md +6 -0
  5. package/getting_started/MyVault.sol +2 -2
  6. package/getting_started/advanced/SanctionsPolicy.sol +6 -2
  7. package/package.json +3 -3
  8. package/packages/cross-chain-identity/docs/API_REFERENCE.md +2 -0
  9. package/packages/cross-chain-identity/src/CredentialRegistry.sol +9 -7
  10. package/packages/cross-chain-identity/src/CredentialRegistryFactory.sol +96 -0
  11. package/packages/cross-chain-identity/src/CredentialRegistryIdentityValidator.sol +15 -4
  12. package/packages/cross-chain-identity/src/CredentialRegistryIdentityValidatorPolicy.sol +10 -7
  13. package/packages/cross-chain-identity/src/IdentityRegistry.sol +33 -17
  14. package/packages/cross-chain-identity/src/IdentityRegistryFactory.sol +96 -0
  15. package/packages/cross-chain-identity/src/TrustedIssuerRegistry.sol +8 -6
  16. package/packages/cross-chain-identity/src/TrustedIssuerRegistryFactory.sol +96 -0
  17. package/packages/cross-chain-identity/src/interfaces/ICredentialRegistry.sol +6 -0
  18. package/packages/cross-chain-identity/src/interfaces/ICredentialRequirements.sol +2 -1
  19. package/packages/cross-chain-identity/src/interfaces/IIdentityRegistry.sol +7 -1
  20. package/packages/cross-chain-identity/src/interfaces/ITrustedIssuerRegistry.sol +6 -0
  21. package/packages/cross-chain-identity/test/CredentialRegistry.t.sol +1 -1
  22. package/packages/cross-chain-identity/test/CredentialRegistryFactory.t.sol +105 -0
  23. package/packages/cross-chain-identity/test/CredentialRegistryIdentityValidator.t.sol +16 -1
  24. package/packages/cross-chain-identity/test/CredentialRegistryIdentityValidatorPolicy.t.sol +58 -1
  25. package/packages/cross-chain-identity/test/IdentityRegistry.t.sol +140 -1
  26. package/packages/cross-chain-identity/test/IdentityRegistryFactory.t.sol +103 -0
  27. package/packages/cross-chain-identity/test/IdentityValidator.t.sol +1 -1
  28. package/packages/cross-chain-identity/test/TrustedIssuerRegistry.t.sol +1 -1
  29. package/packages/cross-chain-identity/test/TrustedIssuerRegistryFactory.t.sol +107 -0
  30. package/packages/cross-chain-identity/test/helpers/BaseProxyTest.sol +1 -1
  31. package/packages/cross-chain-identity/test/helpers/MockCredentialDataValidator.sol +1 -1
  32. package/packages/cross-chain-identity/test/helpers/MockCredentialRegistryReverting.sol +3 -1
  33. package/packages/policy-management/README.md +1 -0
  34. package/packages/policy-management/docs/API_GUIDE.md +2 -0
  35. package/packages/policy-management/docs/API_REFERENCE.md +3 -1
  36. package/packages/policy-management/docs/CUSTOM_POLICIES_TUTORIAL.md +10 -4
  37. package/packages/policy-management/src/core/Policy.sol +5 -4
  38. package/packages/policy-management/src/core/PolicyEngine.sol +113 -57
  39. package/packages/policy-management/src/core/PolicyEngineFactory.sol +102 -0
  40. package/packages/policy-management/src/core/PolicyFactory.sol +1 -1
  41. package/packages/policy-management/src/core/PolicyProtected.sol +28 -55
  42. package/packages/policy-management/src/core/PolicyProtectedUpgradeable.sol +134 -0
  43. package/packages/policy-management/src/extractors/ComplianceTokenForceTransferExtractor.sol +4 -1
  44. package/packages/policy-management/src/extractors/ComplianceTokenFreezeUnfreezeExtractor.sol +4 -1
  45. package/packages/policy-management/src/extractors/ComplianceTokenMintBurnExtractor.sol +4 -1
  46. package/packages/policy-management/src/extractors/ERC20ApproveExtractor.sol +4 -1
  47. package/packages/policy-management/src/extractors/ERC20TransferExtractor.sol +4 -1
  48. package/packages/policy-management/src/extractors/ERC3643ForcedTransferExtractor.sol +4 -1
  49. package/packages/policy-management/src/extractors/ERC3643FreezeUnfreezeExtractor.sol +4 -1
  50. package/packages/policy-management/src/extractors/ERC3643MintBurnExtractor.sol +4 -1
  51. package/packages/policy-management/src/extractors/ERC3643SetAddressFrozenExtractor.sol +4 -1
  52. package/packages/policy-management/src/interfaces/ICertifiedActionValidator.sol +110 -0
  53. package/packages/policy-management/src/interfaces/IExtractor.sol +6 -0
  54. package/packages/policy-management/src/interfaces/IMapper.sol +6 -0
  55. package/packages/policy-management/src/interfaces/IPolicy.sol +6 -0
  56. package/packages/policy-management/src/interfaces/IPolicyEngine.sol +90 -10
  57. package/packages/policy-management/src/interfaces/IPolicyProtected.sol +6 -0
  58. package/packages/policy-management/src/libraries/CertifiedActionLib.sol +47 -0
  59. package/packages/policy-management/src/policies/AllowPolicy.sol +12 -7
  60. package/packages/policy-management/src/policies/BypassPolicy.sol +23 -5
  61. package/packages/policy-management/src/policies/CertifiedActionDONValidatorPolicy.sol +156 -0
  62. package/packages/policy-management/src/policies/CertifiedActionERC20TransferValidatorPolicy.sol +202 -0
  63. package/packages/policy-management/src/policies/CertifiedActionValidatorPolicy.sol +365 -0
  64. package/packages/policy-management/src/policies/IntervalPolicy.sol +64 -48
  65. package/packages/policy-management/src/policies/MaxPolicy.sol +7 -5
  66. package/packages/policy-management/src/policies/OnlyAuthorizedSenderPolicy.sol +20 -4
  67. package/packages/policy-management/src/policies/OnlyOwnerPolicy.sol +4 -2
  68. package/packages/policy-management/src/policies/PausePolicy.sol +16 -15
  69. package/packages/policy-management/src/policies/RejectPolicy.sol +23 -5
  70. package/packages/policy-management/src/policies/RoleBasedAccessControlPolicy.sol +7 -5
  71. package/packages/policy-management/src/policies/SecureMintPolicy.sol +136 -48
  72. package/packages/policy-management/src/policies/VolumePolicy.sol +9 -5
  73. package/packages/policy-management/src/policies/VolumeRatePolicy.sol +11 -7
  74. package/packages/policy-management/test/PolicyEngine.t.sol +131 -23
  75. package/packages/policy-management/test/PolicyEngineFactory.t.sol +95 -0
  76. package/packages/policy-management/test/PolicyFactory.t.sol +1 -1
  77. package/packages/policy-management/test/{PolicyProtectedToken.t.sol → PolicyProtected.t.sol} +54 -8
  78. package/packages/policy-management/test/PolicyProtectedUpgradeable.t.sol +126 -0
  79. package/packages/policy-management/test/extractors/ComplianceTokenForceTransferExtractor.t.sol +1 -1
  80. package/packages/policy-management/test/extractors/ComplianceTokenFreezeUnfreezeExtractor.t.sol +1 -1
  81. package/packages/policy-management/test/extractors/ComplianceTokenMintBurnExtractor.t.sol +1 -1
  82. package/packages/policy-management/test/extractors/ERC20ApproveExtractor.t.sol +1 -1
  83. package/packages/policy-management/test/extractors/ERC3643ForcedTransferExtractor.t.sol +1 -1
  84. package/packages/policy-management/test/extractors/ERC3643FreezeUnfreezeExtractor.t.sol +1 -1
  85. package/packages/policy-management/test/extractors/ERC3643MintBurnExtractor.t.sol +1 -1
  86. package/packages/policy-management/test/extractors/ERC3643SetAddressFrozenExtractor.t.sol +1 -1
  87. package/packages/policy-management/test/helpers/BaseCertifiedActionTest.sol +44 -0
  88. package/packages/policy-management/test/helpers/BaseProxyTest.sol +88 -7
  89. package/packages/policy-management/test/helpers/CustomMapper.sol +3 -1
  90. package/packages/policy-management/test/helpers/DummyExtractor.sol +3 -1
  91. package/packages/policy-management/test/helpers/ExpectedParameterPolicy.sol +3 -1
  92. package/packages/policy-management/test/helpers/FaultyPolicyEngine.sol +54 -0
  93. package/packages/policy-management/test/helpers/MockCertifiedActionValidatorPolicyExtension.sol +46 -0
  94. package/packages/policy-management/test/helpers/MockToken.sol +2 -5
  95. package/packages/policy-management/test/helpers/MockTokenExtractor.sol +9 -4
  96. package/packages/policy-management/test/helpers/MockTokenUpgradeable.sol +66 -0
  97. package/packages/policy-management/test/helpers/PolicyAlwaysAllowed.sol +3 -1
  98. package/packages/policy-management/test/helpers/PolicyAlwaysContinue.sol +3 -1
  99. package/packages/policy-management/test/helpers/PolicyAlwaysRejected.sol +10 -1
  100. package/packages/policy-management/test/helpers/PolicyFailingRun.sol +3 -1
  101. package/packages/policy-management/test/policies/AllowPolicy.t.sol +39 -23
  102. package/packages/policy-management/test/policies/BypassPolicy.t.sol +48 -20
  103. package/packages/policy-management/test/policies/CertifiedActionDONValidatorPolicy.t.sol +172 -0
  104. package/packages/policy-management/test/policies/CertifiedActionERC20TransferValidatorPolicy.t.sol +217 -0
  105. package/packages/policy-management/test/policies/CertifiedActionValidatorPolicy.t.sol +1083 -0
  106. package/packages/policy-management/test/policies/IntervalPolicy.t.sol +105 -55
  107. package/packages/policy-management/test/policies/MaxPolicy.t.sol +15 -7
  108. package/packages/policy-management/test/policies/OnlyAuthorizedSenderPolicy.t.sol +91 -16
  109. package/packages/policy-management/test/policies/OnlyOwnerPolicy.t.sol +11 -7
  110. package/packages/policy-management/test/policies/PausePolicy.t.sol +46 -16
  111. package/packages/policy-management/test/policies/RejectPolicy.t.sol +52 -24
  112. package/packages/policy-management/test/policies/RoleBasedAccessControlPolicy.t.sol +50 -30
  113. package/packages/policy-management/test/policies/SecureMintPolicy.t.sol +211 -32
  114. package/packages/policy-management/test/policies/VolumePolicy.t.sol +20 -10
  115. package/packages/policy-management/test/policies/VolumeRatePolicy.t.sol +24 -18
  116. package/packages/tokens/erc-20/src/ComplianceTokenERC20.sol +4 -7
  117. package/packages/tokens/erc-20/src/ComplianceTokenStoreERC20.sol +4 -4
  118. package/packages/tokens/erc-20/test/ComplianceTokenERC20.t.sol +92 -82
  119. package/packages/tokens/erc-20/test/helpers/BaseProxyTest.sol +74 -1
  120. package/packages/tokens/erc-3643/src/ComplianceTokenERC3643.sol +12 -7
  121. package/packages/tokens/erc-3643/src/ComplianceTokenStoreERC3643.sol +4 -4
  122. package/packages/tokens/erc-3643/test/ComplianceTokenERC3643.t.sol +108 -119
  123. package/packages/tokens/erc-3643/test/helpers/BaseProxyTest.sol +74 -1
  124. package/packages/tokens/erc-3643/test/helpers/ExpectedContextPolicy.sol +3 -1
  125. package/remappings.txt +1 -0
  126. package/script/DeployCertifiedActionsComplianceTokenERC3643.s.sol +125 -0
@@ -0,0 +1,44 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity ^0.8.20;
3
+
4
+ import {ICertifiedActionValidator} from "../../src/interfaces/ICertifiedActionValidator.sol";
5
+ import {CertifiedActionValidatorPolicy} from "../../src/policies/CertifiedActionValidatorPolicy.sol";
6
+ import {BaseProxyTest} from "./BaseProxyTest.sol";
7
+
8
+ contract BaseCertifiedActionTest is BaseProxyTest {
9
+ uint256 private _nonce;
10
+
11
+ function _generatePermit(
12
+ address caller,
13
+ address subject,
14
+ bytes4 selector,
15
+ bytes[] memory parameters
16
+ )
17
+ internal
18
+ returns (ICertifiedActionValidator.Permit memory)
19
+ {
20
+ return ICertifiedActionValidator.Permit(
21
+ keccak256(abi.encodePacked(_nonce++)),
22
+ caller,
23
+ address(subject),
24
+ selector,
25
+ parameters,
26
+ "",
27
+ 0,
28
+ uint48(block.timestamp + 1 days)
29
+ );
30
+ }
31
+
32
+ function _signPermit(
33
+ CertifiedActionValidatorPolicy policy,
34
+ ICertifiedActionValidator.Permit memory permit,
35
+ uint256 pKey
36
+ )
37
+ internal
38
+ view
39
+ returns (bytes memory)
40
+ {
41
+ (uint8 v, bytes32 r, bytes32 s) = vm.sign(pKey, policy.hashTypedDataV4Permit(permit));
42
+ return abi.encodePacked(r, s, v);
43
+ }
44
+ }
@@ -1,12 +1,12 @@
1
1
  // SPDX-License-Identifier: BUSL-1.1
2
- pragma solidity 0.8.26;
2
+ pragma solidity ^0.8.20;
3
3
 
4
4
  import {Test} from "forge-std/Test.sol";
5
5
  import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
6
6
  import {IPolicyEngine} from "../../src/interfaces/IPolicyEngine.sol";
7
7
  import {PolicyEngine} from "../../src/core/PolicyEngine.sol";
8
8
  import {Policy} from "../../src/core/Policy.sol";
9
- import {MockToken} from "./MockToken.sol";
9
+ import {MockTokenUpgradeable} from "./MockTokenUpgradeable.sol";
10
10
 
11
11
  /**
12
12
  * @title BaseProxyTest
@@ -55,21 +55,102 @@ abstract contract BaseProxyTest is Test {
55
55
  */
56
56
  function _deployMockToken(address policyEngine) internal returns (address) {
57
57
  // Import and create MockToken implementation
58
- MockToken mockTokenImpl = new MockToken();
59
- bytes memory mockTokenData = abi.encodeWithSelector(MockToken.initialize.selector, policyEngine);
58
+ MockTokenUpgradeable mockTokenImpl = new MockTokenUpgradeable();
59
+ bytes memory mockTokenData = abi.encodeWithSelector(MockTokenUpgradeable.initialize.selector, policyEngine);
60
60
  ERC1967Proxy mockTokenProxy = new ERC1967Proxy(address(mockTokenImpl), mockTokenData);
61
61
  return address(mockTokenProxy);
62
62
  }
63
63
 
64
+ /**
65
+ * @notice Encode PolicyRunRejected error for use with vm.expectRevert
66
+ * @param policy The address of the policy that rejected the action
67
+ * @param reason The reason for rejection
68
+ * @param payload The payload that was rejected
69
+ * @return The encoded error data
70
+ */
64
71
  function _encodeRejectedRevert(
65
- bytes4 selector,
66
72
  address policy,
67
- string memory reason
73
+ string memory reason,
74
+ IPolicyEngine.Payload memory payload
68
75
  )
69
76
  internal
70
77
  pure
71
78
  returns (bytes memory)
72
79
  {
73
- return abi.encodeWithSelector(IPolicyEngine.PolicyRunRejected.selector, selector, policy, reason);
80
+ return abi.encodeWithSelector(IPolicyEngine.PolicyRunRejected.selector, policy, reason, payload);
81
+ }
82
+
83
+ /**
84
+ * @notice Expect a PolicyRunRejected revert with a payload
85
+ * @param policy The address of the policy that rejected the action
86
+ * @param reason The reason for rejection
87
+ * @param payload The payload that was rejected
88
+ */
89
+ function _expectRejectedRevert(address policy, string memory reason, IPolicyEngine.Payload memory payload) internal {
90
+ vm.expectRevert(_encodeRejectedRevert(policy, reason, payload));
91
+ }
92
+
93
+ /**
94
+ * @notice Expect a PolicyRunRejected revert with a payload created from parameters
95
+ * @param policy The address of the policy that rejected the action
96
+ * @param reason The reason for rejection
97
+ * @param selector The function selector
98
+ * @param sender The sender address
99
+ * @param data The encoded function parameters
100
+ * @param context The context bytes (defaults to empty if not provided)
101
+ */
102
+ function _expectRejectedRevert(
103
+ address policy,
104
+ string memory reason,
105
+ bytes4 selector,
106
+ address sender,
107
+ bytes memory data,
108
+ bytes memory context
109
+ )
110
+ internal
111
+ {
112
+ IPolicyEngine.Payload memory payload =
113
+ IPolicyEngine.Payload({selector: selector, sender: sender, data: data, context: context});
114
+ _expectRejectedRevert(policy, reason, payload);
115
+ }
116
+
117
+ /**
118
+ * @notice Expect a PolicyRunRejected revert with a payload created from parameters (empty context)
119
+ * @param policy The address of the policy that rejected the action
120
+ * @param reason The reason for rejection
121
+ * @param selector The function selector
122
+ * @param sender The sender address
123
+ * @param data The encoded function parameters
124
+ */
125
+ function _expectRejectedRevert(
126
+ address policy,
127
+ string memory reason,
128
+ bytes4 selector,
129
+ address sender,
130
+ bytes memory data
131
+ )
132
+ internal
133
+ {
134
+ _expectRejectedRevert(policy, reason, selector, sender, data, "");
135
+ }
136
+
137
+ /**
138
+ * @notice Expect a PolicyRunError revert with a payload
139
+ * @param policy The address of the policy that caused the error
140
+ * @param error The encoded error data
141
+ * @param payload The payload that caused the error
142
+ */
143
+ function _expectRunError(address policy, bytes memory error, IPolicyEngine.Payload memory payload) internal {
144
+ vm.expectRevert(abi.encodeWithSelector(IPolicyEngine.PolicyRunError.selector, policy, error, payload));
145
+ }
146
+
147
+ /**
148
+ * @notice Expect a PolicyPostRunError revert with a payload
149
+ * @param policy The address of the policy that caused the error
150
+ * @param error The encoded error data
151
+ * @param payload The payload that caused the error
152
+ */
153
+ function _expectPostRunError(address policy, bytes memory error, IPolicyEngine.Payload memory payload) internal {
154
+ vm.expectRevert(abi.encodeWithSelector(IPolicyEngine.PolicyPostRunError.selector, policy, error, payload));
74
155
  }
75
156
  }
@@ -1,10 +1,12 @@
1
1
  // SPDX-License-Identifier: BUSL-1.1
2
- pragma solidity 0.8.26;
2
+ pragma solidity ^0.8.20;
3
3
 
4
4
  import {IMapper} from "../../src/interfaces/IMapper.sol";
5
5
  import {IPolicyEngine} from "../../src/interfaces/IPolicyEngine.sol";
6
6
 
7
7
  contract CustomMapper is IMapper {
8
+ string public constant override typeAndVersion = "CustomMapper 1.0.0";
9
+
8
10
  bytes[] private s_mappedParameters;
9
11
 
10
12
  function setMappedParameters(bytes[] memory mappedParameters) public {
@@ -1,10 +1,12 @@
1
1
  // SPDX-License-Identifier: BUSL-1.1
2
- pragma solidity 0.8.26;
2
+ pragma solidity ^0.8.20;
3
3
 
4
4
  import {IExtractor} from "../../src/interfaces/IExtractor.sol";
5
5
  import {IPolicyEngine} from "../../src/interfaces/IPolicyEngine.sol";
6
6
 
7
7
  contract DummyExtractor is IExtractor {
8
+ string public constant override typeAndVersion = "DummyExtractor 1.0.0";
9
+
8
10
  function extract(IPolicyEngine.Payload calldata) external pure override returns (IPolicyEngine.Parameter[] memory) {
9
11
  return new IPolicyEngine.Parameter[](0);
10
12
  }
@@ -1,10 +1,12 @@
1
1
  // SPDX-License-Identifier: BUSL-1.1
2
- pragma solidity 0.8.26;
2
+ pragma solidity ^0.8.20;
3
3
 
4
4
  import {IPolicyEngine} from "../../src/interfaces/IPolicyEngine.sol";
5
5
  import {Policy} from "../../src/core/Policy.sol";
6
6
 
7
7
  contract ExpectedParameterPolicy is Policy {
8
+ string public constant override typeAndVersion = "ExpectedParameterPolicy 1.0.0";
9
+
8
10
  bytes[] private s_expectedParameters;
9
11
 
10
12
  function configure(bytes calldata parameters) internal override onlyInitializing {
@@ -0,0 +1,54 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity ^0.8.20;
3
+
4
+ import {IPolicyEngine} from "../../src/interfaces/IPolicyEngine.sol";
5
+
6
+ contract FaultyPolicyEngine is IPolicyEngine {
7
+ function typeAndVersion() external pure override returns (string memory) {
8
+ return "FaultyPolicyEngine 1.0.0";
9
+ }
10
+
11
+ function attach() external override {}
12
+
13
+ function detach() public override {
14
+ revert("FaultyPolicyEngine: detach not allowed");
15
+ }
16
+
17
+ function setExtractor(bytes4, address) external override {}
18
+
19
+ function setExtractors(bytes4[] calldata, address) external override {}
20
+
21
+ function getExtractor(bytes4) external view override returns (address) {
22
+ return address(0);
23
+ }
24
+
25
+ function setPolicyMapper(address, address) external override {}
26
+
27
+ function getPolicyMapper(address) external view override returns (address) {
28
+ return address(0);
29
+ }
30
+
31
+ function addPolicy(address, bytes4, address, bytes32[] calldata) external override {}
32
+
33
+ function addPolicyAt(address, bytes4, address, bytes32[] calldata, uint256) external override {}
34
+
35
+ function removePolicy(address, bytes4, address) external override {}
36
+
37
+ function getPolicies(address, bytes4) external view override returns (address[] memory) {
38
+ return new address[](0);
39
+ }
40
+
41
+ function setPolicyConfiguration(address, uint256, bytes4, bytes calldata) external override {}
42
+
43
+ function getPolicyConfigVersion(address) external view override returns (uint256) {
44
+ return 0;
45
+ }
46
+
47
+ function setDefaultPolicyAllow(bool) external override {}
48
+
49
+ function setTargetDefaultPolicyAllow(address, bool) external override {}
50
+
51
+ function check(Payload calldata) external view override {}
52
+
53
+ function run(Payload calldata) external override {}
54
+ }
@@ -0,0 +1,46 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity ^0.8.20;
3
+
4
+ import {CertifiedActionValidatorPolicy} from "../../src/policies/CertifiedActionValidatorPolicy.sol";
5
+
6
+ contract MockCertifiedActionValidatorPolicyExtension is CertifiedActionValidatorPolicy {
7
+ function _validatePrePresentedPermitHook(
8
+ bytes32, /*permitId*/
9
+ address, /*caller*/
10
+ address, /*subject*/
11
+ bytes4, /*selector*/
12
+ bytes[] memory /*parameters*/
13
+ )
14
+ internal
15
+ view
16
+ override
17
+ returns (bool)
18
+ {
19
+ // call a non-internal function so that it is observable by vm.expectCall
20
+ return this.validatePrePresentedPermitHook();
21
+ }
22
+
23
+ function validatePrePresentedPermitHook() public pure returns (bool) {
24
+ return true;
25
+ }
26
+
27
+ function _validateSignedPermitHook(
28
+ Permit memory, /*permit*/
29
+ address, /*caller*/
30
+ address, /*subject*/
31
+ bytes4, /*selector*/
32
+ bytes[] memory /*parameters*/
33
+ )
34
+ internal
35
+ view
36
+ override
37
+ returns (bool)
38
+ {
39
+ // call a non-internal function so that it is observable by vm.expectCall
40
+ return this.validatePermitHook();
41
+ }
42
+
43
+ function validatePermitHook() public pure returns (bool) {
44
+ return true;
45
+ }
46
+ }
@@ -2,9 +2,8 @@
2
2
  pragma solidity ^0.8.20;
3
3
 
4
4
  import {PolicyProtected} from "@chainlink/policy-management/core/PolicyProtected.sol";
5
- import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
6
5
 
7
- contract MockToken is Initializable, PolicyProtected {
6
+ contract MockToken is PolicyProtected {
8
7
  mapping(address account => uint256 balance) public s_balances;
9
8
  uint256 public totalSupply = 0;
10
9
  bool public paused;
@@ -18,9 +17,7 @@ contract MockToken is Initializable, PolicyProtected {
18
17
  _;
19
18
  }
20
19
 
21
- function initialize(address policyEngine) external initializer {
22
- __PolicyProtected_init(msg.sender, policyEngine);
23
- }
20
+ constructor(address policyEngine) PolicyProtected(msg.sender, policyEngine) {}
24
21
 
25
22
  function transfer(address to, uint256 amount) external whenNotPaused runPolicy {
26
23
  s_balances[to] += amount;
@@ -1,11 +1,13 @@
1
1
  // SPDX-License-Identifier: BUSL-1.1
2
- pragma solidity 0.8.26;
2
+ pragma solidity ^0.8.20;
3
3
 
4
4
  import {IExtractor} from "../../src/interfaces/IExtractor.sol";
5
5
  import {IPolicyEngine} from "../../src/interfaces/IPolicyEngine.sol";
6
- import {MockToken} from "./MockToken.sol";
6
+ import {MockTokenUpgradeable} from "./MockTokenUpgradeable.sol";
7
7
 
8
8
  contract MockTokenExtractor is IExtractor {
9
+ string public constant override typeAndVersion = "MockTokenExtractor 1.0.0";
10
+
9
11
  bytes32 public constant PARAM_FROM = keccak256("from");
10
12
  bytes32 public constant PARAM_TO = keccak256("to");
11
13
  bytes32 public constant PARAM_AMOUNT = keccak256("amount");
@@ -15,10 +17,13 @@ contract MockTokenExtractor is IExtractor {
15
17
  address to = address(0);
16
18
  uint256 amount = 0;
17
19
 
18
- if (payload.selector == MockToken.transfer.selector || payload.selector == MockToken.transferWithContext.selector) {
20
+ if (
21
+ payload.selector == MockTokenUpgradeable.transfer.selector
22
+ || payload.selector == MockTokenUpgradeable.transferWithContext.selector
23
+ ) {
19
24
  from = payload.sender;
20
25
  (to, amount) = abi.decode(payload.data, (address, uint256));
21
- } else if (payload.selector == MockToken.transferFrom.selector) {
26
+ } else if (payload.selector == MockTokenUpgradeable.transferFrom.selector) {
22
27
  (from, to, amount) = abi.decode(payload.data, (address, address, uint256));
23
28
  } else {
24
29
  revert IPolicyEngine.UnsupportedSelector(payload.selector);
@@ -0,0 +1,66 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity ^0.8.20;
3
+
4
+ import {PolicyProtectedUpgradeable} from "@chainlink/policy-management/core/PolicyProtectedUpgradeable.sol";
5
+ import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
6
+
7
+ contract MockTokenUpgradeable is Initializable, PolicyProtectedUpgradeable {
8
+ mapping(address account => uint256 balance) public s_balances;
9
+ uint256 public totalSupply = 0;
10
+ bool public paused;
11
+
12
+ error Paused();
13
+
14
+ modifier whenNotPaused() {
15
+ if (paused) {
16
+ revert Paused();
17
+ }
18
+ _;
19
+ }
20
+
21
+ function initialize(address policyEngine) external initializer {
22
+ __PolicyProtected_init(msg.sender, policyEngine);
23
+ }
24
+
25
+ function transfer(address to, uint256 amount) external whenNotPaused runPolicy {
26
+ s_balances[to] += amount;
27
+ }
28
+
29
+ function transferWithContext(
30
+ address to,
31
+ uint256 amount,
32
+ bytes calldata context
33
+ )
34
+ external
35
+ whenNotPaused
36
+ runPolicyWithContext(context)
37
+ {
38
+ s_balances[to] += amount;
39
+ }
40
+
41
+ function transferFrom(address, /*from*/ address to, uint256 amount) external whenNotPaused runPolicy {
42
+ s_balances[to] += amount;
43
+ }
44
+
45
+ function balanceOf(address account) external view returns (uint256) {
46
+ return s_balances[account];
47
+ }
48
+
49
+ function mint(address to, uint256 amount) external whenNotPaused runPolicy {
50
+ s_balances[to] += amount;
51
+ totalSupply += amount;
52
+ }
53
+
54
+ function burn(address to, uint256 amount) external whenNotPaused runPolicy {
55
+ s_balances[to] -= amount;
56
+ totalSupply -= amount;
57
+ }
58
+
59
+ function pause() external runPolicy {
60
+ paused = true;
61
+ }
62
+
63
+ function unpause() external runPolicy {
64
+ paused = false;
65
+ }
66
+ }
@@ -1,10 +1,12 @@
1
1
  // SPDX-License-Identifier: BUSL-1.1
2
- pragma solidity 0.8.26;
2
+ pragma solidity ^0.8.20;
3
3
 
4
4
  import {IPolicyEngine} from "../../src/interfaces/IPolicyEngine.sol";
5
5
  import {Policy} from "../../src/core/Policy.sol";
6
6
 
7
7
  contract PolicyAlwaysAllowed is Policy {
8
+ string public constant override typeAndVersion = "PolicyAlwaysAllowed 1.0.0";
9
+
8
10
  uint8 private s_policyNumber;
9
11
 
10
12
  event PolicyAllowedExecuted(uint256 value);
@@ -1,11 +1,13 @@
1
1
  // SPDX-License-Identifier: BUSL-1.1
2
2
 
3
- pragma solidity 0.8.26;
3
+ pragma solidity ^0.8.20;
4
4
 
5
5
  import {IPolicyEngine} from "../../src/interfaces/IPolicyEngine.sol";
6
6
  import {Policy} from "../../src/core/Policy.sol";
7
7
 
8
8
  contract PolicyAlwaysContinue is Policy {
9
+ string public constant override typeAndVersion = "PolicyAlwaysContinue 1.0.0";
10
+
9
11
  function run(
10
12
  address,
11
13
  address,
@@ -1,11 +1,15 @@
1
1
  // SPDX-License-Identifier: BUSL-1.1
2
2
 
3
- pragma solidity 0.8.26;
3
+ pragma solidity ^0.8.20;
4
4
 
5
5
  import {IPolicyEngine} from "../../src/interfaces/IPolicyEngine.sol";
6
6
  import {Policy} from "../../src/core/Policy.sol";
7
7
 
8
8
  contract PolicyAlwaysRejected is Policy {
9
+ string public constant override typeAndVersion = "PolicyAlwaysRejected 1.0.0";
10
+
11
+ event ConfigFuncExecuted();
12
+
9
13
  function run(
10
14
  address,
11
15
  address,
@@ -20,4 +24,9 @@ contract PolicyAlwaysRejected is Policy {
20
24
  {
21
25
  revert IPolicyEngine.PolicyRejected("test policy always rejects");
22
26
  }
27
+
28
+ function configFunc() external onlyOwner {
29
+ // dummy logic
30
+ emit ConfigFuncExecuted();
31
+ }
23
32
  }
@@ -1,10 +1,12 @@
1
1
  // SPDX-License-Identifier: BUSL-1.1
2
- pragma solidity 0.8.26;
2
+ pragma solidity ^0.8.20;
3
3
 
4
4
  import {IPolicyEngine} from "../../src/interfaces/IPolicyEngine.sol";
5
5
  import {Policy} from "../../src/core/Policy.sol";
6
6
 
7
7
  contract PolicyFailingRun is Policy {
8
+ string public constant override typeAndVersion = "PolicyFailingRun 1.0.0";
9
+
8
10
  function run(
9
11
  address,
10
12
  address,
@@ -1,16 +1,16 @@
1
1
  // SPDX-License-Identifier: BUSL-1.1
2
- pragma solidity 0.8.26;
2
+ pragma solidity ^0.8.20;
3
3
 
4
4
  import {IPolicyEngine, PolicyEngine} from "@chainlink/policy-management/core/PolicyEngine.sol";
5
5
  import {ERC20TransferExtractor} from "@chainlink/policy-management/extractors/ERC20TransferExtractor.sol";
6
6
  import {AllowPolicy} from "@chainlink/policy-management/policies/AllowPolicy.sol";
7
- import {MockToken} from "../helpers/MockToken.sol";
7
+ import {MockTokenUpgradeable} from "../helpers/MockTokenUpgradeable.sol";
8
8
  import {ERC3643MintBurnExtractor} from "@chainlink/policy-management/extractors/ERC3643MintBurnExtractor.sol";
9
9
  import {BaseProxyTest} from "../helpers/BaseProxyTest.sol";
10
10
 
11
11
  contract AllowPolicyTest is BaseProxyTest {
12
12
  PolicyEngine public policyEngine;
13
- MockToken public token;
13
+ MockTokenUpgradeable public token;
14
14
  AllowPolicy public allowPolicy;
15
15
  address public deployer;
16
16
  address public account;
@@ -30,21 +30,23 @@ contract AllowPolicyTest is BaseProxyTest {
30
30
  // add account by default
31
31
  allowPolicy.allowAddress(account);
32
32
 
33
- token = MockToken(_deployMockToken(address(policyEngine)));
33
+ token = MockTokenUpgradeable(_deployMockToken(address(policyEngine)));
34
34
 
35
35
  // set up the allowPolicy to check the recipient and origin of token transfers (multiple accounts)
36
36
  ERC20TransferExtractor transferExtractor = new ERC20TransferExtractor();
37
37
  bytes32[] memory transferPolicyParams = new bytes32[](2);
38
38
  transferPolicyParams[0] = transferExtractor.PARAM_TO();
39
39
  transferPolicyParams[1] = transferExtractor.PARAM_FROM();
40
- policyEngine.setExtractor(MockToken.transfer.selector, address(transferExtractor));
41
- policyEngine.addPolicy(address(token), MockToken.transfer.selector, address(allowPolicy), transferPolicyParams);
40
+ policyEngine.setExtractor(MockTokenUpgradeable.transfer.selector, address(transferExtractor));
41
+ policyEngine.addPolicy(
42
+ address(token), MockTokenUpgradeable.transfer.selector, address(allowPolicy), transferPolicyParams
43
+ );
42
44
  // set up the allowPolicy to check the mint account (single account)
43
45
  ERC3643MintBurnExtractor mintBurnExtractor = new ERC3643MintBurnExtractor();
44
46
  bytes32[] memory mintPolicyParams = new bytes32[](1);
45
47
  mintPolicyParams[0] = mintBurnExtractor.PARAM_ACCOUNT();
46
- policyEngine.setExtractor(MockToken.mint.selector, address(mintBurnExtractor));
47
- policyEngine.addPolicy(address(token), MockToken.mint.selector, address(allowPolicy), mintPolicyParams);
48
+ policyEngine.setExtractor(MockTokenUpgradeable.mint.selector, address(mintBurnExtractor));
49
+ policyEngine.addPolicy(address(token), MockTokenUpgradeable.mint.selector, address(allowPolicy), mintPolicyParams);
48
50
  }
49
51
 
50
52
  function test_allowAddress_succeeds() public {
@@ -113,8 +115,12 @@ contract AllowPolicyTest is BaseProxyTest {
113
115
  vm.startPrank(account, account);
114
116
 
115
117
  // transfer from address to recipient (reverts)
116
- vm.expectRevert(
117
- _encodeRejectedRevert(MockToken.transfer.selector, address(allowPolicy), "address is not on allow list")
118
+ _expectRejectedRevert(
119
+ address(allowPolicy),
120
+ "address is not on allow list",
121
+ MockTokenUpgradeable.transfer.selector,
122
+ account,
123
+ abi.encode(recipient, 100)
118
124
  );
119
125
  token.transfer(recipient, 100);
120
126
  }
@@ -135,8 +141,12 @@ contract AllowPolicyTest is BaseProxyTest {
135
141
 
136
142
  // transfer from address to recipient (should revert after removal)
137
143
  vm.startPrank(account, account);
138
- vm.expectRevert(
139
- _encodeRejectedRevert(MockToken.transfer.selector, address(allowPolicy), "address is not on allow list")
144
+ _expectRejectedRevert(
145
+ address(allowPolicy),
146
+ "address is not on allow list",
147
+ MockTokenUpgradeable.transfer.selector,
148
+ account,
149
+ abi.encode(recipient, 100)
140
150
  );
141
151
  token.transfer(recipient, 100);
142
152
  }
@@ -150,8 +160,12 @@ contract AllowPolicyTest is BaseProxyTest {
150
160
 
151
161
  function test_mint_notInList_failure() public {
152
162
  vm.startPrank(deployer, deployer);
153
- vm.expectRevert(
154
- _encodeRejectedRevert(MockToken.mint.selector, address(allowPolicy), "address is not on allow list")
163
+ _expectRejectedRevert(
164
+ address(allowPolicy),
165
+ "address is not on allow list",
166
+ MockTokenUpgradeable.mint.selector,
167
+ deployer,
168
+ abi.encode(recipient, 20)
155
169
  );
156
170
  token.mint(recipient, 20);
157
171
  }
@@ -160,15 +174,17 @@ contract AllowPolicyTest is BaseProxyTest {
160
174
  vm.startPrank(deployer);
161
175
  // misconfigure the allowPolicy to check burn operations (no accounts)
162
176
  ERC3643MintBurnExtractor mintBurnExtractor = new ERC3643MintBurnExtractor();
163
- policyEngine.setExtractor(MockToken.burn.selector, address(mintBurnExtractor));
164
- policyEngine.addPolicy(address(token), MockToken.burn.selector, address(allowPolicy), new bytes32[](0));
165
-
166
- bytes memory error = abi.encodeWithSignature("Error(string)", "expected at least 1 parameter");
167
- vm.expectRevert(
168
- abi.encodeWithSelector(
169
- IPolicyEngine.PolicyRunError.selector, MockToken.burn.selector, address(allowPolicy), error
170
- )
171
- );
177
+ policyEngine.setExtractor(MockTokenUpgradeable.burn.selector, address(mintBurnExtractor));
178
+ policyEngine.addPolicy(address(token), MockTokenUpgradeable.burn.selector, address(allowPolicy), new bytes32[](0));
179
+
180
+ IPolicyEngine.Payload memory payload = IPolicyEngine.Payload({
181
+ selector: MockTokenUpgradeable.burn.selector,
182
+ sender: deployer,
183
+ data: abi.encode(account, 100),
184
+ context: new bytes(0)
185
+ });
186
+ bytes memory error = abi.encodeWithSignature("InvalidParameters(string)", "expected at least 1 parameter");
187
+ _expectRunError(address(allowPolicy), error, payload);
172
188
  token.burn(account, 100);
173
189
  }
174
190
  }