Skip to content

Commit 08685bf

Browse files
committed
feat(evm): upgrade wormhole-solidity-sdk to v1.1.0 with gas optimizations
Migrate from wormhole-solidity-sdk v0.1.0 to v1.1.0. Replace parseAndVerifyVM with client-side CoreBridgeLib.decodeAndVerifyVaaCd, switch receiveMessage to calldata, use VaaLib.calcVaaDoubleHashCd for replay protection, inline nttManagerMessageDigest, add constant-time countSetBits popcount, cache transceiver index in attestation, and replace ConfigMakers with SDK's CustomConsistencyLib. receiveMessage gas: avg -21.6%, median -18.1%, max -12.0%. Deployment size: -14.1%. Bump NttManager and WormholeTransceiver to v2.1.0 with TS SDK bindings.
1 parent 9607ca7 commit 08685bf

41 files changed

Lines changed: 6751 additions & 659 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

evm/echidna/FuzzNttManager.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import "./helpers/FuzzingHelpers.sol";
1414
import "openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol";
1515
import "solidity-bytes-utils/BytesLib.sol";
1616
import "../test/mocks/DummyTransceiver.sol";
17-
import "wormhole-solidity-sdk/Utils.sol";
17+
import "wormhole-sdk/Utils.sol";
1818

1919
contract FuzzNttManager is FuzzingHelpers {
2020
uint64[] queuedOutboundTransfersArray;

evm/foundry.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99
"rev": "e0115c4d231910df47ce3b60625ce562fe4af985"
1010
},
1111
"lib/wormhole-solidity-sdk": {
12-
"rev": "b9e129e65d34827d92fceeed8c87d3ecdfc801d0"
12+
"rev": "d80e0f6cd16f281f3f9df435e98e823b4212b2ad"
1313
}
1414
}

evm/foundry.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
[profile.default]
2-
solc_version = "0.8.19"
2+
solc_version = "0.8.24"
33
optimizer = true
44
optimizer_runs = 200
5-
via_ir = false
5+
via_ir = true
66
evm_version = "london"
77
src = "src"
88
out = "out"

evm/lib/wormhole-solidity-sdk

evm/remappings.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
wormhole-solidity-sdk/=lib/wormhole-solidity-sdk/src/
2+
wormhole-sdk/=lib/wormhole-solidity-sdk/src/

evm/script/DeployWormholeNtt.s.sol

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,11 @@ import {INttManager} from "../src/interfaces/INttManager.sol";
99
import {IWormholeTransceiver} from "../src/interfaces/IWormholeTransceiver.sol";
1010
import "../src/interfaces/IManagerBase.sol";
1111
import "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
12+
import {ICoreBridge} from "wormhole-sdk/interfaces/ICoreBridge.sol";
1213
import {NttManager} from "../src/NttManager/NttManager.sol";
1314
import {NttManagerNoRateLimiting} from "../src/NttManager/NttManagerNoRateLimiting.sol";
1415
import {NttManagerWethUnwrap} from "../src/NttManager/NttManagerWethUnwrap.sol";
1516

