Skip to content

Commit 58a10d9

Browse files
zimphaThegaramicemelon
authored
feat(contracts): address alias check in L2 (#438)
Co-authored-by: Péter Garamvölgyi <[email protected]> Co-authored-by: Haichen Shen <[email protected]>
1 parent 8bf6592 commit 58a10d9

9 files changed

+79
-13
lines changed

contracts/src/L2/L2ScrollMessenger.sol

+4-8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {IL1GasPriceOracle} from "./predeploys/IL1GasPriceOracle.sol";
1111

1212
import {PatriciaMerkleTrieVerifier} from "../libraries/verifier/PatriciaMerkleTrieVerifier.sol";
1313
import {ScrollConstants} from "../libraries/constants/ScrollConstants.sol";
14+
import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol";
1415
import {IScrollMessenger} from "../libraries/IScrollMessenger.sol";
1516
import {ScrollMessengerBase} from "../libraries/ScrollMessengerBase.sol";
1617

@@ -208,14 +209,9 @@ contract L2ScrollMessenger is ScrollMessengerBase, PausableUpgradeable, IL2Scrol
208209
uint256 _value,
209210
uint256 _nonce,
210211
bytes memory _message
211-
) external override whenNotPaused onlyWhitelistedSender(msg.sender) {
212-
// anti reentrance
213-
require(
214-
xDomainMessageSender == ScrollConstants.DEFAULT_XDOMAIN_MESSAGE_SENDER,
215-
"Message is already in execution"
216-
);
217-
218-
// @todo address unalis to check sender is L1ScrollMessenger
212+
) external override whenNotPaused {
213+
// It is impossible to deploy a contract with the same address, reentrance is prevented in nature.
214+
require(AddressAliasHelper.undoL1ToL2Alias(msg.sender) == counterpart, "Caller is not L1ScrollMessenger");
219215

220216
bytes32 _xDomainCalldataHash = keccak256(_encodeXDomainCalldata(_from, _to, _value, _nonce, _message));
221217

contracts/src/test/L1CustomERC20Gateway.t.sol

+8-1
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,14 @@ contract L1CustomERC20GatewayTest is L1GatewayTestBase {
290290
// emit FinalizeWithdrawERC20 from L1StandardERC20Gateway
291291
{
292292
hevm.expectEmit(true, true, true, true);
293-
emit FinalizeWithdrawERC20(address(l1Token), address(l2Token), sender, address(recipient), amount, dataToCall);
293+
emit FinalizeWithdrawERC20(
294+
address(l1Token),
295+
address(l2Token),
296+
sender,
297+
address(recipient),
298+
amount,
299+
dataToCall
300+
);
294301
}
295302

296303
// emit RelayedMessage from L1ScrollMessenger

contracts/src/test/L1StandardERC20Gateway.t.sol

+8-1
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,14 @@ contract L1StandardERC20GatewayTest is L1GatewayTestBase {
364364
// emit FinalizeWithdrawERC20 from L1StandardERC20Gateway
365365
{
366366
hevm.expectEmit(true, true, true, true);
367-
emit FinalizeWithdrawERC20(address(l1Token), address(l2Token), sender, address(recipient), amount, dataToCall);
367+
emit FinalizeWithdrawERC20(
368+
address(l1Token),
369+
address(l2Token),
370+
sender,
371+
address(recipient),
372+
amount,
373+
dataToCall
374+
);
368375
}
369376

370377
// emit RelayedMessage from L1ScrollMessenger

contracts/src/test/L1WETHGateway.t.sol

+8-1
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,14 @@ contract L1WETHGatewayTest is L1GatewayTestBase {
316316
// emit FinalizeWithdrawERC20 from L1WETHGateway
317317
{
318318
hevm.expectEmit(true, true, true, true);
319-
emit FinalizeWithdrawERC20(address(l1weth), address(l2weth), sender, address(recipient), amount, dataToCall);
319+
emit FinalizeWithdrawERC20(
320+
address(l1weth),
321+
address(l2weth),
322+
sender,
323+
address(recipient),
324+
amount,
325+
dataToCall
326+
);
320327
}
321328

322329
// emit RelayedMessage from L1ScrollMessenger

contracts/src/test/L2CustomERC20Gateway.t.sol

+14-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import {IL1ERC20Gateway, L1CustomERC20Gateway} from "../L1/gateways/L1CustomERC2
88
import {IL2ERC20Gateway, L2CustomERC20Gateway} from "../L2/gateways/L2CustomERC20Gateway.sol";
99
import {L2GatewayRouter} from "../L2/gateways/L2GatewayRouter.sol";
1010

11+
import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol";
12+
1113
import {L2GatewayTestBase} from "./L2GatewayTestBase.t.sol";
1214
import {MockScrollMessenger} from "./mocks/MockScrollMessenger.sol";
1315
import {MockGatewayRecipient} from "./mocks/MockGatewayRecipient.sol";
@@ -224,7 +226,9 @@ contract L2CustomERC20GatewayTest is L2GatewayTestBase {
224226
uint256 gatewayBalance = l2Token.balanceOf(address(gateway));
225227
uint256 recipientBalance = l2Token.balanceOf(recipient);
226228
assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata)));
229+
hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)));
227230
l2Messenger.relayMessage(address(uint160(address(counterpartGateway)) + 1), address(gateway), 0, 0, message);
231+
hevm.stopPrank();
228232
assertEq(gatewayBalance, l2Token.balanceOf(address(gateway)));
229233
assertEq(recipientBalance, l2Token.balanceOf(recipient));
230234
assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata)));
@@ -263,7 +267,14 @@ contract L2CustomERC20GatewayTest is L2GatewayTestBase {
263267
// emit FinalizeDepositERC20 from L2CustomERC20Gateway
264268
{
265269
hevm.expectEmit(true, true, true, true);
266-
emit FinalizeDepositERC20(address(l1Token), address(l2Token), sender, address(recipient), amount, dataToCall);
270+
emit FinalizeDepositERC20(
271+
address(l1Token),
272+
address(l2Token),
273+
sender,
274+
address(recipient),
275+
amount,
276+
dataToCall
277+
);
267278
}
268279

269280
// emit RelayedMessage from L2ScrollMessenger
@@ -275,7 +286,9 @@ contract L2CustomERC20GatewayTest is L2GatewayTestBase {
275286
uint256 gatewayBalance = l2Token.balanceOf(address(gateway));
276287
uint256 recipientBalance = l2Token.balanceOf(address(recipient));
277288
assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata)));
289+
hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)));
278290
l2Messenger.relayMessage(address(counterpartGateway), address(gateway), 0, 0, message);
291+
hevm.stopPrank();
279292
assertEq(gatewayBalance, l2Token.balanceOf(address(gateway)));
280293
assertEq(recipientBalance + amount, l2Token.balanceOf(address(recipient)));
281294
assertBoolEq(true, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata)));

contracts/src/test/L2ETHGateway.t.sol

+6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import {L2GatewayRouter} from "../L2/gateways/L2GatewayRouter.sol";
66
import {IL1ETHGateway, L1ETHGateway} from "../L1/gateways/L1ETHGateway.sol";
77
import {IL2ETHGateway, L2ETHGateway} from "../L2/gateways/L2ETHGateway.sol";
88

9+
import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol";
10+
911
import {L2GatewayTestBase} from "./L2GatewayTestBase.t.sol";
1012
import {MockScrollMessenger} from "./mocks/MockScrollMessenger.sol";
1113
import {MockGatewayRecipient} from "./mocks/MockGatewayRecipient.sol";
@@ -167,13 +169,15 @@ contract L2ETHGatewayTest is L2GatewayTestBase {
167169
uint256 messengerBalance = address(l2Messenger).balance;
168170
uint256 recipientBalance = recipient.balance;
169171
assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata)));
172+
hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)));
170173
l2Messenger.relayMessage(
171174
address(uint160(address(counterpartGateway)) + 1),
172175
address(gateway),
173176
amount,
174177
0,
175178
message
176179
);
180+
hevm.stopPrank();
177181
assertEq(messengerBalance, address(l2Messenger).balance);
178182
assertEq(recipientBalance, recipient.balance);
179183
assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata)));
@@ -224,7 +228,9 @@ contract L2ETHGatewayTest is L2GatewayTestBase {
224228
uint256 messengerBalance = address(l2Messenger).balance;
225229
uint256 recipientBalance = address(recipient).balance;
226230
assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata)));
231+
hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)));
227232
l2Messenger.relayMessage(address(counterpartGateway), address(gateway), amount, 0, message);
233+
hevm.stopPrank();
228234
assertEq(messengerBalance - amount, address(l2Messenger).balance);
229235
assertEq(recipientBalance + amount, address(recipient).balance);
230236
assertBoolEq(true, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata)));

contracts/src/test/L2ScrollMessenger.t.sol

+9
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import {Whitelist} from "../L2/predeploys/Whitelist.sol";
1111
import {L1ScrollMessenger} from "../L1/L1ScrollMessenger.sol";
1212
import {L2ScrollMessenger} from "../L2/L2ScrollMessenger.sol";
1313

14+
import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol";
15+
1416
contract L2ScrollMessengerTest is DSTestPlus {
1517
L1ScrollMessenger internal l1Messenger;
1618

@@ -40,12 +42,19 @@ contract L2ScrollMessengerTest is DSTestPlus {
4042
l1GasOracle.updateWhitelist(address(whitelist));
4143
}
4244

45+
function testRelayByCounterparty() external {
46+
hevm.expectRevert("Caller is not L1ScrollMessenger");
47+
l2Messenger.relayMessage(address(this), address(this), 0, 0, new bytes(0));
48+
}
49+
4350
function testForbidCallFromL1() external {
51+
hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)));
4452
hevm.expectRevert("Forbid to call message queue");
4553
l2Messenger.relayMessage(address(this), address(l2MessageQueue), 0, 0, new bytes(0));
4654

4755
hevm.expectRevert("Forbid to call self");
4856
l2Messenger.relayMessage(address(this), address(l2Messenger), 0, 0, new bytes(0));
57+
hevm.stopPrank();
4958
}
5059

5160
function testSendMessage(uint256 exceedValue, address refundAddress) external {

contracts/src/test/L2StandardERC20Gateway.t.sol

+16-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import {IL2ERC20Gateway, L2StandardERC20Gateway} from "../L2/gateways/L2Standard
1010
import {ScrollStandardERC20} from "../libraries/token/ScrollStandardERC20.sol";
1111
import {ScrollStandardERC20Factory} from "../libraries/token/ScrollStandardERC20Factory.sol";
1212

13+
import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol";
14+
1315
import {L2GatewayTestBase} from "./L2GatewayTestBase.t.sol";
1416
import {MockScrollMessenger} from "./mocks/MockScrollMessenger.sol";
1517
import {MockGatewayRecipient} from "./mocks/MockGatewayRecipient.sol";
@@ -68,6 +70,7 @@ contract L2StandardERC20GatewayTest is L2GatewayTestBase {
6870

6971
// Prepare token balances
7072
l2Token = MockERC20(gateway.getL2ERC20Address(address(l1Token)));
73+
hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)));
7174
l2Messenger.relayMessage(
7275
address(counterpartGateway),
7376
address(gateway),
@@ -83,6 +86,7 @@ contract L2StandardERC20GatewayTest is L2GatewayTestBase {
8386
abi.encode("", abi.encode("symbol", "name", 18))
8487
)
8588
);
89+
hevm.stopPrank();
8690
}
8791

