Skip to content

Add adapter#577

Merged
hieronx merged 32 commits intomainfrom
layerzero-adapter
Aug 27, 2025
Merged

Add adapter#577
hieronx merged 32 commits intomainfrom
layerzero-adapter

Conversation

@hieronx
Copy link
Copy Markdown
Contributor

@hieronx hieronx commented Aug 18, 2025

No description provided.

wischli

This comment was marked as off-topic.

wischli
wischli previously approved these changes Aug 19, 2025
Copy link
Copy Markdown
Contributor

@wischli wischli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a bunch of post-approval questions, minor nits and test additions. Great job!


/// @inheritdoc ILayerZeroReceiver
function nextNonce(uint32, bytes32) external pure override returns (uint64 nonce) {
return 0;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be sure: Based on the ILayerZero comment (ref), we return 0 here to not enforce nonce ordering, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed

Comment on lines +133 to +135
uint16 internal constant TYPE_3 = 3;
uint8 internal constant WORKER_ID = 1;
uint8 internal constant OPTION_TYPE_LZRECEIVE = 1;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Not a fan of storage values outside the header area

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally think this is a case of making an exception since it works better in this specific case. These aren't really storage variables, just configuration vars that only apply to the options. For that reason to me it seems more logical to have it grouped together.

Copy link
Copy Markdown
Contributor

@lemunozm lemunozm Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand what you want is name those "random" values. It's true it looks a bit different. Maybe we can just add variables to the method below if only used there.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is already audited, would not change this now. But yes could have been variables in the function too.

Comment on lines +134 to +135
uint8 internal constant WORKER_ID = 1;
uint8 internal constant OPTION_TYPE_LZRECEIVE = 1;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since these values were opaque to me, I looked into the LayerZero-v2 ExecutorOptions to confirm these values for the most recent TYPE_3 = 3: https://github.com/LayerZero-Labs/LayerZero-v2/blob/200cda254120375f40ed0a7e89931afb897b8891/packages/layerzero-v2/evm/messagelib/contracts/libs/ExecutorOptions.sol#L10-L12

Co-authored-by: William Freudenberger <w.freude@icloud.com>
@hieronx hieronx requested a review from wischli August 21, 2025 20:32
@hieronx hieronx enabled auto-merge August 21, 2025 20:33
Copy link
Copy Markdown
Contributor

@lemunozm lemunozm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Pretty similar scheme! Just some few comment, mostly NITs

Comment on lines +43 to +44
endpoint.setDelegate(delegate);
emit SetDelegate(delegate);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT, maybe we can call to setDelegate() directly

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using CastLib for *;
using MathLib for *;

IMessageHandler public immutable entrypoint;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we want to set this as mutable in order to avoid migrating this in v3.1

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All adapters have this now as immutable so would keep as is for now. Something to reconsider for v3.1 upgrade yeah

/// @inheritdoc IAdapter
function estimate(uint16 centrifugeId, bytes calldata payload, uint256 gasLimit) external view returns (uint256) {
LayerZeroDestination memory destination = destinations[centrifugeId];
MessagingFee memory fee = endpoint.quote(_params(destination, payload, gasLimit), address(this));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could the estimation fail because address(this) is not payable?

Maybe we should pass the refund address to this method too, to correctly estimate everything. Refunding will add some cost

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +133 to +135
uint16 internal constant TYPE_3 = 3;
uint8 internal constant WORKER_ID = 1;
uint8 internal constant OPTION_TYPE_LZRECEIVE = 1;
Copy link
Copy Markdown
Contributor

@lemunozm lemunozm Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand what you want is name those "random" values. It's true it looks a bit different. Maybe we can just add variables to the method below if only used there.

}

function quote(MessagingParams calldata, address) external pure returns (MessagingFee memory) {
// TODO: decode gas limit from params.options
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A reminder of this TODO

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I will remove this TODO. It is a bit complex, and not really much value. More valuable to add the integration tests that our auditors wrote to the codebase (https://gist.github.com/gvladika/ad74ef148840879b0b60fba96278a50e)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tracking ticket: #583

@github-actions
Copy link
Copy Markdown

Coverage after merging layerzero-adapter into main will be

96.42%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src/adapters
   AxelarAdapter.sol100%100%100%100%
   LayerZeroAdapter.sol87.50%100%80%86.84%81–83, 87–88
   WormholeAdapter.sol100%100%100%100%
src/common
   BaseValuation.sol100%100%100%100%
   GasService.sol96.88%100%100%96.67%106, 114
   Gateway.sol100%100%100%100%
   Guardian.sol89.04%64.29%100%93.02%130, 130–131, 48–52
   MessageDispatcher.sol97.40%92.59%100%99.12%64–68
   MessageProcessor.sol95.27%91.07%100%97.70%191, 51–55, 69
   MultiAdapter.sol100%100%100%100%
   PoolEscrow.sol100%100%100%100%
   Root.sol100%100%100%100%
   TokenRecoverer.sol100%100%100%100%
src/common/factories
   PoolEscrowFactory.sol100%100%100%100%
src/common/libraries
   MessageLib.sol100%100%100%100%
   MessageProofLib.sol100%100%100%100%
   PricingLib.sol100%100%100%100%
   RequestCallbackMessageLib.sol89.58%50%100%100%106, 141, 38, 57, 77
   RequestMessageLib.sol89.74%50%100%100%37, 55, 72, 89
src/hooks
   BaseTransferHook.sol100%100%100%100%
   FreelyTransferable.sol100%100%100%100%
   FreezeOnly.sol100%100%100%100%
   FullRestrictions.sol100%100%100%100%
   RedemptionRestrictions.sol100%100%100%100%
src/hooks/libraries
   UpdateRestrictionMessageLib.sol90%50%100%100%40, 61, 82
src/hub
   Accounting.sol93.75%96%100%91.53%114–115, 118–119, 134, 137
   Holdings.sol97.46%88%100%100%116, 222, 82
   Hub.sol85.27%44.68%100%90.50%110, 290, 429–430, 433, 433–434, 452, 455, 455–456, 476, 493, 510, 537, 541, 571–572, 572, 572–573, 573, 573, 578, 583, 601, 611, 621, 621, 621, 623, 637, 644–646, 736, 79–80, 80–81, 81–82, 82–83, 83–85
   HubHelpers.sol88.46%87.50%90%88.54%155–157, 163–165, 215, 239, 244–247, 54–55
   HubRegistry.sol93.67%79.17%100%100%104, 110, 116, 33, 44
   ShareClassManager.sol100%100%100%100%
src/managers
   MerkleProofManager.sol79.45%61.11%88.89%84.78%104, 111, 130–131, 131, 131, 133–134, 136–137, 40–41, 44, 54
   OnOfframpManager.sol100%100%100%100%
src/managers/decoders
   BaseDecoder.sol75%100%75%75%43–44
   CircleDecoder.sol0%100%0%0%11, 16, 20, 22
   VaultDecoder.sol0%100%0%0%10, 104, 110, 15–16, 22, 28, 34, 40, 46, 52, 58, 64, 69, 75, 80, 86, 9, 92, 98
src/misc
   Auth.sol100%100%100%100%
   ERC20.sol100%100%100%100%
   Escrow.sol56.25%33.33%100%66.67%15, 17, 21–22, 22, 22, 24
   Multicall.sol83.33%33.33%100%100%17, 17
   Recoverable.sol100%100%100%100%
   ReentrancyProtection.sol90%75%100%100%22
src/misc/libraries
   ArrayLib.sol95.83%75%100%100%26
   BitmapLib.sol100%100%100%100%
   BytesLib.sol90.09%54.17%100%100%109, 120, 131, 14, 142, 153, 16, 164, 175, 186, 87
   CastLib.sol95.24%66.67%100%100%10, 34
   EIP712Lib.sol100%100%100%100%
   MathLib.sol80.19%42.86%81.82%90.54%161, 167, 171–172, 172, 172–173, 177, 182, 193–194, 35–36, 45, 47, 49, 51, 53, 88
   MerkleProofLib.sol100%100%100%100%
   SafeTransferLib.sol96.97%92.86%100%100%75
   SignatureLib.sol95.24%80%100%100%17
   StringLib.sol100%100%100%100%
   TransientArrayLib.sol100%100%100%100%
   TransientBytesLib.sol100%100%100%100%
   TransientStorageLib.sol100%100%100%100%
src/spoke
   BalanceSheet.sol99.46%96.77%100%100%59
   ContractUpdater.sol100%100%100%100%
   ShareToken.sol93.59%66.67%94.44%98.04%101, 113, 146, 33
   Spoke.sol95.26%85.57%100%98.67%102, 102–103, 103, 128, 128–129, 129, 131, 330, 336–338, 393–394, 420–421
src/spoke/factories
   TokenFactory.sol92%50%100%94.74%24–25
src/spoke/libraries
   UpdateContractMessageLib.sol89.74%50%100%100%110, 40, 62, 86
src/valuations
   IdentityValuation.sol100%100%100%100%
src/vaults
   AsyncRequestManager.sol95.03%85.71%93.02%98.35%164, 167, 170, 173, 184, 196, 201, 220, 227, 260, 294, 408, 413, 452, 454
   AsyncVault.sol96.25%83.33%95%98.15%148, 49
   BaseVaults.sol92.50%80.77%95.24%93.94%125, 138, 240, 313–314, 400–401, 86–87, 87, 87–89
   SyncDepositVault.sol100%100%100%100%
   SyncManager.sol83.19%70%87.50%85.71%106–107, 109, 161, 181–182, 227–228, 59–61, 63, 63, 63, 65, 70, 75
   VaultRouter.sol91.16%53.85%100%98.97%105, 108–109, 122, 122–123, 123, 138–139, 158, 158, 175, 221
src/vaults/factories
   AsyncVaultFactory.sol89.47%50%100%93.33%36, 48
   SyncDepositVaultFactory.sol91.30%50%100%94.74%45, 60

@hieronx hieronx merged commit ab653b5 into main Aug 27, 2025
10 checks passed
@hieronx hieronx deleted the layerzero-adapter branch August 27, 2025 07:40
@lemunozm
Copy link
Copy Markdown
Contributor

As a note, the configuration is missing in WireAdapters.s.sol

@wischli wischli restored the layerzero-adapter branch August 28, 2025 14:21
wischli added a commit that referenced this pull request Sep 1, 2025
tests: improve AdaptersDeploymentInputTest
@wischli wischli mentioned this pull request Sep 1, 2025
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants