Skip to content

Conversation

Raid5594
Copy link
Collaborator

What ❔

Why ❔

Checklist

  • PR title corresponds to the body of PR (we generate changelog entries from PRs).
  • Tests for the changes have been added / updated.
  • Documentation comments have been added / updated.

Copy link
Collaborator

@0xValera 0xValera left a comment

Choose a reason for hiding this comment

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

The part of the fix that's done looks good.
Please add test with Mailbox not being mocked, look here.
Please ensure the CI is at least as good as base branch.


vm.deal(randomCaller, 1 ether);
vm.prank(randomCaller);
vm.expectRevert(abi.encodeWithSelector(MsgValueMismatch.selector, 0, randomCaller.balance));
Copy link
Collaborator

Choose a reason for hiding this comment

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

do we need this first part? It checks that the call would fail with the wrong amount of tokens, which probably should've been covered by other tests

@Raid5594
Copy link
Collaborator Author

Raid5594 commented Sep 23, 2025

The part of the fix that's done looks good. Please add test with Mailbox not being mocked, look here. Please ensure the CI is at least as good as base branch.

@0xValera these are not complete tests fyi, but we have a different location where it can be tested

@Raid5594 Raid5594 marked this pull request as ready for review September 23, 2025 15:57
@Raid5594 Raid5594 requested a review from Deniallugo as a code owner October 1, 2025 10:02
@Raid5594 Raid5594 changed the title feat: add the fix, tests in progress feat: 7702 bug fix Oct 1, 2025

request.refundRecipient = AddressAliasHelper.actualRefundRecipient(request.refundRecipient, request.sender);
bool is7702AccountRefundRecipient = EIP_7702_CHECKER.isEIP7702Account(request.refundRecipient);
bool is7702AccountSender = EIP_7702_CHECKER.isEIP7702Account(request.sender); // This is not the same as refundRecipient, as it appears to be the AR during TwoBridges.
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is not the same as refundRecipient, as it appears to be the AR during TwoBridges.

do we need this then?

Copy link
Collaborator Author

@Raid5594 Raid5594 Oct 2, 2025

Choose a reason for hiding this comment

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

In case it's a direct tx EOA will be the sender and for 7702 we don't want it to be aliased

// If the `_refundRecipient` is not provided, we use the `_originalCaller` as the recipient.
// solhint-disable avoid-tx-origin
// slither-disable-next-line tx-origin
_recipient = (_originalCaller == tx.origin || _is7702Account)
Copy link
Collaborator

Choose a reason for hiding this comment

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

why do we have _is7702Account here? Isn't it related to _refundRecipient, and not _originalCaller?

Copy link
Collaborator Author

@Raid5594 Raid5594 Oct 2, 2025

Choose a reason for hiding this comment

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

maybe it has to be removed

"build": "hardhat compile && CONTRACTS_BASE_NETWORK_ZKSYNC=true hardhat compile ",
"build-l1": "hardhat compile",
"build:foundry": "forge build && forge build --zksync --skip '*/l1-contracts/test/*'",
"build:foundry": "forge build && forge build --zksync --skip '*/l1-contracts/test/*' --skip 'deploy-scripts/*'",
Copy link
Collaborator

Choose a reason for hiding this comment

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

todo rollback?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Comment on lines +265 to +266
// TODO: remove comment to check that refund recipient is correct after foundry version is bumped to post-prague
// assertEq(address(uint160(request.transaction.reserved[1])), randomCaller, "Refund recipient mismatch");
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please read this thread.
I think you can bump the foundry? Or were there other issues with that as well, apart from just choosing a foundry version?

DeployedContracts memory contracts;

contracts.multicall3 = address(new Multicall3{salt: salt}());
contracts.eip7702Checker = address(new MockEIP7702Checker{salt: salt}());
Copy link
Collaborator

Choose a reason for hiding this comment

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

Here we deploy MockEIP7702Checker. Should we use EIP7702Checker?

@zkzoomer zkzoomer mentioned this pull request Oct 10, 2025
3 tasks
Copy link

Coverage after merging ra/7702-bug-fix into draft-v30 will be