8892
function testInitialized() public {
@@ -256,7 +260,9 @@ contract L2StandardERC20GatewayTest is L2GatewayTestBase {
256260
uint256 gatewayBalance = l2Token.balanceOf(address(gateway));
257261
uint256 recipientBalance = l2Token.balanceOf(recipient);
258262
assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata)));
263+
hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)));
259264
l2Messenger.relayMessage(address(uint160(address(counterpartGateway)) + 1), address(gateway), 0, 0, message);
265+
hevm.stopPrank();
260266
assertEq(gatewayBalance, l2Token.balanceOf(address(gateway)));
261267
assertEq(recipientBalance, l2Token.balanceOf(recipient));
262268
assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata)));
@@ -293,7 +299,14 @@ contract L2StandardERC20GatewayTest is L2GatewayTestBase {
293299
// emit FinalizeDepositERC20 from L2StandardERC20Gateway
294300
{
295301
hevm.expectEmit(true, true, true, true);
296-
emit FinalizeDepositERC20(address(l1Token), address(l2Token), sender, address(recipient), amount, dataToCall);
302+
emit FinalizeDepositERC20(
303+
address(l1Token),
304+
address(l2Token),
305+
sender,
306+
address(recipient),
307+
amount,
308+
dataToCall
309+
);
297310
}
298311

299312
// emit RelayedMessage from L2ScrollMessenger
@@ -305,7 +318,9 @@ contract L2StandardERC20GatewayTest is L2GatewayTestBase {
305318
uint256 gatewayBalance = l2Token.balanceOf(address(gateway));
306319
uint256 recipientBalance = l2Token.balanceOf(address(recipient));
307320
assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata)));
321+
hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)));
308322
l2Messenger.relayMessage(address(counterpartGateway), address(gateway), 0, 0, message);
323+
hevm.stopPrank();
309324
assertEq(gatewayBalance, l2Token.balanceOf(address(gateway)));
310325
assertEq(recipientBalance + amount, l2Token.balanceOf(address(recipient)));
311326
assertBoolEq(true, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata)));

contracts/src/test/L2WETHGateway.t.sol

+6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import {IL1ERC20Gateway, L1WETHGateway} from "../L1/gateways/L1WETHGateway.sol";
88
import {L2GatewayRouter} from "../L2/gateways/L2GatewayRouter.sol";
99
import {IL2ERC20Gateway, L2WETHGateway} from "../L2/gateways/L2WETHGateway.sol";
1010

11+
import {AddressAliasHelper} from "../libraries/common/AddressAliasHelper.sol";
12+
1113
import {L2GatewayTestBase} from "./L2GatewayTestBase.t.sol";
1214
import {MockScrollMessenger} from "./mocks/MockScrollMessenger.sol";
1315
import {MockGatewayRecipient} from "./mocks/MockGatewayRecipient.sol";
@@ -258,13 +260,15 @@ contract L2WETHGatewayTest is L2GatewayTestBase {
258260
uint256 messengerBalance = address(l2Messenger).balance;
259261
uint256 recipientBalance = l2weth.balanceOf(recipient);
260262
assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata)));
263+
hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)));
261264
l2Messenger.relayMessage(
262265
address(uint160(address(counterpartGateway)) + 1),
263266
address(gateway),
264267
amount,
265268
0,
266269
message
267270
);
271+
hevm.stopPrank();
268272
assertEq(messengerBalance, address(l2Messenger).balance);
269273
assertEq(recipientBalance, l2weth.balanceOf(recipient));
270274
assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata)));
@@ -317,7 +321,9 @@ contract L2WETHGatewayTest is L2GatewayTestBase {
317321
uint256 messengerBalance = address(l2Messenger).balance;
318322
uint256 recipientBalance = l2weth.balanceOf(address(recipient));
319323
assertBoolEq(false, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata)));
324+
hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)));
320325
l2Messenger.relayMessage(address(counterpartGateway), address(gateway), amount, 0, message);
326+
hevm.stopPrank();
321327
assertEq(messengerBalance - amount, address(l2Messenger).balance);
322328
assertEq(recipientBalance + amount, l2weth.balanceOf(address(recipient)));
323329
assertBoolEq(true, l2Messenger.isL1MessageExecuted(keccak256(xDomainCalldata)));

0 commit comments

Comments
 (0)