diff --git a/interfaces/L2/IFeeVault.sol b/interfaces/L2/IFeeVault.sol index ee6fdba4..87730a57 100644 --- a/interfaces/L2/IFeeVault.sol +++ b/interfaces/L2/IFeeVault.sol @@ -4,6 +4,18 @@ pragma solidity ^0.8.0; import { IProxyAdminOwnedBase } from "interfaces/L1/IProxyAdminOwnedBase.sol"; import { Types } from "src/libraries/Types.sol"; +/// @title IFeeVault +/// @notice Interface for the FeeVault contract that manages fee withdrawals +/// and recipient configurations. +/// @dev Security Note: The `initialize` function MUST be protected with OpenZeppelin's +/// `initializer` modifier to prevent reinitialization attacks. The implementation +/// contract MUST be initialized in the constructor using `_disableInitializers()` +/// to prevent front-running attacks on the uninitialized implementation. +/// +/// @custom:risk Uninitialized Implementation Front-Running +/// If the implementation contract is not initialized during deployment, an attacker +/// could call `initialize` directly on the implementation, setting their own recipient +/// and withdrawal network. Always call `_disableInitializers()` in the constructor. interface IFeeVault is IProxyAdminOwnedBase { error InvalidInitialization(); error NotInitializing(); @@ -20,6 +32,13 @@ interface IFeeVault is IProxyAdminOwnedBase { receive() external payable; + /// @notice Initializes the FeeVault with recipient, min withdrawal amount, and network. + /// @dev IMPORTANT: This function MUST be protected with the `initializer` modifier. + /// Only the first call should succeed; subsequent calls must revert. + /// @param _recipient The address that will receive withdrawn fees. + /// @param _minWithdrawalAmount Minimum amount required to trigger a withdrawal. + /// @param _withdrawalNetwork The target network for withdrawals (L1 or L2). + /// @custom:risk Multiple calls to initialize can hijack the contract's configuration. function initialize( address _recipient, uint256 _minWithdrawalAmount, @@ -38,5 +57,9 @@ interface IFeeVault is IProxyAdminOwnedBase { function setRecipient(address _newRecipient) external; function setWithdrawalNetwork(Types.WithdrawalNetwork _newWithdrawalNetwork) external; + /// @notice One-time initialization function for proxy setup. + /// @dev IMPORTANT: This function MUST be protected so it can only be called once. + /// Implementers should use OpenZeppelin's Initializable pattern. + /// @custom:risk Reinitialization can lead to configuration hijacking. function __constructor__() external; }