Skip to content

Commit 60a5ca5

Browse files
committed
WIP - ccipReceive tests
1 parent 8068820 commit 60a5ca5

File tree

7 files changed

+677
-66
lines changed

7 files changed

+677
-66
lines changed

src/interfaces/IEnsoCCIPReceiver.sol

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ interface IEnsoCCIPReceiver {
4747
/// @dev errorData encodings:
4848
/// - ALREADY_EXECUTED: (bytes32 messageId)
4949
/// - Others: empty bytes unless specified by the implementation.
50-
event MessageValidationFailed(bytes32 indexed messageId, ErrorCode errorCode, bytes errorData);
50+
event MessageValidationFailed(bytes32 indexed messageId, ErrorCode indexed errorCode, bytes errorData);
5151

5252
/// @notice Funds were quarantined in the receiver instead of delivered to the payload receiver.
5353
/// @param messageId The CCIP message id.
@@ -56,7 +56,7 @@ interface IEnsoCCIPReceiver {
5656
/// @param amount Token amount retained.
5757
/// @param receiver Original payload receiver (informational; may be zero if not decoded).
5858
event MessageQuarantined(
59-
bytes32 indexed messageId, ErrorCode code, address token, uint256 amount, address receiver
59+
bytes32 indexed messageId, ErrorCode indexed code, address token, uint256 amount, address receiver
6060
);
6161

6262
/// @notice Emitted when Enso Shortcuts execution succeeds for a CCIP message.
@@ -69,7 +69,7 @@ interface IEnsoCCIPReceiver {
6969
event ShortcutExecutionFailed(bytes32 indexed messageId, bytes err);
7070

7171
/// @notice Emitted when the owner recovers tokens from the receiver.
72-
event TokensRecovered(address token, address to, uint256 amount);
72+
event TokensRecovered(address indexed token, address indexed to, uint256 amount);
7373

7474
// -------------------------------------------------------------------------
7575
// Errors

test/mocks/MockEnsoRouter.sol

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ contract MockEnsoRouter {
3737
}
3838
}
3939
if (isNativeAsset) {
40-
shortcuts.call{ value: msg.value }("");
40+
(bool success, bytes memory result) = shortcuts.call{ value: msg.value }("");
41+
(success);
42+
(result);
4143
}
4244
}
4345

test/shortcuts/ShortcutsEthereum.sol

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,9 @@ library ShortcutsEthereum {
144144

145145
shortcut.txGas = 92_661;
146146
shortcut.txData = abi.encodePacked(
147-
hex"95352c9fad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a51b21602de47c41deb22fa12edf3f9188303132333435363738394142434445460000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000042e1a7d4d0100ffffffffffffc02aaa39b223fe8d0a0e5c4f27ead9083c756cc219198595a30081ffffffffff",
147+
hex"95352c9fad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a523e16585efc24d639f861691ad38481130313233343536373839414243444546000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000005a9059cbb010001ffffffffffc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22e1a7d4d0102ffffffffffffc02aaa39b223fe8d0a0e5c4f27ead9083c756cc219198595a30283ffffffffff",
148148
receiver,
149-
hex"6e7a43a3010002ffffffff027e7d64d987cab6eed08a191c4c2459daf2f8ed0b241c59120102ffffffffffff7e7d64d987cab6eed08a191c4c2459daf2f8ed0b0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000dcef33a6f838000"
149+
hex"6e7a43a3010204ffffffff047e7d64d987cab6eed08a191c4c2459daf2f8ed0b241c59120104ffffffffffff7e7d64d987cab6eed08a191c4c2459daf2f8ed0b000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000200000000000000000000000006aa68c46ed86161eb318b1396f7b79e386e886760000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000dbd2fc137a30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001"
150150
);
151151
shortcut.referralCode = "0123456789ABCDEF";
152152
}
@@ -158,7 +158,8 @@ library ShortcutsEthereum {
158158
function getShortcut2(
159159
address weth,
160160
address ensoShortcutsHelpers,
161-
address receiver
161+
address receiver,
162+
address feeReceiver
162163
)
163164
public
164165
pure
@@ -182,19 +183,23 @@ library ShortcutsEthereum {
182183
shortcut.tokensOut = tokensOut;
183184

184185
shortcut.fee = 0.01 ether;
185-
shortcut.feeReceiver = 0x6AA68C46eD86161eB318b1396F7b79E386e88676;
186+
shortcut.feeReceiver = feeReceiver;
186187

187188
shortcut.txGas = 92_661;
188189
shortcut.txData = abi.encodePacked(
189-
hex"95352c9fad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a51b21602de47c41deb22fa12edf3f9188303132333435363738394142434445460000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000042e1a7d4d0100ffffffffffff",
190+
hex"95352c9fad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a523e16585efc24d639f861691ad38481130313233343536373839414243444546000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000005a9059cbb010001ffffffffff",
191+
weth,
192+
hex"2e1a7d4d0102ffffffffffff",
190193
weth,
191-
hex"19198595a30081ffffffffff",
194+
hex"19198595a30283ffffffffff",
192195
receiver,
193-
hex"6e7a43a3010002ffffffff02",
196+
hex"6e7a43a3010204ffffffff04",
194197
ensoShortcutsHelpers,
195-
hex"241c59120102ffffffffffff",
198+
hex"241c59120104ffffffffffff",
196199
ensoShortcutsHelpers,
197-
hex"0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000dcef33a6f838000"
200+
hex"000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000",
201+
feeReceiver,
202+
hex"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000dbd2fc137a30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001"
198203
);
199204
shortcut.referralCode = "0123456789ABCDEF";
200205
}

test/unit/concrete/bridge/ensoCCIPReceiver/EnsoCCIPReceiver.t.sol

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
// SPDX-License-Identifier: GPL-3.0-only
22
pragma solidity ^0.8.28;
33

4+
import { EnsoShortcuts } from "../../../../../src/EnsoShortcuts.sol";
45
import { EnsoCCIPReceiver } from "../../../../../src/bridge/EnsoCCIPReceiver.sol";
56
import { EnsoShortcutsHelpers } from "../../../../../src/helpers/EnsoShortcutsHelpers.sol";
67
import { EnsoRouter } from "../../../../../src/router/EnsoRouter.sol";
8+
import { MockERC20 } from "../../../../mocks/MockERC20.sol";
79
import { WETH9 } from "../../../../mocks/WETH9.sol";
810
import { MockCCIPRouter } from "chainlink-ccip/test/mocks/MockRouter.sol";
911
import { Test } from "forge-std-1.9.7/Test.sol";
@@ -14,10 +16,13 @@ abstract contract EnsoCCIPReceiver_Unit_Concrete_Test is Test {
1416
address payable internal s_account1;
1517
address payable internal s_account2;
1618
EnsoRouter internal s_ensoRouter;
19+
EnsoShortcuts internal s_ensoShortcuts;
1720
EnsoShortcutsHelpers internal s_ensoShortcutsHelpers;
1821
MockCCIPRouter internal s_ccipRouter;
1922
EnsoCCIPReceiver internal s_ensoCcipReceiver;
2023
WETH9 internal s_weth;
24+
MockERC20 internal s_tokenA;
25+
MockERC20 internal s_tokenB;
2126

2227
function setUp() public virtual {
2328
s_deployer = payable(vm.addr(1));
@@ -40,6 +45,9 @@ abstract contract EnsoCCIPReceiver_Unit_Concrete_Test is Test {
4045
s_ensoRouter = new EnsoRouter();
4146
vm.label(address(s_ensoRouter), "EnsoRouter");
4247

48+
s_ensoShortcuts = EnsoShortcuts(payable(s_ensoRouter.shortcuts()));
49+
vm.label(address(s_ensoShortcuts), "EnsoShortcuts");
50+
4351
s_ensoShortcutsHelpers = new EnsoShortcutsHelpers();
4452
vm.label(address(s_ensoShortcutsHelpers), "EnsoShortcutsHelpers");
4553

@@ -51,6 +59,15 @@ abstract contract EnsoCCIPReceiver_Unit_Concrete_Test is Test {
5159

5260
s_weth = new WETH9();
5361
vm.label(address(s_weth), "WETH9");
62+
63+
s_tokenA = new MockERC20("Token A", "TKNA");
64+
vm.label(address(s_tokenA), "TKNA");
65+
s_tokenA.mint(s_deployer, 1000 ether);
66+
67+
s_tokenB = new MockERC20("Token B", "TKNB");
68+
vm.label(address(s_tokenB), "TKNB");
69+
s_tokenB.mint(s_deployer, 1000 ether);
70+
5471
vm.stopPrank();
5572
}
5673
}

test/unit/concrete/bridge/ensoCCIPReceiver/EnsoCCIPReceiver.tree

Lines changed: 107 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,55 +4,115 @@
44
// └── when caller is pending owner
55
// └── it should transfer ownership
66

7+
// EnsoCCIPReceiver::CcipReceive
8+
// # when caller is not ccipRouter
9+
// ## it should revert
10+
// # when caller is ccipRouter
11+
// ## when message was already executed
12+
// ### it should emit MessageValidationFailed
13+
// ### it should not update executedMessage
14+
// ## when message was not executed
15+
// ### when message has no tokens
16+
// #### it should emit MessageValidationFailed
17+
// #### it should update executedMessage
18+
// #### it should emit MessageQuarantined
19+
// ### when message has tokens
20+
// #### when message has more than one token
21+
// ##### it should emit MessageValidationFailed
22+
// ##### it should update executedMessage
23+
// ##### it should emit MessageQuarantined
24+
// ##### it should escrow message tokens
25+
// #### when message has single token
26+
// ##### when message token amount is zero
27+
// ###### it should emit MessageValidationFailed
28+
// ###### it should update executedMessage
29+
// ###### it should emit MessageQuarantined
30+
// ##### when message token amount is gt zero
31+
// ###### when message data is malformed
32+
// ####### it should emit MessageValidationFailed
33+
// ####### it should update executedMessage
34+
// ####### it should emit MessageQuarantined
35+
// ####### it should escrow message token
36+
// ###### when message data is well formed
37+
// ####### when message data receiver is zero address
38+
// ######## it should emit MessageValidationFailed
39+
// ######## it shoud update executedMessage
40+
// ######## it should escrow message token
41+
// ######## it should emit MessageQuarantined
42+
// ####### when message data receiver is not zero address
43+
// ######## when contract is paused
44+
// ######### it should emit MessageValidationFailed
45+
// ######### it shoud update executedMessage
46+
// ######### it should safe transfer token amount to receiver
47+
// ######## when contract is not paused
48+
// ######### when shortcut execution was successful
49+
// ########## it shoud update executedMessage
50+
// ########## it should emit ShortcutExecutionSuccessful
51+
// ######### when shortcut execution failed
52+
// ########## it shoud update executedMessage
53+
// ########## it should emit ShortcutExecutionFailed
54+
// ########## it should safe transfer token amount to receiver
55+
756
EnsoCCIPReceiver::CcipReceive
8-
# when caller is not ccipRouter
9-
## it should revert
10-
# when caller is ccipRouter
11-
## when message was already executed
12-
### it should emit MessageValidationFailed
13-
## when message was not executed
14-
### when message has no tokens
15-
#### it should emit MessageValidationFailed
16-
### when message has tokens
17-
#### when message has more than one token
18-
##### it should emit MessageValidationFailed
19-
#### when message has single token
20-
##### when message token amount is zero
21-
###### it should emit MessageValidationFailed
22-
##### when message token amount is gt zero
23-
###### when message data is malformed
24-
####### it should emit MessageValidationFailed
25-
###### when message data is well formed
26-
####### when message data receiver is zero address
27-
######## it should emit MessageValidationFailed
28-
######## it shoud set executedMessage to true
29-
######## it should emit MessageQuarantined
30-
######## it should escrow message token amount
31-
####### when message data receiver is not zero address
32-
######## when contract is paused
33-
######### it should emit MessageValidationFailed
34-
######### it shoud set executedMessage to true
35-
######### it should safe transfer token amount to receiver
36-
######## when contract is not paused
37-
######### when shortcut execution was was successful
38-
########## it shoud set executedMessage to true
39-
########## it should emit ShortcutExecutionSuccessful
40-
######### when shortcut execution failed
41-
########## it should emit ShortcutExecutionFailed
42-
########## it should safe transfer token amount to receiver
57+
├── when caller is not ccipRouter
58+
│ └── it should revert
59+
└── when caller is ccipRouter
60+
├── when message was already executed
61+
│ ├── it should emit MessageValidationFailed
62+
│ └── it should update executedMessage
63+
└── when message was not executed
64+
├── when message has no tokens
65+
│ ├── it should emit MessageValidationFailed
66+
│ └── it should not update executedMessage
67+
└── when message has tokens
68+
├── when message has more than one token
69+
│ ├── it should emit MessageValidationFailed
70+
│ ├── it should not update executedMessage
71+
│ ├── it should emit MessageQuarantined
72+
│ └── it should escrow message tokens
73+
└── when message has single token
74+
├── when message token amount is zero
75+
│ ├── it should emit MessageValidationFailed
76+
│ ├── it should not update executedMessage
77+
│ └── it should emit MessageQuarantined
78+
└── when message token amount is gt zero
79+
├── when message data is malformed
80+
│ ├── it should emit MessageValidationFailed
81+
│ ├── it should not update executedMessage
82+
│ ├── it should emit MessageQuarantined
83+
│ └── it should escrow message token
84+
└── when message data is well formed
85+
├── when message data receiver is zero address
86+
│ ├── it should emit MessageValidationFailed
87+
│ ├── it shoud update executedMessage
88+
│ ├── it should escrow message token
89+
│ └── it should emit MessageQuarantined
90+
└── when message data receiver is not zero address
91+
├── when contract is paused
92+
│ ├── it should emit MessageValidationFailed
93+
│ ├── it shoud update executedMessage
94+
│ └── it should safe transfer token amount to receiver
95+
└── when contract is not paused
96+
├── when shortcut execution was successful
97+
│ ├── it shoud update executedMessage
98+
│ └── it should emit ShortcutExecutionSuccessful
99+
└── when shortcut execution failed
100+
├── it shoud update executedMessage
101+
├── it should emit ShortcutExecutionFailed
102+
└── it should safe transfer token amount to receiver
43103

44104
// EnsoCCIPReceiver::Constructor
45105
// └── when deployed
46106
// ├── it should set owner
47107
// ├── it should set ccipRouter
48108
// └── it should set ensoRouter
49109

50-
EnsoCCIPReceiver::RecoverTokens
51-
# when caller is not self
52-
## it should revert
53-
# when caller is self
54-
## it should force approve amount to ensoRouter
55-
## it should call ensoRouter routeSingle
110+
// EnsoCCIPReceiver::RecoverTokens
111+
// # when caller is not self
112+
// ## it should revert
113+
// # when caller is self
114+
// ## it should force approve amount to ensoRouter
115+
// ## it should call ensoRouter routeSingle
56116

57117
// EnsoCCIPReceiver::Pause
58118
// ├── when caller is not owner
@@ -72,12 +132,12 @@ EnsoCCIPReceiver::RecoverTokens
72132
// └── when caller is owner
73133
// └── it should start ownership transfer
74134

75-
EnsoCCIPReceiver::RecoverTokens
76-
# when caller is not owner
77-
## it should revert
78-
# when caller is owner
79-
## it should safe transfer amount to recipient
80-
## it should emit TOkensRecovered
135+
// EnsoCCIPReceiver::RecoverTokens
136+
// # when caller is not owner
137+
// ## it should revert
138+
// # when caller is owner
139+
// ## it should safe transfer amount to recipient
140+
// ## it should emit TOkensRecovered
81141

82142
// EnsoCCIPReceiver::RenounceOwnership
83143
// ├── when caller is not owner

0 commit comments

Comments
 (0)