16-
interface IWormhole {
17-
function chainId() external view returns (uint16);
18-
}
19-
2017
contract DeployWormholeNtt is Script, DeployWormholeNttBase {
2118
function run() public {
2219
vm.startBroadcast();
@@ -32,7 +29,7 @@ contract DeployWormholeNtt is Script, DeployWormholeNttBase {
3229
modeUint == 0 ? IManagerBase.Mode.LOCKING : IManagerBase.Mode.BURNING;
3330
string memory managerVariant = vm.envOr("MANAGER_VARIANT", string("standard"));
3431

35-
IWormhole wh = IWormhole(wormhole);
32+
ICoreBridge wh = ICoreBridge(wormhole);
3633

3734
// sanity check decimals
3835
(bool success, bytes memory queriedDecimals) =

evm/script/helpers/DeployWormholeNttBase.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
WormholeTransceiver
1515
} from "../../src/Transceiver/WormholeTransceiver/WormholeTransceiver.sol";
1616
import {ERC1967Proxy} from "openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol";
17-
import {IWormhole} from "wormhole-solidity-sdk/interfaces/IWormhole.sol";
17+
import {ICoreBridge} from "wormhole-sdk/interfaces/ICoreBridge.sol";
1818

1919
contract DeployWormholeNttBase is ParseNttConfig {
2020
/// @notice Parameters for deploying NTT contracts
@@ -106,7 +106,7 @@ contract DeployWormholeNttBase is ParseNttConfig {
106106
WormholeTransceiver transceiverProxy =
107107
WormholeTransceiver(address(new ERC1967Proxy(address(implementation), "")));
108108

109-
IWormhole wh = IWormhole(params.wormholeCoreBridge);
109+
ICoreBridge wh = ICoreBridge(params.wormholeCoreBridge);
110110
uint256 messageFee = wh.messageFee();
111111
// wh transceiver sends a WH_TRANSCEIVER_INIT_PREFIX message
112112
transceiverProxy.initialize{value: messageFee}();

evm/script/helpers/ParseNttConfig.sol

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {stdJson} from "forge-std/StdJson.sol";
66

77
import "../../src/interfaces/INttManager.sol";
88
import "../../src/interfaces/IWormholeTransceiver.sol";
9+
import {toUniversalAddress, fromUniversalAddress} from "wormhole-sdk/Utils.sol";
910

1011
contract ParseNttConfig is Script {
1112
using stdJson for string;
@@ -25,24 +26,6 @@ contract ParseNttConfig is Script {
2526

2627
mapping(uint16 => bool) duplicateChainIds;
2728

28-
function toUniversalAddress(
29-
address evmAddr
30-
) internal pure returns (bytes32 converted) {
31-
assembly ("memory-safe") {
32-
converted := and(0xffffffffffffffffffffffffffffffffffffffff, evmAddr)
33-
}
34-
}
35-
36-
function fromUniversalAddress(
37-
bytes32 universalAddr
38-
) internal pure returns (address converted) {
39-
require(bytes12(universalAddr) == 0, "Address overflow");
40-
41-
assembly ("memory-safe") {
42-
converted := universalAddr
43-
}
44-
}
45-
4629
function _parseAndValidateConfigFile(
4730
uint16 wormholeChainId
4831
)

evm/src/NttManager/ManagerBase.sol

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// SPDX-License-Identifier: Apache 2
22
pragma solidity >=0.8.8 <0.9.0;
33

4-
import "wormhole-solidity-sdk/Utils.sol";
5-
import "wormhole-solidity-sdk/libraries/BytesParsing.sol";
4+
import "wormhole-sdk/Utils.sol";
5+
import "wormhole-sdk/libraries/BytesParsing.sol";
66

77
import "../libraries/external/OwnableUpgradeable.sol";
88
import "../libraries/external/ReentrancyGuardUpgradeable.sol";
@@ -146,16 +146,20 @@ abstract contract ManagerBase is
146146
bytes32 nttManagerMessageHash =
147147
TransceiverStructs.nttManagerMessageDigest(sourceChainId, payload);
148148

149+
// Cache the transceiver index to avoid redundant storage reads.
150+
uint8 index = _getTransceiverInfosStorage()[msg.sender].index;
151+
149152
// set the attested flag for this transceiver.
150153
// NOTE: Attestation is idempotent (bitwise or 1), but we revert
151154
// anyway to ensure that the client does not continue to initiate calls
152155
// to receive the same message through the same transceiver.
153-
if (transceiverAttestedToMessage(
154-
nttManagerMessageHash, _getTransceiverInfosStorage()[msg.sender].index
155-
)) {
156+
if (transceiverAttestedToMessage(nttManagerMessageHash, index)) {
156157
revert TransceiverAlreadyAttestedToMessage(nttManagerMessageHash);
157158
}
158-
_setTransceiverAttestedToMessage(nttManagerMessageHash, msg.sender);
159+
_setTransceiverAttestedToMessage(nttManagerMessageHash, index);
160+
161+
// msg.sender is the transceiver address (guaranteed by onlyTransceiver modifier)
162+
emit MessageAttestedTo(nttManagerMessageHash, msg.sender, index);
159163

160164
return nttManagerMessageHash;
161165
}
@@ -430,16 +434,6 @@ abstract contract ManagerBase is
430434
_getMessageAttestationsStorage()[digest].attestedTransceivers |= uint64(1 << index);
431435
}
432436

433-
function _setTransceiverAttestedToMessage(
434-
bytes32 digest,
435-
address transceiver
436-
) internal {
437-
_setTransceiverAttestedToMessage(digest, _getTransceiverInfosStorage()[transceiver].index);
438-
439-
emit MessageAttestedTo(
440-
digest, transceiver, _getTransceiverInfosStorage()[transceiver].index
441-
);
442-
}
443437

444438
/// @dev Returns the bitmap of attestations from enabled transceivers for a given message.
445439
function _getMessageAttestations(

evm/src/NttManager/NttManager.sol

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ pragma solidity >=0.8.8 <0.9.0;
44
import "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
55
import "openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol";
66
import "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol";
7-
import "wormhole-solidity-sdk/Utils.sol";
8-
import "wormhole-solidity-sdk/libraries/BytesParsing.sol";
7+
import "wormhole-sdk/Utils.sol";
8+
import "wormhole-sdk/libraries/BytesParsing.sol";
99

1010
import "../libraries/RateLimiter.sol";
1111

@@ -41,7 +41,7 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
4141
using TrimmedAmountLib for uint256;
4242
using TrimmedAmountLib for TrimmedAmount;
4343

44-
string public constant NTT_MANAGER_VERSION = "2.0.0";
44+
string public constant NTT_MANAGER_VERSION = "2.1.0";
4545

4646
// =============== Setup =================================================================
4747

@@ -245,7 +245,7 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
245245
TrimmedAmount nativeTransferAmount =
246246
(nativeTokenTransfer.amount.untrim(toDecimals)).trim(toDecimals, toDecimals);
247247

248-
address transferRecipient = fromWormholeFormat(nativeTokenTransfer.to);
248+
address transferRecipient = fromUniversalAddress(nativeTokenTransfer.to);
249249

250250
bool enqueued = _enqueueOrConsumeInboundRateLimit(
251251
digest, sourceChainId, nativeTransferAmount, transferRecipient
@@ -551,7 +551,7 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
551551
bytes memory encodedNttManagerPayload = TransceiverStructs.encodeNttManagerMessage(
552552
TransceiverStructs.NttManagerMessage(
553553
bytes32(uint256(seq)),
554-
toWormholeFormat(sender),
554+
toUniversalAddress(sender),
555555
TransceiverStructs.encodeNativeTokenTransfer(ntt)
556556
)
557557
);
@@ -609,7 +609,7 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
609609
bytes32 // refundAddress
610610
) internal virtual returns (TransceiverStructs.NativeTokenTransfer memory) {
611611
return TransceiverStructs.NativeTokenTransfer(
612-
amount, toWormholeFormat(token), recipient, recipientChain, ""
612+
amount, toUniversalAddress(token), recipient, recipientChain, ""
613613
);
614614
}
615615

0 commit comments

Comments
 (0)