Commit 1bfd7e9b authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

contracts-bedrock: cleanup interop predeploys (#10995)

* contracts-bedrock: cleanup interop predeploys

Small refactor to the interop predeploys to reuse existing code.
It was determined safe to use the `SafeCall` library, so we opt
to use that instead of duplicating code. No tests are added since
existing test coverage ensures that these calls happen as expected.
A manual mutation test where the value was not passed through was
performed and failing tests were observed.

The `SafeCall` library was previously pinned to `0.8.15` due to the
"call with min gas" semantics, it may be possible that a new compiler
version could emit code that doesn't act how `0.8.15` acts, but the
whole gas introspection thing is an anti pattern and we have invariant
tests that would catch this if we modified the solc version used
by `OptimismPortal`. We know to never follow this pattern again,
ie `hasMinGas` or `callWithMinGas` should never be used again
in the codebase and should be deleted at some point once we get
rid of the whole min gas limit semantics.

* lint: fix

* semver-lock: update
parent 124b1a9e
......@@ -64,8 +64,8 @@
"sourceCodeHash": "0x3a725791a0f5ed84dc46dcdae26f6170a759b2fe3dc360d704356d088b76cfd6"
},
"src/L2/CrossL2Inbox.sol": {
"initCodeHash": "0x46e15ac5de81ea415061d049730da25acf31040d6d5d70fe3a9bf4cac100c282",
"sourceCodeHash": "0xc3d38bfa73fc33369891a2e8c987baf64b1e94c53d6104676fd4c93e1f5c8011"
"initCodeHash": "0x074af4b17cfdd1d1dafaaccb79d68ab4ceef50d35dc205aeeedc265e11ae2a92",
"sourceCodeHash": "0x5b4355b060e8e5ab81047e5f3d093869c2be7bae14a48a0e5ddf6872a219faf2"
},
"src/L2/GasPriceOracle.sol": {
"initCodeHash": "0xb16f1e370e58c7693fd113a21a1b1e7ccebc03d4f1e5a76786fc27847ef51ead",
......@@ -100,8 +100,8 @@
"sourceCodeHash": "0x8388b9b8075f31d580fed815b66b45394e40fb1a63cd8cda2272d2c390fc908c"
},
"src/L2/L2ToL2CrossDomainMessenger.sol": {
"initCodeHash": "0x975a4b620e71a1cacd5078972c5e042d010b01e52d0ccd17934cbc7c9890f23b",
"sourceCodeHash": "0x249218d69909750f5245a42d247a789f1837c24863bded94dc577fcbec914175"
"initCodeHash": "0x15fbb6175eb98a7d7c6b99862de49e8c3f8ac768c656e82ad7c41c0d1739bd66",
"sourceCodeHash": "0x1f14aafab2cb15970cccedb461b72218fca8afa6ffd0ac696a9e28ff1415a068"
},
"src/L2/SequencerFeeVault.sol": {
"initCodeHash": "0xb94145f571e92ee615c6fe903b6568e8aac5fe760b6b65148ffc45d2fb0f5433",
......
......@@ -5,6 +5,7 @@ import { Predeploys } from "src/libraries/Predeploys.sol";
import { TransientContext, TransientReentrancyAware } from "src/libraries/TransientContext.sol";
import { ISemver } from "src/universal/ISemver.sol";
import { ICrossL2Inbox } from "src/L2/ICrossL2Inbox.sol";
import { SafeCall } from "src/libraries/SafeCall.sol";
/// @title IDependencySet
/// @notice Interface for L1Block with only `isInDependencySet(uint256)` method.
......@@ -55,8 +56,8 @@ contract CrossL2Inbox is ICrossL2Inbox, ISemver, TransientReentrancyAware {
bytes32 internal constant CHAINID_SLOT = 0x6e0446e8b5098b8c8193f964f1b567ec3a2bdaeba33d36acb85c1f1d3f92d313;
/// @notice Semantic version.
/// @custom:semver 0.1.0
string public constant version = "0.1.0";
/// @custom:semver 1.0.0-beta.1
string public constant version = "1.0.0-beta.1";
/// @notice Emitted when a cross chain message is being executed.
/// @param encodedId Encoded Identifier of the message.
......@@ -122,7 +123,7 @@ contract CrossL2Inbox is ICrossL2Inbox, ISemver, TransientReentrancyAware {
_storeIdentifier(_id);
// Call the target account with the message payload.
bool success = _callWithAllGas(_target, _message);
bool success = SafeCall.call(_target, msg.value, _message);
// Revert if the target call failed.
if (!success) revert TargetCallFailed();
......@@ -139,23 +140,4 @@ contract CrossL2Inbox is ICrossL2Inbox, ISemver, TransientReentrancyAware {
TransientContext.set(TIMESTAMP_SLOT, _id.timestamp);
TransientContext.set(CHAINID_SLOT, _id.chainId);
}
/// @notice Calls the target address with the message payload and all available gas.
/// @param _target Target address to call.
/// @param _message Message payload to call target with.
/// @return _success True if the call was successful, and false otherwise.
function _callWithAllGas(address _target, bytes memory _message) internal returns (bool _success) {
assembly {
_success :=
call(
gas(), // gas
_target, // recipient
callvalue(), // ether value
add(_message, 32), // inloc
mload(_message), // inlen
0, // outloc
0 // outlen
)
}
}
}
......@@ -6,6 +6,7 @@ import { Predeploys } from "src/libraries/Predeploys.sol";
import { CrossL2Inbox } from "src/L2/CrossL2Inbox.sol";
import { IL2ToL2CrossDomainMessenger } from "src/L2/IL2ToL2CrossDomainMessenger.sol";
import { ISemver } from "src/universal/ISemver.sol";
import { SafeCall } from "src/libraries/SafeCall.sol";
/// @notice Thrown when a non-written slot in transient storage is attempted to be read from.
error NotEntered();
......@@ -59,8 +60,8 @@ contract L2ToL2CrossDomainMessenger is IL2ToL2CrossDomainMessenger, ISemver {
uint16 public constant messageVersion = uint16(0);
/// @notice Semantic version.
/// @custom:semver 0.1.0
string public constant version = "0.1.0";
/// @custom:semver 1.0.0-beta.1
string public constant version = "1.0.0-beta.1";
/// @notice Mapping of message hashes to boolean receipt values. Note that a message will only be present in this
/// mapping if it has successfully been relayed on this chain, and can therefore not be relayed again.
......@@ -175,7 +176,7 @@ contract L2ToL2CrossDomainMessenger is IL2ToL2CrossDomainMessenger, ISemver {
_storeMessageMetadata(_source, _sender);
bool success = _callWithAllGas(_target, _message);
bool success = SafeCall.call(_target, msg.value, _message);
if (success) {
successfulMessages[messageHash] = true;
......@@ -213,23 +214,4 @@ contract L2ToL2CrossDomainMessenger is IL2ToL2CrossDomainMessenger, ISemver {
tstore(CROSS_DOMAIN_MESSAGE_SOURCE_SLOT, _source)
}
}
/// @notice Calls the target address with the message payload and all available gas.
/// @param _target Target address to call.
/// @param _message Message payload to call target with.
/// @return _success True if the call was successful, and false otherwise.
function _callWithAllGas(address _target, bytes memory _message) internal returns (bool _success) {
assembly {
_success :=
call(
gas(), // gas
_target, // recipient
callvalue(), // ether value
add(_message, 32), // inloc
mload(_message), // inlen
0, // outloc
0 // outlen
)
}
}
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
pragma solidity ^0.8.0;
/// @title SafeCall
/// @notice Perform low level safe calls
......@@ -59,6 +59,14 @@ library SafeCall {
}
}
/// @notice Perform a low level call without copying any returndata
/// @param _target Address to call
/// @param _value Amount of value to pass to the call
/// @param _calldata Calldata to pass to the call
function call(address _target, uint256 _value, bytes memory _calldata) internal returns (bool success_) {
success_ = call({ _target: _target, _gas: gasleft(), _value: _value, _calldata: _calldata });
}
/// @notice Helper function to determine if there is sufficient gas remaining within the context
/// to guarantee that the minimum gas requirement for a call will be met as well as
/// optionally reserving a specified amount of gas for after the call has concluded.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment