Skip to content

Commit bc98679

Browse files
committed
Add test with CMTAT v3.0.0 and v3.2.0-rc0
1 parent 86d14cf commit bc98679

8 files changed

Lines changed: 806 additions & 3 deletions

File tree

foundry.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"lib/CMTAT": {
33
"tag": {
4-
"name": "v3.2.0-rc0",
5-
"rev": "012ccc409c4205da2b38f23ce21496b3486bc663"
4+
"name": "v3.2.0-rc2",
5+
"rev": "78e6e48e491e01e853e6490e061189875d4785ea"
66
}
77
},
88
"lib/forge-std": {

lib/CMTAT

Submodule CMTAT updated 916 files

remappings.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
CMTAT=lib/CMTAT/contracts/
2+
CMTATv3.0.0=lib/CMTATv3.0.0/contracts/
23
OZ/=lib/openzeppelin-contracts/contracts
34
@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts
45
@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/

test/HelperContractV3.sol

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
//SPDX-License-Identifier: MPL-2.0
2+
pragma solidity ^0.8.20;
3+
4+
import "forge-std/Test.sol";
5+
import "CMTATv3.0.0/deployment/CMTATStandalone.sol";
6+
7+
import {RuleEngineInvariantStorage} from "src/modules/library/RuleEngineInvariantStorage.sol";
8+
import {RulesManagementModuleInvariantStorage} from "src/modules/library/RulesManagementModuleInvariantStorage.sol";
9+
// RuleEngine
10+
import {RuleEngine} from "src/RuleEngine.sol";
11+
import {RulesManagementModule} from "src/RuleEngineBase.sol";
12+
import {ERC3643ComplianceModule} from "src/RuleEngineBase.sol";
13+
// RuleConditionalTransfer
14+
import {RuleConditionalTransferLight} from "src/mocks/rules/operation/RuleConditionalTransferLight.sol";
15+
import {RuleConditionalTransferLightInvariantStorage} from "src/mocks/rules/operation/abstract/RuleConditionalTransferLightInvariantStorage.sol";
16+
// RuleWhitelist
17+
import {RuleWhitelist} from "src/mocks/rules/validation/RuleWhitelist.sol";
18+
import {RuleWhitelistInvariantStorage} from "src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol";
19+
import {RuleAddressListInvariantStorage} from "src/mocks/rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol";
20+
21+
// Rule interface
22+
import {IRule} from "src/interfaces/IRule.sol";
23+
24+
// V3 IRuleEngine for type casting with setRuleEngine
25+
import {IRuleEngine as IRuleEngineV3} from "CMTATv3.0.0/interfaces/engine/IRuleEngine.sol";
26+
27+
// utils
28+
import "./utils/CMTATDeploymentV3.sol";
29+
30+
/**
31+
* @title Constants used by the V3 tests
32+
*/
33+
abstract contract HelperContractV3 is
34+
RuleWhitelistInvariantStorage,
35+
RuleAddressListInvariantStorage,
36+
RuleEngineInvariantStorage,
37+
RuleConditionalTransferLightInvariantStorage,
38+
RulesManagementModuleInvariantStorage
39+
{
40+
// Test result
41+
uint256 internal resUint256;
42+
uint8 internal resUint8;
43+
bool internal resBool;
44+
bool internal resCallBool;
45+
string internal resString;
46+
address internal resAddr;
47+
// EOA to perform tests
48+
address constant ZERO_ADDRESS = address(0);
49+
address constant DEFAULT_ADMIN_ADDRESS = address(1);
50+
address constant WHITELIST_OPERATOR_ADDRESS = address(2);
51+
address constant RULE_ENGINE_OPERATOR_ADDRESS = address(3);
52+
address constant CONDITIONAL_TRANSFER_OPERATOR_ADDRESS = address(9);
53+
address constant ATTACKER = address(4);
54+
address constant ADDRESS1 = address(5);
55+
address constant ADDRESS2 = address(6);
56+
address constant ADDRESS3 = address(7);
57+
// role string
58+
string constant RULE_ENGINE_ROLE_HASH =
59+
"0x774b3c5f4a8b37a7da21d72b7f2429e4a6d49c4de0ac5f2b831a1a539d0f0fd2";
60+
string constant WHITELIST_ROLE_HASH =
61+
"0xdc72ed553f2544c34465af23b847953efeb813428162d767f9ba5f4013be6760";
62+
string constant DEFAULT_ADMIN_ROLE_HASH =
63+
"0x0000000000000000000000000000000000000000000000000000000000000000";
64+
65+
// contract
66+
RuleWhitelist public ruleWhitelist;
67+
RuleConditionalTransferLight public ruleConditionalTransferLight;
68+
69+
// CMTAT
70+
CMTATDeploymentV3 cmtatDeployment;
71+
CMTATStandalone CMTAT_CONTRACT;
72+
73+
// RuleEngine Mock
74+
RuleEngine public ruleEngineMock;
75+
76+
//bytes32 public constant RULE_ENGINE_ROLE = keccak256("RULE_ENGINE_ROLE");
77+
78+
uint8 constant NO_ERROR = 0;
79+
uint8 CODE_NONEXISTENT = 255;
80+
// Defined in CMTAT.sol
81+
uint8 constant TRANSFER_OK = 0;
82+
string constant TEXT_TRANSFER_OK = "NoRestriction";
83+
// Forwarder
84+
string ERC2771ForwarderDomain = "ERC2771ForwarderDomain";
85+
86+
error Rulelist_AddressAlreadylisted();
87+
error Rulelist_AddressNotPresent();
88+
89+
constructor() {}
90+
}
Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
// SPDX-License-Identifier: MPL-2.0
2+
pragma solidity ^0.8.20;
3+
4+
import "forge-std/Test.sol";
5+
import "CMTATv3.0.0/deployment/CMTATStandalone.sol";
6+
import "../../HelperContractV3.sol";
7+
import "OZ/token/ERC20/IERC20.sol";
8+
9+
/**
10+
* @title General functions of the RuleEngine with CMTAT v3.0.0
11+
*/
12+
contract RuleEngineCMTATIntegrationV3Test is Test, HelperContractV3 {
13+
uint256 defaultValue = 20;
14+
15+
// Arrange
16+
function setUp() public {
17+
// global arrange
18+
cmtatDeployment = new CMTATDeploymentV3();
19+
CMTAT_CONTRACT = cmtatDeployment.cmtat();
20+
21+
// CMTAT
22+
vm.prank(DEFAULT_ADMIN_ADDRESS);
23+
CMTAT_CONTRACT.mint(ADDRESS1, defaultValue * 2);
24+
vm.prank(DEFAULT_ADMIN_ADDRESS);
25+
CMTAT_CONTRACT.mint(ADDRESS2, defaultValue);
26+
27+
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
28+
ruleEngineMock = new RuleEngine(
29+
RULE_ENGINE_OPERATOR_ADDRESS,
30+
ZERO_ADDRESS,
31+
address(CMTAT_CONTRACT)
32+
);
33+
ruleConditionalTransferLight = new RuleConditionalTransferLight(
34+
CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
35+
ruleEngineMock
36+
);
37+
38+
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
39+
ruleEngineMock.addRule(ruleConditionalTransferLight);
40+
// Arrange - Assert
41+
resUint256 = ruleEngineMock.rulesCount();
42+
assertEq(resUint256, 1);
43+
44+
// We set the Rule Engine
45+
vm.prank(DEFAULT_ADMIN_ADDRESS);
46+
CMTAT_CONTRACT.setRuleEngine(IRuleEngineV3(address(ruleEngineMock)));
47+
}
48+
49+
function testCanDetectTransferRestrictionOK() public {
50+
// Arrange
51+
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
52+
53+
vm.expectEmit(true, true, true, true);
54+
emit TransferApproved(ADDRESS1, ADDRESS2, defaultValue, 1);
55+
ruleConditionalTransferLight.approveTransfer(
56+
ADDRESS1,
57+
ADDRESS2,
58+
defaultValue
59+
);
60+
// Act
61+
// RuleEngine
62+
resUint8 = ruleEngineMock.detectTransferRestriction(
63+
ADDRESS1,
64+
ADDRESS2,
65+
defaultValue
66+
);
67+
68+
// Assert
69+
assertEq(resUint8, 0);
70+
71+
resUint8 = ruleEngineMock.detectTransferRestrictionFrom(
72+
address(0),
73+
ADDRESS1,
74+
ADDRESS2,
75+
defaultValue
76+
);
77+
78+
// Assert
79+
assertEq(resUint8, 0);
80+
81+
// CMTAT
82+
resUint8 = CMTAT_CONTRACT.detectTransferRestriction(
83+
ADDRESS1,
84+
ADDRESS2,
85+
defaultValue
86+
);
87+
88+
// Assert
89+
assertEq(resUint8, 0);
90+
91+
resUint8 = CMTAT_CONTRACT.detectTransferRestrictionFrom(
92+
address(0),
93+
ADDRESS1,
94+
ADDRESS2,
95+
defaultValue
96+
);
97+
98+
// Assert
99+
assertEq(resUint8, 0);
100+
101+
// RuleEngine
102+
resBool = ruleEngineMock.canTransfer(ADDRESS1, ADDRESS2, defaultValue);
103+
104+
// Assert
105+
assertEq(resBool, true);
106+
107+
resBool = ruleEngineMock.canTransferFrom(
108+
ADDRESS3,
109+
ADDRESS1,
110+
ADDRESS2,
111+
defaultValue
112+
);
113+
114+
// Assert
115+
assertEq(resBool, true);
116+
117+
// CMTAT
118+
resBool = CMTAT_CONTRACT.canTransfer(ADDRESS1, ADDRESS2, defaultValue);
119+
120+
// Assert
121+
assertEq(resBool, true);
122+
123+
resBool = CMTAT_CONTRACT.canTransferFrom(
124+
ADDRESS3,
125+
ADDRESS1,
126+
ADDRESS2,
127+
defaultValue
128+
);
129+
130+
// Assert
131+
assertEq(resBool, true);
132+
}
133+
134+
function testCanDetectTransferRestrictionNotOk() public {
135+
// Act
136+
resUint8 = ruleEngineMock.detectTransferRestriction(
137+
ADDRESS1,
138+
ADDRESS2,
139+
20
140+
);
141+
142+
// Assert
143+
assertEq(resUint8, CODE_TRANSFER_REQUEST_NOT_APPROVED);
144+
145+
// CMTAT
146+
resUint8 = CMTAT_CONTRACT.detectTransferRestriction(
147+
ADDRESS1,
148+
ADDRESS2,
149+
20
150+
);
151+
152+
// Assert
153+
assertEq(resUint8, CODE_TRANSFER_REQUEST_NOT_APPROVED);
154+
155+
// Act
156+
resUint8 = ruleEngineMock.detectTransferRestrictionFrom(
157+
ADDRESS3,
158+
ADDRESS1,
159+
ADDRESS2,
160+
20
161+
);
162+
163+
// Assert
164+
assertEq(resUint8, CODE_TRANSFER_REQUEST_NOT_APPROVED);
165+
166+
// CMTAT
167+
resUint8 = CMTAT_CONTRACT.detectTransferRestrictionFrom(
168+
ADDRESS3,
169+
ADDRESS1,
170+
ADDRESS2,
171+
20
172+
);
173+
174+
// Assert
175+
assertEq(resUint8, CODE_TRANSFER_REQUEST_NOT_APPROVED);
176+
177+
// Act
178+
resBool = ruleEngineMock.canTransfer(ADDRESS1, ADDRESS2, 20);
179+
180+
// Assert
181+
assertFalse(resBool);
182+
183+
// CMTAT
184+
resBool = CMTAT_CONTRACT.canTransfer(ADDRESS1, ADDRESS2, 20);
185+
186+
// Assert
187+
assertFalse(resBool);
188+
189+
// Act
190+
resBool = ruleEngineMock.canTransferFrom(
191+
ADDRESS3,
192+
ADDRESS1,
193+
ADDRESS2,
194+
20
195+
);
196+
197+
// Assert
198+
assertFalse(resBool);
199+
200+
// CMTAT
201+
resBool = CMTAT_CONTRACT.canTransferFrom(
202+
ADDRESS3,
203+
ADDRESS1,
204+
ADDRESS2,
205+
20
206+
);
207+
208+
// Assert
209+
assertFalse(resBool);
210+
}
211+
212+
function testCanPerfromATransfer() public {
213+
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
214+
ruleConditionalTransferLight.approveTransfer(
215+
ADDRESS1,
216+
ADDRESS2,
217+
defaultValue
218+
);
219+
vm.prank(ADDRESS1);
220+
CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
221+
222+
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
223+
ruleConditionalTransferLight.approveTransfer(
224+
ADDRESS1,
225+
ADDRESS2,
226+
defaultValue
227+
);
228+
vm.prank(ADDRESS1);
229+
CMTAT_CONTRACT.approve(ADDRESS3, defaultValue);
230+
vm.prank(ADDRESS3);
231+
CMTAT_CONTRACT.transferFrom(ADDRESS1, ADDRESS2, defaultValue);
232+
}
233+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// SPDX-License-Identifier: MPL-2.0
2+
pragma solidity ^0.8.20;
3+
4+
import "forge-std/Test.sol";
5+
import "../../HelperContractV3.sol";
6+
import "OZ/token/ERC20/IERC20.sol";
7+
import "src/mocks/rules/operation/RuleOperationRevert.sol";
8+
9+
/**
10+
* @title General functions of the RuleEngine with CMTAT v3.0.0
11+
*/
12+
contract RuleEngineOperationTestRevertV3 is Test, HelperContractV3 {
13+
// Arrange
14+
function setUp() public {
15+
// CMTAT
16+
cmtatDeployment = new CMTATDeploymentV3();
17+
CMTAT_CONTRACT = cmtatDeployment.cmtat();
18+
19+
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
20+
ruleEngineMock = new RuleEngine(
21+
RULE_ENGINE_OPERATOR_ADDRESS,
22+
ZERO_ADDRESS,
23+
address(CMTAT_CONTRACT)
24+
);
25+
RuleOperationRevert ruleOperationRevert = new RuleOperationRevert();
26+
27+
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
28+
ruleEngineMock.addRule(ruleOperationRevert);
29+
// Arrange - Assert
30+
resUint256 = ruleEngineMock.rulesCount();
31+
assertEq(resUint256, 1);
32+
33+
vm.prank(DEFAULT_ADMIN_ADDRESS);
34+
CMTAT_CONTRACT.setRuleEngine(IRuleEngineV3(address(ruleEngineMock)));
35+
}
36+
37+
function testRuleEngineTransferredRevert() public {
38+
// Arrange
39+
vm.expectRevert(
40+
RuleOperationRevert
41+
.RuleConditionalTransferLight_InvalidTransfer
42+
.selector
43+
);
44+
// Act
45+
CMTAT_CONTRACT.transfer(ADDRESS2, 21);
46+
}
47+
}

0 commit comments

Comments
 (0)