Commit b01b93ee authored by Maurelian's avatar Maurelian Committed by GitHub

feat: Remove DelayedVetoable (#12939)

parent 1a067802
This diff is collapsed.
[
{
"inputs": [
{
"internalType": "address",
"name": "_vetoer",
"type": "address"
},
{
"internalType": "address",
"name": "_initiator",
"type": "address"
},
{
"internalType": "address",
"name": "_target",
"type": "address"
},
{
"internalType": "uint256",
"name": "_operatingDelay",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"stateMutability": "nonpayable",
"type": "fallback"
},
{
"inputs": [],
"name": "delay",
"outputs": [
{
"internalType": "uint256",
"name": "delay_",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "initiator",
"outputs": [
{
"internalType": "address",
"name": "initiator_",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "_callHash",
"type": "bytes32"
}
],
"name": "queuedAt",
"outputs": [
{
"internalType": "uint256",
"name": "queuedAt_",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "target",
"outputs": [
{
"internalType": "address",
"name": "target_",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "version",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "vetoer",
"outputs": [
{
"internalType": "address",
"name": "vetoer_",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "delay",
"type": "uint256"
}
],
"name": "DelayActivated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "callHash",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "Forwarded",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "callHash",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "Initiated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "callHash",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "Vetoed",
"type": "event"
},
{
"inputs": [],
"name": "ForwardingEarly",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "expected",
"type": "address"
},
{
"internalType": "address",
"name": "actual",
"type": "address"
}
],
"name": "Unauthorized",
"type": "error"
}
]
\ No newline at end of file
...@@ -3,10 +3,6 @@ ...@@ -3,10 +3,6 @@
"initCodeHash": "0xbd00d6568abab3e7fc211c40d682862242f25493010a4a097bd1f3b45c8c87c3", "initCodeHash": "0xbd00d6568abab3e7fc211c40d682862242f25493010a4a097bd1f3b45c8c87c3",
"sourceCodeHash": "0x58b587034a67b4bb718abbaded8ac23b082c0971105874bcc42c23f051c67f6e" "sourceCodeHash": "0x58b587034a67b4bb718abbaded8ac23b082c0971105874bcc42c23f051c67f6e"
}, },
"src/L1/DelayedVetoable.sol": {
"initCodeHash": "0x9fe8ade6f6332262ff1f3539ac0bf57660edbad3cf4c4cb230c2ddac18aa0a3f",
"sourceCodeHash": "0x30e83a535ef27b2e900c831c4e1a4ec2750195350011c4fdacda1da9db2d167b"
},
"src/L1/L1CrossDomainMessenger.sol": { "src/L1/L1CrossDomainMessenger.sol": {
"initCodeHash": "0x2e9cb3ceb5e55341b311f0666ef7655df4fafae75afdfbcd701cd9c9b2b017d5", "initCodeHash": "0x2e9cb3ceb5e55341b311f0666ef7655df4fafae75afdfbcd701cd9c9b2b017d5",
"sourceCodeHash": "0x848ec3774be17bcc8ba65a23d08e35e979b3f39f9d2ac8a810188f945c69c9ea" "sourceCodeHash": "0x848ec3774be17bcc8ba65a23d08e35e979b3f39f9d2ac8a810188f945c69c9ea"
......
[
{
"bytes": "32",
"label": "_delay",
"offset": 0,
"slot": "0",
"type": "uint256"
},
{
"bytes": "32",
"label": "_queuedAt",
"offset": 0,
"slot": "1",
"type": "mapping(bytes32 => uint256)"
}
]
\ No newline at end of file
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Interfaces
import { ISemver } from "src/universal/interfaces/ISemver.sol";
/// @title DelayedVetoable
/// @notice This contract enables a delay before a call is forwarded to a target contract, and during the delay period
/// the call can be vetoed by the authorized vetoer.
/// This contract does not support value transfers, only data is forwarded.
/// Additionally, this contract cannot be used to forward calls with data beginning with the function selector
/// of the queuedAt(bytes32) function. This is because of input validation checks which solidity performs at
/// runtime on functions which take an argument.
contract DelayedVetoable is ISemver {
/// @notice Error for when attempting to forward too early.
error ForwardingEarly();
/// @notice Error for unauthorized calls.
error Unauthorized(address expected, address actual);
/// @notice An event that is emitted when the delay is activated.
/// @param delay The delay that was activated.
event DelayActivated(uint256 delay);
/// @notice An event that is emitted when a call is initiated.
/// @param callHash The hash of the call data.
/// @param data The data of the initiated call.
event Initiated(bytes32 indexed callHash, bytes data);
/// @notice An event that is emitted each time a call is forwarded.
/// @param callHash The hash of the call data.
/// @param data The data forwarded to the target.
event Forwarded(bytes32 indexed callHash, bytes data);
/// @notice An event that is emitted each time a call is vetoed.
/// @param callHash The hash of the call data.
/// @param data The data forwarded to the target.
event Vetoed(bytes32 indexed callHash, bytes data);
/// @notice The address that all calls are forwarded to after the delay.
address internal immutable TARGET;
/// @notice The address that can veto a call.
address internal immutable VETOER;
/// @notice The address that can initiate a call.
address internal immutable INITIATOR;
/// @notice The delay which will be set after the initial system deployment is completed.
uint256 internal immutable OPERATING_DELAY;
/// @notice The current amount of time to wait before forwarding a call.
uint256 internal _delay;
/// @notice The time that a call was initiated.
mapping(bytes32 => uint256) internal _queuedAt;
/// @notice A modifier that reverts if not called by the vetoer or by address(0) to allow
/// eth_call to interact with this proxy without needing to use low-level storage
/// inspection. We assume that nobody is able to trigger calls from address(0) during
/// normal EVM execution.
modifier readOrHandle() {
if (msg.sender == address(0)) {
_;
} else {
// This WILL halt the call frame on completion.
_handleCall();
}
}
/// @notice Semantic version.
/// @custom:semver 1.0.1-beta.2
string public constant version = "1.0.1-beta.2";
/// @notice Sets the target admin during contract deployment.
/// @param _vetoer Address of the vetoer.
/// @param _initiator Address of the initiator.
/// @param _target Address of the target.
/// @param _operatingDelay Time to delay when the system is operational.
constructor(address _vetoer, address _initiator, address _target, uint256 _operatingDelay) {
// Note that the _delay value is not set here. Having an initial delay of 0 is helpful
// during the deployment of a new system.
VETOER = _vetoer;
INITIATOR = _initiator;
TARGET = _target;
OPERATING_DELAY = _operatingDelay;
}
/// @notice Gets the initiator
/// @return initiator_ Initiator address.
function initiator() external virtual readOrHandle returns (address initiator_) {
initiator_ = INITIATOR;
}
//// @notice Queries the vetoer address.
/// @return vetoer_ Vetoer address.
function vetoer() external virtual readOrHandle returns (address vetoer_) {
vetoer_ = VETOER;
}
//// @notice Queries the target address.
/// @return target_ Target address.
function target() external readOrHandle returns (address target_) {
target_ = TARGET;
}
/// @notice Gets the delay
/// @return delay_ Delay address.
function delay() external readOrHandle returns (uint256 delay_) {
delay_ = _delay;
}
/// @notice Gets entries in the _queuedAt mapping.
/// @param _callHash The hash of the call data.
/// @return queuedAt_ The time the callHash was recorded.
function queuedAt(bytes32 _callHash) external readOrHandle returns (uint256 queuedAt_) {
queuedAt_ = _queuedAt[_callHash];
}
/// @notice Used for all calls that pass data to the contract.
fallback() external {
_handleCall();
}
/// @notice Receives all calls other than those made by the vetoer.
/// This enables transparent initiation and forwarding of calls to the target and avoids
/// the need for additional layers of abi encoding.
function _handleCall() internal {
// The initiator and vetoer activate the delay by passing in null data.
if (msg.data.length == 0 && _delay == 0) {
if (msg.sender != INITIATOR && msg.sender != VETOER) {
revert Unauthorized(INITIATOR, msg.sender);
}
_delay = OPERATING_DELAY;
emit DelayActivated(_delay);
return;
}
bytes32 callHash = keccak256(msg.data);
// Case 1: The initiator is calling the contract to initiate a call.
if (msg.sender == INITIATOR && _queuedAt[callHash] == 0) {
if (_delay == 0) {
// This forward function will halt the call frame on completion.
_forwardAndHalt(callHash);
}
_queuedAt[callHash] = block.timestamp;
emit Initiated(callHash, msg.data);
return;
}
// Case 2: The vetoer is calling the contract to veto a call.
// Note: The vetoer retains the ability to veto even after the delay has passed. This makes censoring the vetoer
// more costly, as there is no time limit after which their transaction can be included.
if (msg.sender == VETOER && _queuedAt[callHash] != 0) {
delete _queuedAt[callHash];
emit Vetoed(callHash, msg.data);
return;
}
// Case 3: The call is from an unpermissioned actor. We'll forward the call if the delay has
// passed.
if (_queuedAt[callHash] == 0) {
// The call has not been initiated, so we'll treat this is an unauthorized initiation attempt.
revert Unauthorized(INITIATOR, msg.sender);
}
if (_queuedAt[callHash] + _delay > block.timestamp) {
// Not enough time has passed, so we'll revert.
revert ForwardingEarly();
}
// Delete the call to prevent replays
delete _queuedAt[callHash];
_forwardAndHalt(callHash);
}
/// @notice Forwards the call to the target and halts the call frame.
function _forwardAndHalt(bytes32 _callHash) internal {
// Forward the call
emit Forwarded(_callHash, msg.data);
(bool success, bytes memory returndata) = TARGET.call(msg.data);
if (success == true) {
assembly {
return(add(returndata, 0x20), mload(returndata))
}
} else {
assembly {
revert(add(returndata, 0x20), mload(returndata))
}
}
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IDelayedVetoable {
error ForwardingEarly();
error Unauthorized(address expected, address actual);
event DelayActivated(uint256 delay);
event Forwarded(bytes32 indexed callHash, bytes data);
event Initiated(bytes32 indexed callHash, bytes data);
event Vetoed(bytes32 indexed callHash, bytes data);
fallback() external;
function delay() external returns (uint256 delay_);
function initiator() external returns (address initiator_);
function queuedAt(bytes32 _callHash) external returns (uint256 queuedAt_);
function target() external returns (address target_);
function version() external view returns (string memory);
function vetoer() external returns (address vetoer_);
function __constructor__(address _vetoer, address _initiator, address _target, uint256 _operatingDelay) external;
}
...@@ -106,14 +106,6 @@ contract Specification_Test is CommonTest { ...@@ -106,14 +106,6 @@ contract Specification_Test is CommonTest {
_addSpec({ _name: "DataAvailabilityChallenge", _sel: IDataAvailabilityChallenge.resolve.selector }); _addSpec({ _name: "DataAvailabilityChallenge", _sel: IDataAvailabilityChallenge.resolve.selector });
_addSpec({ _name: "DataAvailabilityChallenge", _sel: IDataAvailabilityChallenge.unlockBond.selector }); _addSpec({ _name: "DataAvailabilityChallenge", _sel: IDataAvailabilityChallenge.unlockBond.selector });
// DelayedVetoable
_addSpec({ _name: "DelayedVetoable", _sel: _getSel("delay()") });
_addSpec({ _name: "DelayedVetoable", _sel: _getSel("initiator()") });
_addSpec({ _name: "DelayedVetoable", _sel: _getSel("queuedAt(bytes32)") });
_addSpec({ _name: "DelayedVetoable", _sel: _getSel("target()") });
_addSpec({ _name: "DelayedVetoable", _sel: _getSel("version()") });
_addSpec({ _name: "DelayedVetoable", _sel: _getSel("vetoer()") });
// L1CrossDomainMessenger // L1CrossDomainMessenger
_addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("MESSAGE_VERSION()") }); _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("MESSAGE_VERSION()") });
_addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("MIN_GAS_CALLDATA_OVERHEAD()") }); _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("MIN_GAS_CALLDATA_OVERHEAD()") });
......
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