Skip to content

Commit a4cea90

Browse files
committed
chore: update slim testhelper
1 parent 3867459 commit a4cea90

File tree

3 files changed

+378
-86
lines changed

3 files changed

+378
-86
lines changed

packages/test-devtools-evm-foundry/contracts/SlimLzTestHelper.sol

Lines changed: 134 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { DoubleEndedQueue } from "@openzeppelin/contracts/utils/structs/DoubleEn
1111
// Protocol
1212
import { Origin, ILayerZeroEndpointV2 } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol";
1313
import { PacketV1Codec } from "@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/PacketV1Codec.sol";
14+
import { ExecutorOptions } from "@layerzerolabs/lz-evm-messagelib-v2/contracts/libs/ExecutorOptions.sol";
1415

1516
// Minimal Mocks
1617
import { EndpointV2Simple as EndpointV2 } from "./mocks/EndpointV2Simple.sol";
@@ -24,37 +25,37 @@ interface IOAppSetPeer {
2425

2526
/**
2627
* @title SlimLzTestHelper
27-
* @notice Lightweight helper contract for basic LayerZero OApp testing without compile size issues.
28+
* @notice Lightweight helper contract for basic LayerZero OApp testing without compile size issues
2829
* @dev Maintains backward compatibility with TestHelperOz5 for basic testing scenarios.
29-
* @dev For advanced features (DVN, Executor, workers), use TestHelperOz5 instead.
30+
* For advanced features (DVN, Executor, workers), use TestHelperOz5 instead.
3031
*/
3132
contract SlimLzTestHelper is Test, OptionsHelper {
33+
using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque;
34+
using PacketV1Codec for bytes;
35+
3236
// ==================== Custom Errors ====================
3337

34-
/// @notice Core operational errors
35-
/// @dev Thrown when trying to verify packets for an unregistered endpoint
38+
/// @notice Thrown when trying to verify packets for an unregistered endpoint
3639
/// @param eid The endpoint ID that was not found
3740
error SlimLzTestHelper_EndpointNotRegistered(uint32 eid);
3841

39-
/// @dev Thrown when native drop transfer fails
42+
/// @notice Thrown when native drop transfer fails
4043
/// @param receiver The address that failed to receive native tokens
4144
/// @param amount The amount that failed to transfer
4245
error SlimLzTestHelper_NativeDropFailed(address receiver, uint256 amount);
4346

44-
/// @dev Thrown when packet GUID doesn't match expected value
47+
/// @notice Thrown when packet GUID doesn't match expected value
4548
/// @param expected The expected GUID value
4649
/// @param actual The actual GUID value found in packet
4750
error SlimLzTestHelper_GuidMismatch(bytes32 expected, bytes32 actual);
4851

49-
/// @dev Thrown when packet validation fails
52+
/// @notice Thrown when packet validation fails
5053
/// @param guid The GUID of the packet that failed validation
5154
error SlimLzTestHelper_PacketValidationFailed(bytes32 guid);
5255

53-
/// @dev Thrown when attempting to schedule a packet with duplicate GUID
56+
/// @notice Thrown when attempting to schedule a packet with duplicate GUID
5457
/// @param guid The duplicate GUID that was detected
5558
error SlimLzTestHelper_DuplicateGuid(bytes32 guid);
56-
using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque;
57-
using PacketV1Codec for bytes;
5859

5960
enum LibraryType {
6061
UltraLightNode,
@@ -78,32 +79,34 @@ contract SlimLzTestHelper is Test, OptionsHelper {
7879
mapping(bytes32 => bytes) optionsLookup;
7980
mapping(uint32 => address) endpoints;
8081

81-
// Constants
8282
uint128 public executorValueCap = 0.1 ether;
8383

8484
// Maintain same visibility as TestHelperOz5
8585
EndpointSetup internal endpointSetup;
8686

87-
/// @dev Initializes test environment setup
87+
/// @notice Initializes test environment setup
8888
function setUp() public virtual {
8989
_setUpUlnOptions();
9090
}
9191

9292
/**
93-
* @dev set executorValueCap if more than 0.1 ether is necessary
94-
* @param _valueCap amount executor can pass as msg.value to lzReceive()
93+
* @notice Sets the maximum value that can be passed to lzReceive() calls
94+
* @dev Default is 0.1 ether, call this to increase if needed
95+
*
96+
* @param _valueCap The new maximum value cap
9597
*/
9698
function setExecutorValueCap(uint128 _valueCap) public {
9799
executorValueCap = _valueCap;
98100
}
99101

100102
/**
101-
* @notice Sets up endpoints - maintains backward compatibility
103+
* @notice Sets up endpoints for testing
104+
* @dev Creates endpoints and configures them with SimpleMessageLib
105+
*
102106
* @param _endpointNum Number of endpoints to create
103107
*/
104-
function setUpEndpoints(uint8 _endpointNum, LibraryType /* _libraryType */) public {
105-
// In slim version, we always use SimpleMessageLib regardless of _libraryType
106-
// This maintains API compatibility while simplifying implementation
108+
function setUpEndpoints(uint8 _endpointNum) public {
109+
// In slim version, we always use SimpleMessageLib
107110

108111
endpointSetup.endpointList = new EndpointV2[](_endpointNum);
109112
endpointSetup.eidList = new uint32[](_endpointNum);
@@ -148,14 +151,43 @@ contract SlimLzTestHelper is Test, OptionsHelper {
148151
}
149152

150153
/**
151-
* @notice Overload for backward compatibility
154+
* @notice Overload for backward compatibility with LibraryType parameter
155+
* @dev Library type is ignored - always uses SimpleMessageLib
156+
*
157+
* @param _endpointNum Number of endpoints to create
152158
*/
153-
function setUpEndpoints(uint8 _endpointNum) public {
154-
setUpEndpoints(_endpointNum, LibraryType.SimpleMessageLib);
159+
function setUpEndpoints(uint8 _endpointNum, LibraryType /* _libraryType */) public {
160+
setUpEndpoints(_endpointNum);
161+
}
162+
163+
/**
164+
* @notice Deploys an OApp contract
165+
* @dev Uses CREATE opcode to deploy contract with constructor arguments
166+
*
167+
* @param _oappBytecode The OApp contract bytecode
168+
* @param _constructorArgs The encoded constructor arguments
169+
*
170+
* @return addr The deployed contract address
171+
*/
172+
function _deployOApp(bytes memory _oappBytecode, bytes memory _constructorArgs) internal returns (address addr) {
173+
bytes memory bytecode = bytes.concat(abi.encodePacked(_oappBytecode), _constructorArgs);
174+
assembly {
175+
addr := create(0, add(bytecode, 0x20), mload(bytecode))
176+
if iszero(extcodesize(addr)) {
177+
revert(0, 0)
178+
}
179+
}
155180
}
156181

157182
/**
158183
* @notice Sets up mock OApp contracts for testing
184+
* @dev Deploys OApp contracts and wires them together
185+
*
186+
* @param _oappCreationCode The bytecode for creating OApp contracts
187+
* @param _startEid The starting endpoint ID
188+
* @param _oappNum The number of OApp contracts to create
189+
*
190+
* @return oapps Array of deployed OApp addresses
159191
*/
160192
function setupOApps(
161193
bytes memory _oappCreationCode,
@@ -172,6 +204,9 @@ contract SlimLzTestHelper is Test, OptionsHelper {
172204

173205
/**
174206
* @notice Configures the peers between multiple OApp instances
207+
* @dev Sets up bidirectional peer relationships between all OApps
208+
*
209+
* @param oapps Array of OApp addresses to wire together
175210
*/
176211
function wireOApps(address[] memory oapps) public {
177212
uint256 size = oapps.length;
@@ -186,22 +221,12 @@ contract SlimLzTestHelper is Test, OptionsHelper {
186221
}
187222
}
188223

189-
/**
190-
* @notice Deploys an OApp contract
191-
*/
192-
function _deployOApp(bytes memory _oappBytecode, bytes memory _constructorArgs) internal returns (address addr) {
193-
bytes memory bytecode = bytes.concat(abi.encodePacked(_oappBytecode), _constructorArgs);
194-
assembly {
195-
addr := create(0, add(bytecode, 0x20), mload(bytecode))
196-
if iszero(extcodesize(addr)) {
197-
revert(0, 0)
198-
}
199-
}
200-
}
201-
202224
/**
203225
* @notice Schedules a packet for delivery
204-
* @dev Includes optional duplicate GUID detection for enhanced safety
226+
* @dev Stores packet and options for later verification. Includes optional duplicate GUID detection.
227+
*
228+
* @param _packetBytes The encoded packet data
229+
* @param _options The executor options for packet delivery
205230
*/
206231
function schedulePacket(bytes calldata _packetBytes, bytes calldata _options) public {
207232
uint32 dstEid = _packetBytes.dstEid();
@@ -220,21 +245,36 @@ contract SlimLzTestHelper is Test, OptionsHelper {
220245
}
221246

222247
/**
223-
* @notice Verifies and processes packets
248+
* @notice Verifies and processes all pending packets for a destination
249+
* @dev Convenience function that processes all packets without compose
250+
*
251+
* @param _dstEid The destination endpoint ID
252+
* @param _dstAddress The destination address as bytes32
224253
*/
225254
function verifyPackets(uint32 _dstEid, bytes32 _dstAddress) public {
226255
verifyPackets(_dstEid, _dstAddress, 0, address(0x0), bytes(""));
227256
}
228257

229258
/**
230-
* @notice Verifies packets by address
259+
* @notice Verifies and processes all pending packets for a destination address
260+
* @dev Convenience function that converts address to bytes32
261+
*
262+
* @param _dstEid The destination endpoint ID
263+
* @param _dstAddress The destination address
231264
*/
232265
function verifyPackets(uint32 _dstEid, address _dstAddress) public {
233266
verifyPackets(_dstEid, bytes32(uint256(uint160(_dstAddress))), 0, address(0x0), bytes(""));
234267
}
235268

236269
/**
237-
* @notice Main packet verification and delivery
270+
* @notice Main packet verification and delivery function
271+
* @dev Processes packets from queue, executes lzReceive, handles native drops and compose
272+
*
273+
* @param _dstEid The destination endpoint ID
274+
* @param _dstAddress The destination address as bytes32
275+
* @param _packetAmount Number of packets to process (0 for all)
276+
* @param _composer The composer address for lzCompose calls
277+
* @param _resolvedPayload Payload for packet validation (currently unused)
238278
*/
239279
function verifyPackets(
240280
uint32 _dstEid,
@@ -291,6 +331,13 @@ contract SlimLzTestHelper is Test, OptionsHelper {
291331
}
292332
}
293333

334+
/**
335+
* @notice Executes lzReceive for a packet
336+
* @dev Extracts gas and value from options and calls endpoint's lzReceive
337+
*
338+
* @param _packetBytes The encoded packet data
339+
* @param _options The executor options containing gas and value limits
340+
*/
294341
function lzReceive(bytes calldata _packetBytes, bytes memory _options) external payable {
295342
EndpointV2 endpoint = EndpointV2(endpoints[_packetBytes.dstEid()]);
296343
(uint256 gas, uint256 value) = _parseExecutorLzReceiveOption(_options);
@@ -305,6 +352,15 @@ contract SlimLzTestHelper is Test, OptionsHelper {
305352
);
306353
}
307354

355+
/**
356+
* @notice Executes lzCompose for a packet
357+
* @dev Convenience wrapper that extracts packet data and calls full lzCompose
358+
*
359+
* @param _packetBytes The encoded packet data
360+
* @param _options The executor options
361+
* @param _guid The packet GUID
362+
* @param _composer The composer address
363+
*/
308364
function lzCompose(
309365
bytes calldata _packetBytes,
310366
bytes memory _options,
@@ -321,6 +377,17 @@ contract SlimLzTestHelper is Test, OptionsHelper {
321377
);
322378
}
323379

380+
/**
381+
* @notice Executes lzCompose with full parameters
382+
* @dev Extracts gas and value from options and calls endpoint's lzCompose
383+
*
384+
* @param _dstEid The destination endpoint ID
385+
* @param _from The sender address
386+
* @param _options The executor options
387+
* @param _guid The packet GUID
388+
* @param _to The composer contract address
389+
* @param _composerMsg The message for the composer
390+
*/
324391
function lzCompose(
325392
uint32 _dstEid,
326393
address _from,
@@ -334,6 +401,12 @@ contract SlimLzTestHelper is Test, OptionsHelper {
334401
endpoint.lzCompose{ value: value, gas: gas }(_from, _to, _guid, index, _composerMsg, bytes(""));
335402
}
336403

404+
/**
405+
* @notice Validates a packet
406+
* @dev Calls the receive library's validatePacket function
407+
*
408+
* @param _packetBytes The encoded packet data
409+
*/
337410
function validatePacket(bytes calldata _packetBytes, bytes memory /* _resolvedPayload */) external {
338411
uint32 dstEid = _packetBytes.dstEid();
339412
EndpointV2 endpoint = EndpointV2(endpoints[dstEid]);
@@ -343,23 +416,42 @@ contract SlimLzTestHelper is Test, OptionsHelper {
343416
SlimSimpleMessageLibMock(payable(receiveLib)).validatePacket(_packetBytes);
344417
}
345418

419+
/**
420+
* @notice Asserts that a packet's GUID matches the expected value
421+
* @dev Reverts if GUIDs don't match
422+
*
423+
* @param packetBytes The encoded packet data
424+
* @param guid The expected GUID
425+
*/
346426
function assertGuid(bytes calldata packetBytes, bytes32 guid) external pure {
347427
bytes32 packetGuid = packetBytes.guid();
348428
if (packetGuid != guid) {
349429
revert SlimLzTestHelper_GuidMismatch(guid, packetGuid);
350430
}
351431
}
352432

433+
/**
434+
* @notice Registers an endpoint for testing
435+
* @dev Maps endpoint ID to endpoint address
436+
*
437+
* @param endpoint The endpoint to register
438+
*/
353439
function registerEndpoint(EndpointV2 endpoint) public {
354440
endpoints[endpoint.eid()] = address(endpoint);
355441
}
356442

443+
/**
444+
* @notice Converts an address to bytes32
445+
* @dev Used for OApp peer configuration
446+
*
447+
* @param _addr The address to convert
448+
*
449+
* @return The address as bytes32
450+
*/
357451
function addressToBytes32(address _addr) internal pure returns (bytes32) {
358452
return bytes32(uint256(uint160(_addr)));
359453
}
360454

455+
/// @notice Allows contract to receive native tokens
361456
receive() external payable {}
362-
}
363-
364-
// Import ExecutorOptions for compatibility
365-
import { ExecutorOptions } from "@layerzerolabs/lz-evm-messagelib-v2/contracts/libs/ExecutorOptions.sol";
457+
}

0 commit comments

Comments
 (0)