79.67%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
contracts/bridge
   BridgeHelper.sol85.71%100%100%85%31, 36, 41
   BridgedStandardERC20.sol82.14%100%92.31%80.28%120–121, 126–127, 139–140, 164, 205, 212, 219, 229–230, 63, 91
   L1ERC20Bridge.sol94%100%100%92.86%189, 208, 270
   L1Nullifier.sol83.18%100%86.21%82.70%114, 128–130, 160, 221, 224, 234, 237, 247, 250, 418–420, 424–425, 452, 518, 602, 614, 652, 654, 698, 710, 713, 715, 728, 741–742, 746–747, 767
contracts/bridge/asset-router
   AssetRouterBase.sol82.93%100%66.67%87.50%152, 47, 61, 73
   L1AssetRouter.sol87.77%100%86.21%88.05%106, 232, 270, 286, 373, 384, 415, 454–455, 469, 500, 572, 661, 672, 686, 691, 74, 90, 98
contracts/bridge/interfaces
   AssetHandlerModifiers.sol75%100%100%66.67%13
contracts/bridge/ntv
   L1NativeTokenVault.sol86.72%100%90.48%85.98%173–179, 181, 249–250, 252, 263, 265, 269, 95
   NativeTokenVaultBase.sol76.73%100%57.89%81.10%105, 185, 237, 242, 259, 277, 282, 286, 298, 317, 325, 433, 44, 440, 47, 491, 50, 506, 517, 53, 534, 557, 567–568, 572–573, 59, 61, 63, 65, 89
   UpgradeableBeaconDeployer.sol0%100%0%0%15–16, 18, 20–21
contracts/bridgehub
   BridgehubBase.sol77.42%100%75.61%77.84%137, 145, 150–152, 159, 177, 207, 217–218, 227, 242, 281, 284, 303, 319, 350, 390–391, 47, 486, 49, 490, 494–495, 51, 514, 517, 573, 577, 580, 615–616, 620–621, 629–630, 634–635
   CTMDeploymentTracker.sol73.47%100%81.82%71.05%106, 110, 114, 139, 143–144, 32, 40, 65, 78–79
   ChainAssetHandlerBase.sol55%100%33.33%61.29%124, 141, 144, 156–157, 202, 252–253, 257–258, 42, 45, 48, 51, 54, 60, 62, 64, 66, 68, 76, 83–84, 92
   L1Bridgehub.sol87.70%100%92.86%87.04%100–101, 110, 120, 135, 252, 325, 329–330, 333, 65–66, 86, 96
   L1ChainAssetHandler.sol77.78%100%71.43%80%35–36, 44–45
   L1MessageRoot.sol78.57%100%75%80%36–37
   L2Bridgehub.sol80.56%100%75%82.14%108, 65, 81–82, 93
   L2ChainAssetHandler.sol80.65%100%75%82.61%47–48, 70, 94
   L2MessageRoot.sol34.38%100%50%30.77%39–40, 43–44, 50, 68, 74–75, 79, 81, 83, 86–87, 89, 93–96
   L2MessageVerification.sol100%100%100%100%
   MessageRootBase.sol52.46%100%53.85%52.08%100–102, 108–110, 119, 125, 137, 147, 152–157, 159–163, 35, 37
contracts/common
   ReentrancyGuard.sol95%100%100%94.12%79
contracts/common/l2-helpers
   L2ContractHelper.sol84.91%100%100%82.22%102, 108, 112, 129, 134, 73, 79, 83
   SystemContractsCaller.sol0%100%0%0%102, 114, 122–125, 128, 135–139, 141–142, 32–34, 37, 44–45, 47, 49, 51, 53, 66, 69, 72, 75, 78, 83, 89, 91, 93, 96, 98
contracts/common/libraries
   DataEncoding.sol81.63%100%81.82%81.58%109–110, 117–118, 163, 177, 45
   DynamicIncrementalMerkle.sol73.91%100%80%73.17%66–70, 72–74, 76–78
   FullMerkle.sol100%100%100%100%
   Merkle.sol98.15%100%100%97.96%83
   MessageHashing.sol95.16%100%100%94.64%113, 77, 94
   SemVer.sol100%100%100%100%
   UncheckedMath.sol100%100%100%100%
   UnsafeBytes.sol100%100%100%100%
