Skip to content

Commit ed25e9b

Browse files
committed
evm: Prevent registering peers on the same chain
1 parent b74b447 commit ed25e9b

File tree

4 files changed

+59
-40
lines changed

4 files changed

+59
-40
lines changed

evm/src/NttManager/NttManager.sol

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ contract NttManager is INttManager, RateLimiter, ManagerBase {
114114
if (decimals == 0) {
115115
revert InvalidPeerDecimals();
116116
}
117+
if (peerChainId == chainId) {
118+
revert InvalidPeerSameChainId();
119+
}
117120

118121
NttManagerPeer memory oldPeer = _getPeersStorage()[peerChainId];
119122

evm/src/interfaces/INttManager.sol

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ interface INttManager is IManagerBase {
131131
/// @dev Selector 0xbd28e889.
132132
error UnexpectedMsgValue();
133133

134+
/// @notice Peer cannot be on the same chain
135+
/// @dev Selector 0x20371f2a.
136+
error InvalidPeerSameChainId();
137+
134138
/// @notice Transfer a given amount to a recipient on a given chain. This function is called
135139
/// by the user to send the token cross-chain. This function will either lock or burn the
136140
/// sender's tokens. Finally, this function will call into registered `Endpoint` contracts

evm/test/NttManager.t.sol

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ contract TestNttManager is Test, IRateLimiterEvents {
3737

3838
// 0x99'E''T''T'
3939
uint16 constant chainId = 7;
40+
uint16 constant chainId2 = 8;
4041
uint256 constant DEVNET_GUARDIAN_PK =
4142
0xcfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0;
4243
WormholeSimulator guardian;
@@ -109,7 +110,7 @@ contract TestNttManager is Test, IRateLimiterEvents {
109110
uint8 decimals = t.decimals();
110111

111112
nttManagerZeroRateLimiter.setPeer(
112-
chainId, toWormholeFormat(address(0x1)), 9, type(uint64).max
113+
chainId2, toWormholeFormat(address(0x1)), 9, type(uint64).max
113114
);
114115

115116
t.mintDummy(address(user_A), 5 * 10 ** decimals);
@@ -119,13 +120,13 @@ contract TestNttManager is Test, IRateLimiterEvents {
119120
t.approve(address(nttManagerZeroRateLimiter), 3 * 10 ** decimals);
120121

121122
uint64 s1 = nttManagerZeroRateLimiter.transfer(
122-
1 * 10 ** decimals, chainId, toWormholeFormat(user_B)
123+
1 * 10 ** decimals, chainId2, toWormholeFormat(user_B)
123124
);
124125
uint64 s2 = nttManagerZeroRateLimiter.transfer(
125-
1 * 10 ** decimals, chainId, toWormholeFormat(user_B)
126+
1 * 10 ** decimals, chainId2, toWormholeFormat(user_B)
126127
);
127128
uint64 s3 = nttManagerZeroRateLimiter.transfer(
128-
1 * 10 ** decimals, chainId, toWormholeFormat(user_B)
129+
1 * 10 ** decimals, chainId2, toWormholeFormat(user_B)
129130
);
130131
vm.stopPrank();
131132

@@ -336,7 +337,7 @@ contract TestNttManager is Test, IRateLimiterEvents {
336337

337338
uint8 decimals = token.decimals();
338339

339-
newNttManager.setPeer(chainId, toWormholeFormat(address(0x1)), 9, type(uint64).max);
340+
newNttManager.setPeer(chainId2, toWormholeFormat(address(0x1)), 9, type(uint64).max);
340341
newNttManager.setOutboundLimit(packTrimmedAmount(type(uint64).max, 8).untrim(decimals));
341342

342343
token.mintDummy(address(user_A), 5 * 10 ** decimals);
@@ -348,7 +349,7 @@ contract TestNttManager is Test, IRateLimiterEvents {
348349
vm.expectRevert(abi.encodeWithSelector(IManagerBase.NoEnabledTransceivers.selector));
349350
newNttManager.transfer(
350351
1 * 10 ** decimals,
351-
chainId,
352+
chainId2,
352353
toWormholeFormat(user_B),
353354
toWormholeFormat(user_A),
354355
false,
@@ -398,7 +399,7 @@ contract TestNttManager is Test, IRateLimiterEvents {
398399

399400
uint8 decimals = token.decimals();
400401

401-
nttManager.setPeer(chainId, toWormholeFormat(address(0x1)), 9, type(uint64).max);
402+
nttManager.setPeer(chainId2, toWormholeFormat(address(0x1)), 9, type(uint64).max);
402403
nttManager.setOutboundLimit(packTrimmedAmount(type(uint64).max, 8).untrim(decimals));
403404

404405
token.mintDummy(address(user_A), 5 * 10 ** decimals);
@@ -418,7 +419,7 @@ contract TestNttManager is Test, IRateLimiterEvents {
418419

419420
nttManager.transfer(
420421
1 * 10 ** decimals,
421-
chainId,
422+
chainId2,
422423
toWormholeFormat(user_B),
423424
toWormholeFormat(user_A),
424425
false,
@@ -434,7 +435,7 @@ contract TestNttManager is Test, IRateLimiterEvents {
434435

435436
uint8 decimals = token.decimals();
436437

437-
nttManager.setPeer(chainId, toWormholeFormat(address(0x1)), 9, type(uint64).max);
438+
nttManager.setPeer(chainId2, toWormholeFormat(address(0x1)), 9, type(uint64).max);
438439
nttManager.setOutboundLimit(0);
439440

440441
token.mintDummy(address(user_A), 5 * 10 ** decimals);
@@ -448,7 +449,7 @@ contract TestNttManager is Test, IRateLimiterEvents {
448449

449450
uint64 s1 = nttManager.transfer(
450451
1 * 10 ** decimals,
451-
chainId,
452+
chainId2,
452453
toWormholeFormat(user_B),
453454
toWormholeFormat(user_A),
454455
true,
@@ -485,7 +486,7 @@ contract TestNttManager is Test, IRateLimiterEvents {
485486
// The next transfer has previous sequence number + 1
486487
uint64 s2 = nttManager.transfer(
487488
1 * 10 ** decimals,
488-
chainId,
489+
chainId2,
489490
toWormholeFormat(user_B),
490491
toWormholeFormat(user_A),
491492
true,
@@ -683,7 +684,7 @@ contract TestNttManager is Test, IRateLimiterEvents {
683684

684685
uint8 decimals = token.decimals();
685686

686-
nttManager.setPeer(chainId, toWormholeFormat(address(0x1)), 9, type(uint64).max);
687+
nttManager.setPeer(chainId2, toWormholeFormat(address(0x1)), 9, type(uint64).max);
687688
nttManager.setOutboundLimit(packTrimmedAmount(type(uint64).max, 8).untrim(decimals));
688689

689690
token.mintDummy(address(user_A), 5 * 10 ** decimals);
@@ -694,23 +695,23 @@ contract TestNttManager is Test, IRateLimiterEvents {
694695

695696
uint64 s1 = nttManager.transfer(
696697
1 * 10 ** decimals,
697-
chainId,
698+
chainId2,
698699
toWormholeFormat(user_B),
699700
toWormholeFormat(user_A),
700701
false,
701702
new bytes(1)
702703
);
703704
uint64 s2 = nttManager.transfer(
704705
1 * 10 ** decimals,
705-
chainId,
706+
chainId2,
706707
toWormholeFormat(user_B),
707708
toWormholeFormat(user_A),
708709
false,
709710
new bytes(1)
710711
);
711712
uint64 s3 = nttManager.transfer(
712713
1 * 10 ** decimals,
713-
chainId,
714+
chainId2,
714715
toWormholeFormat(user_B),
715716
toWormholeFormat(user_A),
716717
false,
@@ -724,7 +725,7 @@ contract TestNttManager is Test, IRateLimiterEvents {
724725

725726
function test_transferWithAmountAndDecimalsThatCouldOverflow() public {
726727
// The source chain has 18 decimals trimmed to 8, and the peer has 6 decimals trimmed to 6
727-
nttManager.setPeer(chainId, toWormholeFormat(address(0x1)), 6, type(uint64).max);
728+
nttManager.setPeer(chainId2, toWormholeFormat(address(0x1)), 6, type(uint64).max);
728729

729730
address user_A = address(0x123);
730731
address user_B = address(0x456);
@@ -745,13 +746,23 @@ contract TestNttManager is Test, IRateLimiterEvents {
745746

746747
vm.expectRevert("SafeCast: value doesn't fit in 64 bits");
747748
nttManager.transfer(
748-
amount, chainId, toWormholeFormat(user_B), toWormholeFormat(user_A), false, new bytes(1)
749+
amount,
750+
chainId2,
751+
toWormholeFormat(user_B),
752+
toWormholeFormat(user_A),
753+
false,
754+
new bytes(1)
749755
);
750756

751757
// A (slightly) more sensible amount should work normally
752758
amount = (type(uint64).max * 10 ** (decimals - 6 - 2)) - 150000000000; // Subtract this to make sure we don't have dust
753759
nttManager.transfer(
754-
amount, chainId, toWormholeFormat(user_B), toWormholeFormat(user_A), false, new bytes(1)
760+
amount,
761+
chainId2,
762+
toWormholeFormat(user_B),
763+
toWormholeFormat(user_A),
764+
false,
765+
new bytes(1)
755766
);
756767
}
757768

@@ -958,7 +969,7 @@ contract TestNttManager is Test, IRateLimiterEvents {
958969

959970
uint256 maxAmount = 5 * 10 ** decimals;
960971
token.mintDummy(from, maxAmount);
961-
nttManager.setPeer(chainId, toWormholeFormat(address(0x1)), 9, type(uint64).max);
972+
nttManager.setPeer(chainId2, toWormholeFormat(address(0x1)), 9, type(uint64).max);
962973
nttManager.setOutboundLimit(packTrimmedAmount(type(uint64).max, 8).untrim(decimals));
963974
nttManager.setInboundLimit(
964975
packTrimmedAmount(type(uint64).max, 8).untrim(decimals),
@@ -983,7 +994,7 @@ contract TestNttManager is Test, IRateLimiterEvents {
983994
);
984995
nttManager.transfer(
985996
amountWithDust,
986-
chainId,
997+
chainId2,
987998
toWormholeFormat(to),
988999
toWormholeFormat(from),
9891000
false,
@@ -1203,7 +1214,7 @@ contract TestNttManager is Test, IRateLimiterEvents {
12031214

12041215
uint8 decimals = token.decimals();
12051216

1206-
nttManager.setPeer(chainId, toWormholeFormat(address(0x1)), 9, type(uint64).max);
1217+
nttManager.setPeer(chainId2, toWormholeFormat(address(0x1)), 9, type(uint64).max);
12071218
nttManager.setOutboundLimit(packTrimmedAmount(type(uint64).max, 8).untrim(decimals));
12081219

12091220
token.mintDummy(address(user_A), 5 * 10 ** decimals);
@@ -1217,7 +1228,7 @@ contract TestNttManager is Test, IRateLimiterEvents {
12171228
);
12181229
nttManager.transfer(
12191230
1 * 10 ** decimals,
1220-
chainId,
1231+
chainId2,
12211232
toWormholeFormat(user_B),
12221233
toWormholeFormat(user_A),
12231234
false,

evm/test/RateLimit.t.sol

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
2323
using BytesParsing for bytes;
2424

2525
uint16 constant chainId = 7;
26+
uint16 constant chainId2 = 8;
2627

2728
uint256 constant DEVNET_GUARDIAN_PK =
2829
0xcfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0;
@@ -45,7 +46,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
4546
nttManager = MockNttManagerContract(address(new ERC1967Proxy(address(implementation), "")));
4647
nttManager.initialize();
4748

48-
nttManager.setPeer(chainId, toWormholeFormat(address(0x1)), 9, type(uint64).max);
49+
nttManager.setPeer(chainId2, toWormholeFormat(address(0x1)), 9, type(uint64).max);
4950

5051
DummyTransceiver e = new DummyTransceiver(address(nttManager));
5152
nttManager.setTransceiver(address(e));
@@ -88,7 +89,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
8889
token.approve(address(nttManager), transferAmount);
8990
nttManager.transfer(
9091
transferAmount,
91-
chainId,
92+
chainId2,
9293
toWormholeFormat(user_B),
9394
toWormholeFormat(user_A),
9495
false,
@@ -109,7 +110,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
109110
// assert inbound rate limit for destination chain is still at the max.
110111
// the backflow should not override the limit.
111112
IRateLimiter.RateLimitParams memory inboundLimitParams =
112-
nttManager.getInboundLimitParams(chainId);
113+
nttManager.getInboundLimitParams(chainId2);
113114
assertEq(
114115
inboundLimitParams.currentCapacity.getAmount(), inboundLimitParams.limit.getAmount()
115116
);
@@ -135,7 +136,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
135136
token.approve(address(nttManager), transferAmount);
136137
nttManager.transfer(
137138
transferAmount,
138-
chainId,
139+
chainId2,
139140
toWormholeFormat(user_B),
140141
toWormholeFormat(user_A),
141142
false,
@@ -182,7 +183,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
182183
token.approve(address(nttManager), transferAmount);
183184
nttManager.transfer(
184185
transferAmount,
185-
chainId,
186+
chainId2,
186187
toWormholeFormat(user_B),
187188
toWormholeFormat(user_A),
188189
false,
@@ -224,7 +225,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
224225
token.approve(address(nttManager), transferAmount);
225226
nttManager.transfer(
226227
transferAmount,
227-
chainId,
228+
chainId2,
228229
toWormholeFormat(user_B),
229230
toWormholeFormat(user_A),
230231
false,
@@ -280,7 +281,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
280281
token.approve(address(nttManager), transferAmount);
281282
nttManager.transfer(
282283
transferAmount,
283-
chainId,
284+
chainId2,
284285
toWormholeFormat(user_B),
285286
toWormholeFormat(user_A),
286287
false,
@@ -330,7 +331,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
330331
token.approve(address(nttManager), transferAmount);
331332
nttManager.transfer(
332333
transferAmount,
333-
chainId,
334+
chainId2,
334335
toWormholeFormat(user_B),
335336
toWormholeFormat(user_A),
336337
false,
@@ -391,7 +392,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
391392
);
392393
nttManager.transfer(
393394
transferAmount,
394-
chainId,
395+
chainId2,
395396
toWormholeFormat(user_B),
396397
toWormholeFormat(user_A),
397398
false,
@@ -417,7 +418,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
417418
token.approve(address(nttManager), transferAmount);
418419
nttManager.transfer(
419420
transferAmount,
420-
chainId,
421+
chainId2,
421422
toWormholeFormat(user_B),
422423
toWormholeFormat(user_A),
423424
false,
@@ -445,7 +446,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
445446
);
446447
nttManager.transfer(
447448
badTransferAmount,
448-
chainId,
449+
chainId2,
449450
toWormholeFormat(user_B),
450451
toWormholeFormat(user_A),
451452
false,
@@ -478,7 +479,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
478479
// transfer with shouldQueue == true
479480
uint64 qSeq = nttManager.transfer(
480481
transferAmount,
481-
chainId,
482+
chainId2,
482483
toWormholeFormat(user_B),
483484
toWormholeFormat(user_A),
484485
true,
@@ -489,7 +490,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
489490
assertEq(qSeq, 0);
490491
IRateLimiter.OutboundQueuedTransfer memory qt = nttManager.getOutboundQueuedTransfer(0);
491492
assertEq(qt.amount.getAmount(), transferAmount.trim(decimals, decimals).getAmount());
492-
assertEq(qt.recipientChain, chainId);
493+
assertEq(qt.recipientChain, chainId2);
493494
assertEq(qt.recipient, toWormholeFormat(user_B));
494495
assertEq(qt.txTimestamp, initialBlockTimestamp);
495496

@@ -686,7 +687,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
686687
// transfer 10 tokens from user_A -> user_B via the nttManager
687688
nttManager.transfer(
688689
transferAmount.untrim(decimals),
689-
chainId,
690+
chainId2,
690691
toWormholeFormat(user_B),
691692
toWormholeFormat(user_A),
692693
false,
@@ -875,7 +876,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
875876
vm.expectRevert(abi.encodeWithSelector(INttManager.ZeroAmount.selector));
876877
nttManager.transfer(
877878
transferAmount.untrim(decimals),
878-
chainId,
879+
chainId2,
879880
toWormholeFormat(user_B),
880881
toWormholeFormat(user_A),
881882
false,
@@ -888,7 +889,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
888889
// transfer tokens from user_A -> user_B via the nttManager
889890
nttManager.transfer(
890891
transferAmount.untrim(decimals),
891-
chainId,
892+
chainId2,
892893
toWormholeFormat(user_B),
893894
toWormholeFormat(user_A),
894895
false,
@@ -1018,7 +1019,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
10181019
// shouldQueue == true
10191020
uint64 qSeq = nttManager.transfer(
10201021
transferAmount,
1021-
chainId,
1022+
chainId2,
10221023
toWormholeFormat(user_B),
10231024
toWormholeFormat(user_A),
10241025
true,
@@ -1029,7 +1030,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
10291030
assertEq(qSeq, 0);
10301031
IRateLimiter.OutboundQueuedTransfer memory qt = nttManager.getOutboundQueuedTransfer(0);
10311032
assertEq(qt.amount.getAmount(), transferAmount.trim(decimals, decimals).getAmount());
1032-
assertEq(qt.recipientChain, chainId);
1033+
assertEq(qt.recipientChain, chainId2);
10331034
assertEq(qt.recipient, toWormholeFormat(user_B));
10341035
assertEq(qt.txTimestamp, initialBlockTimestamp);
10351036

0 commit comments

Comments
 (0)