Commit 7d1351bd authored by Mark Tyneway's avatar Mark Tyneway

contracts-bedrock: fee vault track total value

Adds an accumulator for the total amount of fees
withdrawn from the system. This is really helpful for
data analytics. I also think it could be used to build
an on chain prediction market for economic activity.
This code path isn't triggered too often, so an extra
sload/sstore and checked math doesn't matter much.
parent 87bd4f55
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -9,11 +9,11 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const SequencerFeeVaultStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"contracts/L2/SequencerFeeVault.sol:SequencerFeeVault\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"}}}"
const SequencerFeeVaultStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"contracts/L2/SequencerFeeVault.sol:SequencerFeeVault\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":1001,\"contract\":\"contracts/L2/SequencerFeeVault.sol:SequencerFeeVault\",\"label\":\"totalProcessed\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"
var SequencerFeeVaultStorageLayout = new(solc.StorageLayout)
var SequencerFeeVaultDeployedBin = "0x60806040526004361061005e5760003560e01c806354fd4d501161004357806354fd4d50146100df578063d3e5792b14610101578063d4ff92181461014357600080fd5b80630d9019e11461006a5780633ccfd60b146100c857600080fd5b3661006557005b600080fd5b34801561007657600080fd5b5061009e7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156100d457600080fd5b506100dd610176565b005b3480156100eb57600080fd5b506100f461037d565b6040516100bf91906105d7565b34801561010d57600080fd5b506101357f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016100bf565b34801561014f57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061009e565b7f0000000000000000000000000000000000000000000000000000000000000000471015610250576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a40160405180910390fd5b60408051478082527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166020830152338284015291517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a1604080516020810182526000815290517fe11013dd0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109163e11013dd918491610348917f000000000000000000000000000000000000000000000000000000000000000091614e20916004016105f1565b6000604051808303818588803b15801561036157600080fd5b505af1158015610375573d6000803e3d6000fd5b505050505050565b60606103a87f0000000000000000000000000000000000000000000000000000000000000000610420565b6103d17f0000000000000000000000000000000000000000000000000000000000000000610420565b6103fa7f0000000000000000000000000000000000000000000000000000000000000000610420565b60405160200161040c93929190610635565b604051602081830303815290604052905090565b60608160000361046357505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561048d5780610477816106da565b91506104869050600a83610741565b9150610467565b60008167ffffffffffffffff8111156104a8576104a8610755565b6040519080825280601f01601f1916602001820160405280156104d2576020820181803683370190505b5090505b8415610555576104e7600183610784565b91506104f4600a8661079b565b6104ff9060306107af565b60f81b818381518110610514576105146107c7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061054e600a86610741565b94506104d6565b949350505050565b60005b83811015610578578181015183820152602001610560565b83811115610587576000848401525b50505050565b600081518084526105a581602086016020860161055d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006105ea602083018461058d565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff8416815263ffffffff8316602082015260606040820152600061062c606083018461058d565b95945050505050565b6000845161064781846020890161055d565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610683816001850160208a0161055d565b6001920191820152835161069e81600284016020880161055d565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361070b5761070b6106ab565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261075057610750610712565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082821015610796576107966106ab565b500390565b6000826107aa576107aa610712565b500690565b600082198211156107c2576107c26106ab565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a"
var SequencerFeeVaultDeployedBin = "0x6080604052600436106100695760003560e01c806384411d651161004357806384411d651461010c578063d3e5792b14610130578063d4ff92181461016457600080fd5b80630d9019e1146100755780633ccfd60b146100d357806354fd4d50146100ea57600080fd5b3661007057005b600080fd5b34801561008157600080fd5b506100a97f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156100df57600080fd5b506100e8610197565b005b3480156100f657600080fd5b506100ff6103b9565b6040516100ca9190610613565b34801561011857600080fd5b5061012260015481565b6040519081526020016100ca565b34801561013c57600080fd5b506101227f000000000000000000000000000000000000000000000000000000000000000081565b34801561017057600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006100a9565b7f0000000000000000000000000000000000000000000000000000000000000000471015610271576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a40160405180910390fd5b60004790508060016000828254610288919061065c565b9091555050604080518281527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166020820152338183015290517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a1604080516020810182526000815290517fe11013dd0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109163e11013dd918491610384917f000000000000000000000000000000000000000000000000000000000000000091614e2091600401610674565b6000604051808303818588803b15801561039d57600080fd5b505af11580156103b1573d6000803e3d6000fd5b505050505050565b60606103e47f000000000000000000000000000000000000000000000000000000000000000061045c565b61040d7f000000000000000000000000000000000000000000000000000000000000000061045c565b6104367f000000000000000000000000000000000000000000000000000000000000000061045c565b604051602001610448939291906106b8565b604051602081830303815290604052905090565b60608160000361049f57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156104c957806104b38161072e565b91506104c29050600a83610795565b91506104a3565b60008167ffffffffffffffff8111156104e4576104e46107a9565b6040519080825280601f01601f19166020018201604052801561050e576020820181803683370190505b5090505b8415610591576105236001836107d8565b9150610530600a866107ef565b61053b90603061065c565b60f81b81838151811061055057610550610803565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061058a600a86610795565b9450610512565b949350505050565b60005b838110156105b457818101518382015260200161059c565b838111156105c3576000848401525b50505050565b600081518084526105e1816020860160208601610599565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061062660208301846105c9565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561066f5761066f61062d565b500190565b73ffffffffffffffffffffffffffffffffffffffff8416815263ffffffff831660208201526060604082015260006106af60608301846105c9565b95945050505050565b600084516106ca818460208901610599565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610706816001850160208a01610599565b60019201918201528351610721816002840160208801610599565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361075f5761075f61062d565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826107a4576107a4610766565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156107ea576107ea61062d565b500390565b6000826107fe576107fe610766565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(SequencerFeeVaultStorageLayoutJSON), SequencerFeeVaultStorageLayout); err != nil {
......
......@@ -19,7 +19,7 @@ CrossDomainOwnable2_Test:test_onlyOwner_notOwner_reverts() (gas: 16588)
CrossDomainOwnable2_Test:test_onlyOwner_succeeds() (gas: 77782)
DeployerWhitelist_Test:test_owner_succeeds() (gas: 7538)
DeployerWhitelist_Test:test_storageSlots_succeeds() (gas: 33395)
FeeVault_Test:test_constructor_succeeds() (gas: 10601)
FeeVault_Test:test_constructor_succeeds() (gas: 10647)
FeeVault_Test:test_minWithdrawalAmount_succeeds() (gas: 10668)
GasPriceOracle_Test:test_baseFee_succeeds() (gas: 8291)
GasPriceOracle_Test:test_gasPrice_succeeds() (gas: 8294)
......@@ -310,8 +310,8 @@ Semver_Test:test_version_succeeds() (gas: 9396)
SequencerFeeVault_Test:test_constructor_succeeds() (gas: 5504)
SequencerFeeVault_Test:test_minWithdrawalAmount_succeeds() (gas: 5420)
SequencerFeeVault_Test:test_receive_succeeds() (gas: 17336)
SequencerFeeVault_Test:test_withdraw_notEnough_reverts() (gas: 9310)
SequencerFeeVault_Test:test_withdraw_succeeds() (gas: 135878)
SequencerFeeVault_Test:test_withdraw_notEnough_reverts() (gas: 9309)
SequencerFeeVault_Test:test_withdraw_succeeds() (gas: 159816)
SystemConfig_Initialize_TestFail:test_initialize_lowGasLimit_reverts() (gas: 61707)
SystemConfig_Setters_TestFail:test_setBatcherHash_notOwner_reverts() (gas: 10501)
SystemConfig_Setters_TestFail:test_setGasConfig_notOwner_reverts() (gas: 10576)
......
......@@ -281,11 +281,33 @@
➡ contracts/L2/SequencerFeeVault.sol:SequencerFeeVault
=======================
+---------------+---------+------+--------+-------+------------------------------------------------------+
| Name | Type | Slot | Offset | Bytes | Contract |
+========================================================================================================+
| spacer_0_0_20 | address | 0 | 0 | 20 | contracts/L2/SequencerFeeVault.sol:SequencerFeeVault |
+---------------+---------+------+--------+-------+------------------------------------------------------+
+----------------+---------+------+--------+-------+------------------------------------------------------+
| Name | Type | Slot | Offset | Bytes | Contract |
+=========================================================================================================+
| spacer_0_0_20 | address | 0 | 0 | 20 | contracts/L2/SequencerFeeVault.sol:SequencerFeeVault |
|----------------+---------+------+--------+-------+------------------------------------------------------|
| totalProcessed | uint256 | 1 | 0 | 32 | contracts/L2/SequencerFeeVault.sol:SequencerFeeVault |
+----------------+---------+------+--------+-------+------------------------------------------------------+
=======================
➡ contracts/L2/BaseFeeVault.sol:BaseFeeVault
=======================
+----------------+---------+------+--------+-------+--------------------------------------------+
| Name | Type | Slot | Offset | Bytes | Contract |
+===============================================================================================+
| totalProcessed | uint256 | 0 | 0 | 32 | contracts/L2/BaseFeeVault.sol:BaseFeeVault |
+----------------+---------+------+--------+-------+--------------------------------------------+
=======================
➡ contracts/L2/L1FeeVault.sol:L1FeeVault
=======================
+----------------+---------+------+--------+-------+----------------------------------------+
| Name | Type | Slot | Offset | Bytes | Contract |
+===========================================================================================+
| totalProcessed | uint256 | 0 | 0 | 32 | contracts/L2/L1FeeVault.sol:L1FeeVault |
+----------------+---------+------+--------+-------+----------------------------------------+
=======================
➡ contracts/vendor/WETH9.sol:WETH9
......
......@@ -7,19 +7,29 @@ import { Predeploys } from "../libraries/Predeploys.sol";
import { FeeVault } from "../universal/FeeVault.sol";
/**
* @custom:proxied
* @custom:predeploy 0x4200000000000000000000000000000000000011
* @title SequencerFeeVault
* @notice The SequencerFeeVault is the contract that holds any fees paid to the Sequencer during
* transaction processing and block production.
* @custom:legacy
* @title SequencerFeeVaultLegacySpacer
* @notice Contract only exists to add a spacer to the SequencerFeeVault where the
* l1FeeWallet variable used to exist. Must be the first contract in the inheritance
* tree of the SequencerFeeVault
*/
contract SequencerFeeVault is FeeVault, Semver {
contract SequencerFeeVaultLegacySpacer {
/**
* @custom:legacy
* @custom:spacer l1FeeWallet
* @notice Spacer for backwards compatibility.
*/
address private spacer_0_0_20;
}
/**
* @custom:proxied
* @custom:predeploy 0x4200000000000000000000000000000000000011
* @title SequencerFeeVault
* @notice The SequencerFeeVault is the contract that holds any fees paid to the Sequencer during
* transaction processing and block production.
*/
contract SequencerFeeVault is SequencerFeeVaultLegacySpacer, FeeVault, Semver {
/**
* @custom:semver 0.0.1
*/
......
......@@ -46,11 +46,16 @@ contract SequencerFeeVault_Test is Bridge_Initializer {
}
function test_withdraw_succeeds() external {
vm.deal(address(vault), vault.MIN_WITHDRAWAL_AMOUNT() + 1);
uint256 amount = vault.MIN_WITHDRAWAL_AMOUNT() + 1;
vm.deal(address(vault), amount);
// No ether has been withdrawn yet
assertEq(vault.totalProcessed(), 0);
vm.expectEmit(true, true, true, true);
emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this));
// The entire vault's balance is withdrawn
vm.expectCall(
Predeploys.L2_STANDARD_BRIDGE,
address(vault).balance,
......@@ -63,5 +68,8 @@ contract SequencerFeeVault_Test is Bridge_Initializer {
);
vault.withdraw();
// The withdrawal was successful
assertEq(vault.totalProcessed(), amount);
}
}
......@@ -24,6 +24,11 @@ abstract contract FeeVault {
*/
address public immutable RECIPIENT;
/**
* @notice Total amount of wei processed by the contract.
*/
uint256 public totalProcessed;
/**
* @param _recipient - The L1 account that funds can be withdrawn to.
* @param _minWithdrawalAmount - The min amount of funds before a withdrawal
......@@ -49,6 +54,8 @@ abstract contract FeeVault {
);
uint256 value = address(this).balance;
totalProcessed += value;
emit Withdrawal(value, RECIPIENT, msg.sender);
L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).bridgeETHTo{ value: value }(
......
......@@ -24,6 +24,8 @@ contracts=(
contracts/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser
contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH
contracts/L2/SequencerFeeVault.sol:SequencerFeeVault
contracts/L2/BaseFeeVault.sol:BaseFeeVault
contracts/L2/L1FeeVault.sol:L1FeeVault
contracts/vendor/WETH9.sol:WETH9
contracts/universal/ProxyAdmin.sol:ProxyAdmin
contracts/universal/Proxy.sol:Proxy
......
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