From 43ba1b46f10d2bec50fab7341b63339134a19122 Mon Sep 17 00:00:00 2001 From: Kunal Arora <55632507+aroralanuk@users.noreply.github.com> Date: Thu, 14 Sep 2023 00:10:43 -0400 Subject: [PATCH] Running forge with latest solc (#2729) ### Description - Removed contracts-bedrock contracts dependency from eth-optimism (which was forcing us to use 0.8.15) - Added local minimal interfaces for the CrossDomainMessenger contract ### Drive-by changes None ### Related issues None ### Backward compatibility Yes ### Testing Unit tests --------- Signed-off-by: -f Co-authored-by: Yorke Rhodes --- .../optimism/ICrossDomainMessenger.sol | 19 +++ solidity/contracts/isms/hook/OPStackIsm.sol | 2 - .../optimism/LibOptimism.sol | 2 +- solidity/foundry.toml | 4 +- solidity/hardhat.config.ts | 2 +- solidity/test/isms/OPStackIsm.t.sol | 152 +++++++++++++----- typescript/token/lib/forge-std | 2 +- typescript/token/src/deploy.ts | 5 +- 8 files changed, 139 insertions(+), 49 deletions(-) diff --git a/solidity/contracts/interfaces/optimism/ICrossDomainMessenger.sol b/solidity/contracts/interfaces/optimism/ICrossDomainMessenger.sol index 19bcbf55e..d1e111fcd 100644 --- a/solidity/contracts/interfaces/optimism/ICrossDomainMessenger.sol +++ b/solidity/contracts/interfaces/optimism/ICrossDomainMessenger.sol @@ -17,4 +17,23 @@ interface ICrossDomainMessenger { bytes calldata _message, uint32 _gasLimit ) external payable; + + function relayMessage( + uint256 _nonce, + address _sender, + address _target, + uint256 _value, + uint256 _minGasLimit, + bytes calldata _message + ) external payable; + + /************* + * Variables * + *************/ + + function xDomainMessageSender() external view returns (address); +} + +interface IL2CrossDomainMessenger is ICrossDomainMessenger { + function messageNonce() external view returns (uint256); } diff --git a/solidity/contracts/isms/hook/OPStackIsm.sol b/solidity/contracts/isms/hook/OPStackIsm.sol index 9cee32fc5..89ecc1549 100644 --- a/solidity/contracts/isms/hook/OPStackIsm.sol +++ b/solidity/contracts/isms/hook/OPStackIsm.sol @@ -22,8 +22,6 @@ import {AbstractMessageIdAuthorizedIsm} from "./AbstractMessageIdAuthorizedIsm.s import {CrossChainEnabledOptimism} from "./crossChainEnabled/optimism/CrossChainEnabledOptimism.sol"; // ============ External Imports ============ - -import {ICrossDomainMessenger} from "@eth-optimism/contracts/libraries/bridge/ICrossDomainMessenger.sol"; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; /** diff --git a/solidity/contracts/isms/hook/crossChainEnabled/optimism/LibOptimism.sol b/solidity/contracts/isms/hook/crossChainEnabled/optimism/LibOptimism.sol index b42a82ad9..9b71e7b8b 100644 --- a/solidity/contracts/isms/hook/crossChainEnabled/optimism/LibOptimism.sol +++ b/solidity/contracts/isms/hook/crossChainEnabled/optimism/LibOptimism.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.4; -import {ICrossDomainMessenger} from "@eth-optimism/contracts/libraries/bridge/ICrossDomainMessenger.sol"; +import {ICrossDomainMessenger} from "../../../../interfaces/optimism/ICrossDomainMessenger.sol"; import {NotCrossChainCall} from "../errors.sol"; /** diff --git a/solidity/foundry.toml b/solidity/foundry.toml index 5eb3cb4dc..111db4f93 100644 --- a/solidity/foundry.toml +++ b/solidity/foundry.toml @@ -3,9 +3,9 @@ src = 'contracts' out = 'out' libs = ['node_modules', 'lib'] test = 'test' -cache_path = 'forge-cache' +cache_path = 'forge-cache' allow_paths = ["../node_modules"] -solc = '0.8.15' +solc = '0.8.19' optimizer = true optimizer_runs = 999_999 diff --git a/solidity/hardhat.config.ts b/solidity/hardhat.config.ts index 518ee335a..5fa922436 100644 --- a/solidity/hardhat.config.ts +++ b/solidity/hardhat.config.ts @@ -11,7 +11,7 @@ module.exports = { solidity: { compilers: [ { - version: '0.8.17', + version: '0.8.19', }, { // for @eth-optimism diff --git a/solidity/test/isms/OPStackIsm.t.sol b/solidity/test/isms/OPStackIsm.t.sol index 79945200b..e7396118e 100644 --- a/solidity/test/isms/OPStackIsm.t.sol +++ b/solidity/test/isms/OPStackIsm.t.sol @@ -15,13 +15,8 @@ import {OPStackHook} from "../../contracts/hooks/OPStackHook.sol"; import {TestRecipient} from "../../contracts/test/TestRecipient.sol"; import {NotCrossChainCall} from "../../contracts/isms/hook/crossChainEnabled/errors.sol"; -import {Lib_CrossDomainUtils} from "@eth-optimism/contracts/libraries/bridge/Lib_CrossDomainUtils.sol"; import {AddressAliasHelper} from "@eth-optimism/contracts/standards/AddressAliasHelper.sol"; -import {ICrossDomainMessenger} from "@eth-optimism/contracts/libraries/bridge/ICrossDomainMessenger.sol"; -import {ICanonicalTransactionChain} from "@eth-optimism/contracts/L1/rollup/ICanonicalTransactionChain.sol"; -import {L2CrossDomainMessenger} from "@eth-optimism/contracts-bedrock/contracts/L2/L2CrossDomainMessenger.sol"; -import {Encoding} from "@eth-optimism/contracts-bedrock/contracts/libraries/Encoding.sol"; -import {Hashing} from "@eth-optimism/contracts-bedrock/contracts/libraries/Hashing.sol"; +import {ICrossDomainMessenger, IL2CrossDomainMessenger} from "../../contracts/interfaces/optimism/ICrossDomainMessenger.sol"; contract OPStackIsmTest is Test { using LibBit for uint256; @@ -44,7 +39,7 @@ contract OPStackIsmTest is Test { address internal alice = address(0x1); ICrossDomainMessenger internal l1Messenger; - L2CrossDomainMessenger internal l2Messenger; + IL2CrossDomainMessenger internal l2Messenger; TestMailbox internal l1Mailbox; OPStackIsm internal opISM; OPStackHook internal opHook; @@ -108,7 +103,7 @@ contract OPStackIsmTest is Test { function deployOPStackIsm() public { vm.selectFork(optimismFork); - l2Messenger = L2CrossDomainMessenger(L2_MESSENGER_ADDRESS); + l2Messenger = IL2CrossDomainMessenger(L2_MESSENGER_ADDRESS); opISM = new OPStackIsm(L2_MESSENGER_ADDRESS); vm.makePersistent(address(opISM)); @@ -154,9 +149,7 @@ contract OPStackIsmTest is Test { (messageId) ); - uint40 nonce = ICanonicalTransactionChain(L1_CANNONICAL_CHAIN) - .getQueueLength(); - + uint40 testNonce = 123; l1Mailbox.updateLatestDispatchedId(messageId); vm.expectEmit(true, true, true, false, L1_MESSENGER_ADDRESS); @@ -164,7 +157,7 @@ contract OPStackIsmTest is Test { address(opISM), address(opHook), encodedHookData, - nonce, + testNonce, DEFAULT_GAS_LIMIT ); opHook.postDispatch(testMetadata, encodedMessage); @@ -232,15 +225,12 @@ contract OPStackIsmTest is Test { (messageId) ); - (uint240 nonce, uint16 verison) = Encoding.decodeVersionedNonce( + (uint240 nonce, uint16 version) = decodeVersionedNonce( l2Messenger.messageNonce() ); - uint256 versionedNonce = Encoding.encodeVersionedNonce( - nonce + 1, - verison - ); + uint256 versionedNonce = encodeVersionedNonce(nonce + 1, version); - bytes32 versionedHash = Hashing.hashCrossDomainMessageV1( + bytes32 versionedHash = hashCrossDomainMessageV1( versionedNonce, address(opHook), address(opISM), @@ -307,13 +297,10 @@ contract OPStackIsmTest is Test { (messageId) ); - (uint240 nonce, uint16 verison) = Encoding.decodeVersionedNonce( + (uint240 nonce, uint16 version) = decodeVersionedNonce( l2Messenger.messageNonce() ); - uint256 versionedNonce = Encoding.encodeVersionedNonce( - nonce + 1, - verison - ); + uint256 versionedNonce = encodeVersionedNonce(nonce + 1, version); vm.prank(AddressAliasHelper.applyL1ToL2Alias(L1_MESSENGER_ADDRESS)); l2Messenger.relayMessage( @@ -341,13 +328,10 @@ contract OPStackIsmTest is Test { (messageId) ); - (uint240 nonce, uint16 verison) = Encoding.decodeVersionedNonce( + (uint240 nonce, uint16 version) = decodeVersionedNonce( l2Messenger.messageNonce() ); - uint256 versionedNonce = Encoding.encodeVersionedNonce( - nonce + 1, - verison - ); + uint256 versionedNonce = encodeVersionedNonce(nonce + 1, version); vm.prank(AddressAliasHelper.applyL1ToL2Alias(L1_MESSENGER_ADDRESS)); l2Messenger.relayMessage{value: _msgValue}( @@ -377,13 +361,10 @@ contract OPStackIsmTest is Test { (messageId) ); - (uint240 nonce, uint16 verison) = Encoding.decodeVersionedNonce( + (uint240 nonce, uint16 version) = decodeVersionedNonce( l2Messenger.messageNonce() ); - uint256 versionedNonce = Encoding.encodeVersionedNonce( - nonce + 1, - verison - ); + uint256 versionedNonce = encodeVersionedNonce(nonce + 1, version); vm.prank(AddressAliasHelper.applyL1ToL2Alias(L1_MESSENGER_ADDRESS)); l2Messenger.relayMessage( @@ -429,13 +410,10 @@ contract OPStackIsmTest is Test { (_messageId) ); - (uint240 nonce, uint16 verison) = Encoding.decodeVersionedNonce( + (uint240 nonce, uint16 version) = decodeVersionedNonce( l2Messenger.messageNonce() ); - uint256 versionedNonce = Encoding.encodeVersionedNonce( - nonce + 1, - verison - ); + uint256 versionedNonce = encodeVersionedNonce(nonce + 1, version); vm.prank(AddressAliasHelper.applyL1ToL2Alias(L1_MESSENGER_ADDRESS)); l2Messenger.relayMessage( @@ -465,4 +443,102 @@ contract OPStackIsmTest is Test { testMessage ); } + + /// @dev from eth-optimism/contracts-bedrock/contracts/libraries/Hashing.sol + /// @notice Hashes a cross domain message based on the V1 (current) encoding. + /// @param _nonce Message nonce. + /// @param _sender Address of the sender of the message. + /// @param _target Address of the target of the message. + /// @param _value ETH value to send to the target. + /// @param _gasLimit Gas limit to use for the message. + /// @param _data Data to send with the message. + /// @return Hashed cross domain message. + function hashCrossDomainMessageV1( + uint256 _nonce, + address _sender, + address _target, + uint256 _value, + uint256 _gasLimit, + bytes memory _data + ) internal pure returns (bytes32) { + return + keccak256( + encodeCrossDomainMessageV1( + _nonce, + _sender, + _target, + _value, + _gasLimit, + _data + ) + ); + } + + /// @dev from eth-optimism/contracts-bedrock/contracts/libraries/Encoding.sol + /// @notice Encodes a cross domain message based on the V1 (current) encoding. + /// @param _nonce Message nonce. + /// @param _sender Address of the sender of the message. + /// @param _target Address of the target of the message. + /// @param _value ETH value to send to the target. + /// @param _gasLimit Gas limit to use for the message. + /// @param _data Data to send with the message. + /// @return Encoded cross domain message. + function encodeCrossDomainMessageV1( + uint256 _nonce, + address _sender, + address _target, + uint256 _value, + uint256 _gasLimit, + bytes memory _data + ) internal pure returns (bytes memory) { + return + abi.encodeWithSignature( + "relayMessage(uint256,address,address,uint256,uint256,bytes)", + _nonce, + _sender, + _target, + _value, + _gasLimit, + _data + ); + } + + /// @dev from eth-optimism/contracts-bedrock/contracts/libraries/Encoding.sol + /// @notice Adds a version number into the first two bytes of a message nonce. + /// @param _nonce Message nonce to encode into. + /// @param _version Version number to encode into the message nonce. + /// @return Message nonce with version encoded into the first two bytes. + function encodeVersionedNonce(uint240 _nonce, uint16 _version) + internal + pure + returns (uint256) + { + uint256 nonce; + assembly { + nonce := or(shl(240, _version), _nonce) + } + return nonce; + } + + /// @dev from eth-optimism/contracts-bedrock/contracts/libraries/Encoding.sol + /// @notice Pulls the version out of a version-encoded nonce. + /// @param _nonce Message nonce with version encoded into the first two bytes. + /// @return Nonce without encoded version. + /// @return Version of the message. + function decodeVersionedNonce(uint256 _nonce) + internal + pure + returns (uint240, uint16) + { + uint240 nonce; + uint16 version; + assembly { + nonce := and( + _nonce, + 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ) + version := shr(240, _nonce) + } + return (nonce, version); + } } diff --git a/typescript/token/lib/forge-std b/typescript/token/lib/forge-std index 74cfb77e3..1d9650e95 160000 --- a/typescript/token/lib/forge-std +++ b/typescript/token/lib/forge-std @@ -1 +1 @@ -Subproject commit 74cfb77e308dd188d2f58864aaf44963ae6b88b1 +Subproject commit 1d9650e951204a0ddce9ff89c32f1997984cef4d diff --git a/typescript/token/src/deploy.ts b/typescript/token/src/deploy.ts index 863ee845f..58202db1b 100644 --- a/typescript/token/src/deploy.ts +++ b/typescript/token/src/deploy.ts @@ -154,10 +154,7 @@ export class HypERC20Deployer extends GasRouterDeployer< [], ); } - await this.multiProvider.handleTx( - chain, - router.initialize(config.mailbox), - ); + await this.multiProvider.handleTx(chain, router.initialize(config.mailbox)); return router; }