contracts/governance
   AccessControlRestriction.sol100%100%100%100%
   ChainAdmin.sol97.87%100%100%97.30%39
   ChainAdminOwnable.sol44.83%100%40%45.83%28, 38–40, 46–48, 57, 66, 77–79, 81
   Governance.sol100%100%100%100%
   L2ProxyAdminDeployer.sol0%100%0%0%16–18, 20
   PermanentRestriction.sol88.80%100%100%87.39%104, 111–112, 200–201, 204–205, 208, 210–211, 240, 288, 310, 341
   ServerNotifier.sol93.10%100%100%90.91%55, 65
   TransitionaryOwner.sol0%100%0%0%16–17, 21–23
contracts/governance/restriction
   Restriction.sol60%100%50%66.67%21
   RestrictionValidator.sol100%100%100%100%
contracts/l2-upgrades
   L2ComplexUpgrader.sol0%100%0%0%23, 25–26, 40, 45, 47, 57, 63–64, 71, 80–82, 85, 87–88
   L2GenesisForceDeploymentsHelper.sol0%100%0%0%100, 107–108, 111–113, 119, 127, 131, 136, 138, 148, 157, 160, 165, 175, 177–178, 181, 184, 190, 194, 198, 209, 218, 223, 225, 233, 244, 258, 264, 284, 292–293, 296–297, 299, 306, 312, 33–36, 44, 47–48,

/// @title EIP7702Checker
/// @notice Utility to detect EIP-7702 style EOAs (accounts with code stubs)
/// @dev See: https://eips.ethereum.org/EIPS/eip-7702

Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: unneeded newline

/**
* @notice Returns true if the given account has exactly the EIP-7702 code stub.
* @param account The address to check.
* @return isStub True if the account matches the EIP-7702 code pattern.
Copy link
Collaborator

Choose a reason for hiding this comment

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

why is it called stub?

/// @title EIP7702Checker
/// @notice Utility to detect EIP-7702 style EOAs (accounts with code stubs)
/// @dev See: https://eips.ethereum.org/EIPS/eip-7702

Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: empty newline

/// @notice Address of the Multicall3 contract.
address multicall3;
/// @notice Address of the EIP7702Checker contract.
address eip7702Checker;
Copy link
Collaborator

Choose a reason for hiding this comment

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

maybe makes sense to remove it fully from this file?

// If the `_refundRecipient` is not provided, we use the `_originalCaller` as the recipient.
// solhint-disable avoid-tx-origin
// slither-disable-next-line tx-origin
_recipient = (_originalCaller == tx.origin)
Copy link
Collaborator

@StanislavBreadless StanislavBreadless Oct 13, 2025

Choose a reason for hiding this comment

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

what if the original caller is an eip712 account? then it is possible that _originalCaller != tx.origin, but we still should not apply aliasing


function getCreationCodeEVM(string memory contractIdentifier) internal view returns (bytes memory) {
string[3] memory DA_CONTRACT_IDENTIFIERS = ["RollupL1DAValidator", "AvailL1DAValidator", "DummyAvailBridge"];
string[4] memory DA_CONTRACT_IDENTIFIERS = [
Copy link
Collaborator

Choose a reason for hiding this comment

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

maybe makes sense to update the variable name? I understand that we may not want to update the folder name in this PR, but still wherever possible, let's keep the variable names aligned with code...

return abi.encode(config.l1ChainId, addresses.daAddresses.rollupDAManager);
} else if (compareStrings(contractName, "MailboxFacet")) {
return abi.encode(config.eraChainId, config.l1ChainId);
return abi.encode(config.eraChainId, config.l1ChainId, addresses.daAddresses.eip7702Checker);
Copy link
Collaborator

Choose a reason for hiding this comment

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

even though the checker is inside da-contracts folder, the only reason it is there is because it is a dedicated folder for l1-only contracts, let's not call it a da contract inside the script

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.

4 participants