Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/curvy-numbers-shake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@eth-optimism/contracts-bedrock': patch
---

Cleans up hashing and encoding library natspec and function names
62 changes: 32 additions & 30 deletions packages/contracts-bedrock/.gas-snapshot
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
GasBenchMark_L1CrossDomainMessenger:test_L1MessengerSendMessage_benchmark_0() (gas: 158608)
GasBenchMark_L1CrossDomainMessenger:test_L1MessengerSendMessage_benchmark_1() (gas: 75017)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 249829)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 116083)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 249851)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 116058)
GasBenchMark_L1CrossDomainMessenger:test_L1MessengerSendMessage_benchmark_0() (gas: 158650)
GasBenchMark_L1CrossDomainMessenger:test_L1MessengerSendMessage_benchmark_1() (gas: 75059)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 249871)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 116125)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 249893)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 116100)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 45413)
GasBenchMark_L2OutputOracle:test_appendL2Output_benchmark() (gas: 68673)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 75069)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 35373)
DeployerWhitelist_Test:test_owner() (gas: 7658)
DeployerWhitelist_Test:test_storageSlots() (gas: 33494)
Encoding_Test:test_encodeDepositTransaction() (gas: 64610)
GasPriceOracle_Test:test_baseFee() (gas: 8370)
GasPriceOracle_Test:test_gasPrice() (gas: 8381)
GasPriceOracle_Test:test_l1BaseFee() (gas: 10582)
Expand All @@ -23,7 +24,8 @@ GasPriceOracle_Test:test_setL1BaseFeeReverts() (gas: 11717)
GasPriceOracle_Test:test_setOverhead() (gas: 36767)
GasPriceOracle_Test:test_setScalar() (gas: 36818)
GasPriceOracle_Test:test_storageLayout() (gas: 86683)
Hashing_Test:test_l2TransactionHash() (gas: 104047)
Hashing_Test:test_hashDepositSource() (gas: 673)
Hashing_Test:test_hashDepositTransaction() (gas: 39129)
L1BlockTest:test_basefee() (gas: 7531)
L1BlockTest:test_hash() (gas: 7575)
L1BlockTest:test_number() (gas: 7630)
Expand All @@ -35,38 +37,38 @@ L1BlockNumberTest:test_getL1BlockNumber() (gas: 10657)
L1BlockNumberTest:test_receive() (gas: 25437)
L1CrossDomainMessenger_Test:testCannot_L1MessengerPause() (gas: 24517)
L1CrossDomainMessenger_Test:testCannot_L1MessengerUnpause() (gas: 24509)
L1CrossDomainMessenger_Test:test_L1MessengerMessageVersion() (gas: 24671)
L1CrossDomainMessenger_Test:test_L1MessengerMessageVersion() (gas: 24716)
L1CrossDomainMessenger_Test:test_L1MessengerPause() (gas: 47995)
L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageSucceeds() (gas: 77935)
L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageToSystemContract() (gas: 67946)
L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageSucceeds() (gas: 77773)
L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageToSystemContract() (gas: 67784)
L1CrossDomainMessenger_Test:test_L1MessengerRelayShouldRevertIfPaused() (gas: 60472)
L1CrossDomainMessenger_Test:test_L1MessengerSendMessage() (gas: 196861)
L1CrossDomainMessenger_Test:test_L1MessengerTwiceSendMessage() (gas: 1273524)
L1CrossDomainMessenger_Test:test_L1MessengerSendMessage() (gas: 196878)
L1CrossDomainMessenger_Test:test_L1MessengerTwiceSendMessage() (gas: 1273626)
L1CrossDomainMessenger_Test:test_L1MessengerUnpause() (gas: 40890)
L1CrossDomainMessenger_Test:test_L1MessengerXDomainSenderReverts() (gas: 24272)
L1CrossDomainMessenger_Test:test_L1MessengerxDomainMessageSenderResets() (gas: 86782)
L1StandardBridge_Test:test_depositERC20() (gas: 474966)
L1StandardBridge_Test:test_depositERC20To() (gas: 477147)
L1StandardBridge_Test:test_depositETH() (gas: 268899)
L1StandardBridge_Test:test_depositETHTo() (gas: 226721)
L1CrossDomainMessenger_Test:test_L1MessengerxDomainMessageSenderResets() (gas: 86701)
L1StandardBridge_Test:test_depositERC20() (gas: 475008)
L1StandardBridge_Test:test_depositERC20To() (gas: 477189)
L1StandardBridge_Test:test_depositETH() (gas: 268941)
L1StandardBridge_Test:test_depositETHTo() (gas: 226763)
L1StandardBridge_Test:test_finalizeERC20Withdrawal() (gas: 490759)
L1StandardBridge_Test:test_finalizeETHWithdrawal() (gas: 64409)
L1StandardBridge_Test:test_initialize() (gas: 26336)
L1StandardBridge_Test:test_onlyEOADepositERC20() (gas: 22363)
L1StandardBridge_Test:test_onlyEOADepositETH() (gas: 40882)
L1StandardBridge_Test:test_onlyL2BridgeFinalizeERC20Withdrawal() (gas: 36271)
L1StandardBridge_Test:test_onlyPortalFinalizeERC20Withdrawal() (gas: 35600)
L1StandardBridge_Test:test_receive() (gas: 413479)
L1StandardBridge_Test:test_receive() (gas: 413521)
L2CrossDomainMessenger_Test:testCannot_L2MessengerPause() (gas: 10821)
L2CrossDomainMessenger_Test:test_L2MessengerMessageVersion() (gas: 8400)
L2CrossDomainMessenger_Test:test_L2MessengerMessageVersion() (gas: 8445)
L2CrossDomainMessenger_Test:test_L2MessengerPause() (gas: 31815)
L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageSucceeds() (gas: 57494)
L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageToSystemContract() (gas: 36221)
L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageSucceeds() (gas: 57332)
L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageToSystemContract() (gas: 36140)
L2CrossDomainMessenger_Test:test_L2MessengerRelayShouldRevertIfPaused() (gas: 41664)
L2CrossDomainMessenger_Test:test_L2MessengerSendMessage() (gas: 119619)
L2CrossDomainMessenger_Test:test_L2MessengerTwiceSendMessage() (gas: 133146)
L2CrossDomainMessenger_Test:test_L2MessengerSendMessage() (gas: 119627)
L2CrossDomainMessenger_Test:test_L2MessengerTwiceSendMessage() (gas: 133248)
L2CrossDomainMessenger_Test:test_L2MessengerXDomainSenderReverts() (gas: 10599)
L2CrossDomainMessenger_Test:test_L2MessengerxDomainMessageSenderResets() (gas: 54925)
L2CrossDomainMessenger_Test:test_L2MessengerxDomainMessageSenderResets() (gas: 54844)
L2OutputOracleTest:testCannot_AppendWithUnmatchedBlockhash() (gas: 26811)
L2OutputOracleTest:testCannot_appendEmptyOutput() (gas: 24086)
L2OutputOracleTest:testCannot_appendFutureTimetamp() (gas: 26075)
Expand All @@ -90,14 +92,14 @@ L2OutputOracleUpgradeable_Test:test_cannotInitImpl() (gas: 8476)
L2OutputOracleUpgradeable_Test:test_cannotInitProxy() (gas: 13497)
L2OutputOracleUpgradeable_Test:test_initValuesOnProxy() (gas: 38865)
L2OutputOracleUpgradeable_Test:test_upgrading() (gas: 230843)
L2StandardBridge_Test:test_ERC20BridgeFailed_whenLocalTokenIsBridge() (gas: 133158)
L2StandardBridge_Test:test_ERC20BridgeFailed_whenLocalTokenIsBridge() (gas: 133200)
L2StandardBridge_Test:test_cannotWithdrawEthWithoutSendingIt() (gas: 21656)
L2StandardBridge_Test:test_finalizeDeposit() (gas: 93203)
L2StandardBridge_Test:test_finalizeDeposit_failsToCompleteOutboundTransfer() (gas: 140168)
L2StandardBridge_Test:test_finalizeDeposit_failsToCompleteOutboundTransfer() (gas: 140210)
L2StandardBridge_Test:test_initialize() (gas: 14802)
L2StandardBridge_Test:test_receive() (gas: 136483)
L2StandardBridge_Test:test_withdraw() (gas: 352780)
L2StandardBridge_Test:test_withdrawTo() (gas: 353464)
L2StandardBridge_Test:test_receive() (gas: 136525)
L2StandardBridge_Test:test_withdraw() (gas: 352813)
L2StandardBridge_Test:test_withdrawTo() (gas: 353498)
L2StandardBridge_Test:test_withdraw_onlyEOA() (gas: 252006)
L2ToL1MessagePasserTest:test_burn() (gas: 112037)
L2ToL1MessagePasserTest:test_initiateWithdrawal_fromContract() (gas: 67892)
Expand Down Expand Up @@ -267,4 +269,4 @@ SequencerFeeVault_Test:test_constructor() (gas: 7656)
SequencerFeeVault_Test:test_minWithdrawalAmount() (gas: 5407)
SequencerFeeVault_Test:test_receive() (gas: 17258)
SequencerFeeVault_Test:test_revertWithdraw() (gas: 9332)
SequencerFeeVault_Test:test_withdraw() (gas: 147281)
SequencerFeeVault_Test:test_withdraw() (gas: 147323)
4 changes: 2 additions & 2 deletions packages/contracts-bedrock/.storage-layout
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
|------------------------+--------------------------+------+--------+-------+----------------------------------------------------------------|
| xDomainMsgSender | address | 202 | 0 | 20 | contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
|------------------------+--------------------------+------+--------+-------+----------------------------------------------------------------|
| msgNonce | uint256 | 203 | 0 | 32 | contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| msgNonce | uint240 | 203 | 0 | 30 | contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
|------------------------+--------------------------+------+--------+-------+----------------------------------------------------------------|
| otherMessenger | address | 204 | 0 | 20 | contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
|------------------------+--------------------------+------+--------+-------+----------------------------------------------------------------|
Expand Down Expand Up @@ -192,7 +192,7 @@
|------------------------+--------------------------+------+--------+-------+----------------------------------------------------------------|
| xDomainMsgSender | address | 202 | 0 | 20 | contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger |
|------------------------+--------------------------+------+--------+-------+----------------------------------------------------------------|
| msgNonce | uint256 | 203 | 0 | 32 | contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger |
| msgNonce | uint240 | 203 | 0 | 30 | contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger |
|------------------------+--------------------------+------+--------+-------+----------------------------------------------------------------|
| otherMessenger | address | 204 | 0 | 20 | contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger |
|------------------------+--------------------------+------+--------+-------+----------------------------------------------------------------|
Expand Down
4 changes: 2 additions & 2 deletions packages/contracts-bedrock/contracts/L1/OptimismPortal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -242,13 +242,13 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {

// Verify that the output root can be generated with the elements in the proof.
require(
proposal.outputRoot == Hashing._deriveOutputRoot(_outputRootProof),
proposal.outputRoot == Hashing.hashOutputRootProof(_outputRootProof),
"OptimismPortal: invalid output root proof"
);

// All withdrawals have a unique hash, we'll use this as the identifier for the withdrawal
// and to prevent replay attacks.
bytes32 withdrawalHash = Hashing.withdrawalHash(
bytes32 withdrawalHash = Hashing.hashWithdrawal(
_nonce,
_sender,
_target,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ contract L2ToL1MessagePasser is Semver {
uint256 _gasLimit,
bytes memory _data
) public payable {
bytes32 withdrawalHash = Hashing.withdrawalHash(
bytes32 withdrawalHash = Hashing.hashWithdrawal(
nonce,
msg.sender,
_target,
Expand Down
160 changes: 90 additions & 70 deletions packages/contracts-bedrock/contracts/libraries/Encoding.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,106 +10,114 @@ import { RLPWriter } from "./rlp/RLPWriter.sol";
*/
library Encoding {
/**
* Generates the correct cross domain calldata for a message.
* @param _target Target contract address.
* @param _sender Message sender address.
* @param _message Message to send to the target.
* @param _messageNonce Nonce for the provided message.
* @return ABI encoded cross domain calldata.
* @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent
* to the L2 system. Useful for searching for a deposit in the L2 system.
*
* @param _from Address of the sender of the deposit.
* @param _to Address of the receiver of the deposit.
* @param _value ETH value to send to the receiver.
* @param _mint ETH value to mint on L2.
* @param _gasLimit Gas limit to use for the transaction.
* @param _isCreation Whether or not the transaction is a contract creation.
* @param _data Data to send with the transaction.
* @param _l1BlockHash Hash of the L1 block where the deposit was included.
* @param _logIndex Index of the deposit event in the L1 block.
*
* @return RLP encoded L2 deposit transaction.
*/
function encodeXDomainCalldata(
address _target,
address _sender,
bytes memory _message,
uint256 _messageNonce
) internal pure returns (bytes memory) {
return
abi.encodeWithSignature(
"relayMessage(address,address,bytes,uint256)",
_target,
_sender,
_message,
_messageNonce
);
}

/**
* @notice RLP encode a deposit transaction
* This only works for user deposits, not system deposits
* TODO: better name + rearrange the input param ordering?
*/
function L2Transaction(
bytes32 _l1BlockHash,
uint256 _logIndex,
function encodeDepositTransaction(
address _from,
address _to,
bool _isCreate,
uint256 _mint,
uint256 _value,
uint256 _gas,
bytes memory _data
uint256 _mint,
uint64 _gasLimit,
bool _isCreation,
bytes memory _data,
bytes32 _l1BlockHash,
uint256 _logIndex
) internal pure returns (bytes memory) {
bytes32 source = Hashing.sourceHash(_l1BlockHash, _logIndex);

bytes32 source = Hashing.hashDepositSource(_l1BlockHash, _logIndex);
bytes[] memory raw = new bytes[](7);

raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));
raw[1] = RLPWriter.writeAddress(_from);

if (_isCreate == true) {
require(_to == address(0));
raw[2] = RLPWriter.writeBytes("");
} else {
raw[2] = RLPWriter.writeAddress(_to);
}

raw[2] = _isCreation ? RLPWriter.writeBytes("") : RLPWriter.writeAddress(_to);
raw[3] = RLPWriter.writeUint(_mint);
raw[4] = RLPWriter.writeUint(_value);
raw[5] = RLPWriter.writeUint(_gas);
raw[5] = RLPWriter.writeUint(uint256(_gasLimit));
raw[6] = RLPWriter.writeBytes(_data);

bytes memory encoded = RLPWriter.writeList(raw);
return abi.encodePacked(uint8(0x7e), uint8(0x0), encoded);
return abi.encodePacked(uint8(0x7e), uint8(0x0), RLPWriter.writeList(raw));
}

/**
* @notice Encodes the cross domain message based on the version that
* is encoded in the nonce
* @notice Encodes the cross domain message based on the version that is encoded into the
* message nonce.
*
* @param _nonce Message nonce with version encoded into the first two bytes.
* @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 getVersionedEncoding(
function encodeCrossDomainMessage(
uint256 _nonce,
address _sender,
address _target,
uint256 _value,
uint256 _gasLimit,
bytes memory _data
) internal pure returns (bytes memory) {
uint16 version = getVersionFromNonce(_nonce);
(, uint16 version) = decodeVersionedNonce(_nonce);
if (version == 0) {
return getEncodingV0(_target, _sender, _data, _nonce);
return encodeCrossDomainMessageV0(_target, _sender, _data, _nonce);
} else if (version == 1) {
return getEncodingV1(_nonce, _sender, _target, _value, _gasLimit, _data);
return encodeCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);
} else {
revert("Encoding: unknown cross domain message version");
}

revert("Unknown version.");
}

/**
* @notice Compute the legacy cross domain serialization
* @notice Encodes a cross domain message based on the V0 (legacy) encoding.
*
* @param _target Address of the target of the message.
* @param _sender Address of the sender of the message.
* @param _data Data to send with the message.
* @param _nonce Message nonce.
*
* @return Encoded cross domain message.
*/
function getEncodingV0(
function encodeCrossDomainMessageV0(
address _target,
address _sender,
bytes memory _data,
uint256 _nonce
) internal pure returns (bytes memory) {
return encodeXDomainCalldata(_target, _sender, _data, _nonce);
return
abi.encodeWithSignature(
"relayMessage(address,address,bytes,uint256)",
_target,
_sender,
_data,
_nonce
);
}

/**
* @notice Compute the V1 cross domain serialization
* @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 getEncodingV1(
function encodeCrossDomainMessageV1(
uint256 _nonce,
address _sender,
address _target,
Expand All @@ -130,24 +138,36 @@ library Encoding {
}

/**
* @notice Adds the version to the nonce
* @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 addVersionToNonce(uint256 _nonce, uint16 _version)
internal
pure
returns (uint256 nonce)
{
function encodeVersionedNonce(uint240 _nonce, uint16 _version) internal pure returns (uint256) {
uint256 nonce;
assembly {
nonce := or(shl(240, _version), _nonce)
}
return nonce;
}

/**
* @notice Gets the version out of the nonce
* @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 getVersionFromNonce(uint256 _nonce) internal pure returns (uint16 version) {
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);
}
}
Loading