Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

contracts: implement fee vault config encoding #12349

Closed
wants to merge 2 commits into from
Closed
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
32 changes: 32 additions & 0 deletions packages/contracts-bedrock/src/libraries/Encoding.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity ^0.8.0;
import { Types } from "src/libraries/Types.sol";
import { Hashing } from "src/libraries/Hashing.sol";
import { RLPWriter } from "src/libraries/rlp/RLPWriter.sol";
import { UnsafeCast } from "src/libraries/errors/CommonErrors.sol";

/// @title Encoding
/// @notice Encoding handles Optimism's various different encoding schemes.
Expand Down Expand Up @@ -134,6 +135,37 @@ library Encoding {
return (nonce, version);
}

/// @notice Encodes a fee vault configuration into a single bytes32 value.
/// @param _recipient Address of the recipient of the fee vault.
/// @param _amount Minimum withdrawal amount of the fee vault.
/// @param _network Withdrawal network for the fee vault.
function encodeFeeVaultConfig(
address _recipient,
uint256 _amount,
Types.WithdrawalNetwork _network
)
internal
pure
returns (bytes32)
{
if (_amount > type(uint88).max) revert UnsafeCast();
return bytes32(uint256(_network) << 248 | _amount << 160 | uint256(uint160(_recipient)));
}

/// @notice Decodes a fee vault configuration from a single bytes32 value.
/// @return recipient_ Address of the recipient of the fee vault.
/// @return amount_ Minimum withdrawal amount of the fee vault.
/// @return network_ Withdrawal network for the fee vault.
function decodeFeeVaultConfig(bytes32 _data)
internal
pure
returns (address recipient_, uint256 amount_, Types.WithdrawalNetwork network_)
{
recipient_ = address(uint160(uint256(_data) & uint256(type(uint160).max)));
amount_ = (uint256(_data) & uint256(type(uint88).max) << 160) >> 160;
network_ = Types.WithdrawalNetwork(uint8(uint256(_data >> 248)));
}

/// @notice Returns an appropriately encoded call to L1Block.setL1BlockValuesEcotone
/// @param _baseFeeScalar L1 base fee Scalar
/// @param _blobBaseFeeScalar L1 blob base fee Scalar
Expand Down
8 changes: 8 additions & 0 deletions packages/contracts-bedrock/src/libraries/Types.sol
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,12 @@ library Types {
uint256 gasLimit;
bytes data;
}

/// @notice Enum representing where the FeeVault withdraws funds to.
/// @custom:value L1 FeeVault withdraws funds to L1.
/// @custom:value L2 FeeVault withdraws funds to L2.
enum WithdrawalNetwork {
L1,
L2
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ error NotCustomGasToken();

/// @notice Error for when a transfer via call fails.
error TransferFailed();

/// @notice Error for when a type cast is unsafe.
error UnsafeCast();
12 changes: 12 additions & 0 deletions packages/contracts-bedrock/test/libraries/Encoding.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,16 @@ contract Encoding_Test is CommonTest {

assertEq(txn, _txn);
}

/// @notice Roundtrip test for fee vault encoding.
// A boolean is used to determine which network should be used.
function testFuzz_encodeFeeVaultConfig_succeeds(address _recipient, uint88 _amount, bool _network) public pure {
Types.WithdrawalNetwork _withdrawalNetwork = _network ? Types.WithdrawalNetwork.L2 : Types.WithdrawalNetwork.L1;
bytes32 encoded = Encoding.encodeFeeVaultConfig(_recipient, uint256(_amount), _withdrawalNetwork);
(address recipient, uint256 amount, Types.WithdrawalNetwork withdrawalNetwork) =
Encoding.decodeFeeVaultConfig(encoded);
assertEq(_recipient, recipient, "bad recipient");
assertEq(uint256(_amount), amount, "bad amount");
assertEq(uint256(withdrawalNetwork), uint256(withdrawalNetwork), "bad network");
}
}