From 03396efca318c14d49edd8decdea24e370cb40da Mon Sep 17 00:00:00 2001 From: Bogdan Kovtun Date: Mon, 28 Oct 2024 03:01:55 +0400 Subject: [PATCH] Move DualGovernanceStateTransitions lib to standalone file --- .../libraries/DualGovernanceStateMachine.sol | 113 +---------------- .../DualGovernanceStateTransitions.sol | 119 ++++++++++++++++++ 2 files changed, 120 insertions(+), 112 deletions(-) create mode 100644 contracts/libraries/DualGovernanceStateTransitions.sol diff --git a/contracts/libraries/DualGovernanceStateMachine.sol b/contracts/libraries/DualGovernanceStateMachine.sol index 5a58879c..dabe5f12 100644 --- a/contracts/libraries/DualGovernanceStateMachine.sol +++ b/contracts/libraries/DualGovernanceStateMachine.sol @@ -5,7 +5,6 @@ import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol"; import {Duration} from "../types/Duration.sol"; -import {PercentD16} from "../types/PercentD16.sol"; import {Timestamp, Timestamps} from "../types/Timestamp.sol"; import {IEscrow} from "../interfaces/IEscrow.sol"; @@ -13,6 +12,7 @@ import {IDualGovernance} from "../interfaces/IDualGovernance.sol"; import {IDualGovernanceConfigProvider} from "../interfaces/IDualGovernanceConfigProvider.sol"; import {DualGovernanceConfig} from "./DualGovernanceConfig.sol"; +import {DualGovernanceStateTransitions} from "./DualGovernanceStateTransitions.sol"; /// @notice Enum describing the state of the Dual Governance State Machine /// @param Unset The initial (uninitialized) state of the Dual Governance State Machine. The state machine cannot @@ -319,114 +319,3 @@ library DualGovernanceStateMachine { emit NewSignallingEscrowDeployed(newSignallingEscrow); } } - -/// @title Dual Governance State Transitions Library -/// @notice Library containing the transitions logic for the Dual Governance system -library DualGovernanceStateTransitions { - using DualGovernanceConfig for DualGovernanceConfig.Context; - - /// @notice Returns the allowed state transition for the Dual Governance State Machine. - /// If no state transition is possible, `currentState` will be equal to `nextState`. - /// @param self The context of the Dual Governance State Machine. - /// @param config The configuration of the Dual Governance State Machine to use for determining - /// state transitions. - /// @return currentState The current state of the Dual Governance State Machine. - /// @return nextState The next state of the Dual Governance State Machine if a transition - /// is possible, otherwise it will be the same as `currentState`. - function getStateTransition( - DualGovernanceStateMachine.Context storage self, - DualGovernanceConfig.Context memory config - ) internal view returns (State currentState, State nextState) { - currentState = self.state; - if (currentState == State.Normal) { - nextState = _fromNormalState(self, config); - } else if (currentState == State.VetoSignalling) { - nextState = _fromVetoSignallingState(self, config); - } else if (currentState == State.VetoSignallingDeactivation) { - nextState = _fromVetoSignallingDeactivationState(self, config); - } else if (currentState == State.VetoCooldown) { - nextState = _fromVetoCooldownState(self, config); - } else if (currentState == State.RageQuit) { - nextState = _fromRageQuitState(self, config); - } else { - assert(false); - } - } - - // --- - // Private Methods - // --- - - function _fromNormalState( - DualGovernanceStateMachine.Context storage self, - DualGovernanceConfig.Context memory config - ) private view returns (State) { - return config.isFirstSealRageQuitSupportCrossed(self.signallingEscrow.getRageQuitSupport()) - ? State.VetoSignalling - : State.Normal; - } - - function _fromVetoSignallingState( - DualGovernanceStateMachine.Context storage self, - DualGovernanceConfig.Context memory config - ) private view returns (State) { - PercentD16 rageQuitSupport = self.signallingEscrow.getRageQuitSupport(); - - if (!config.isVetoSignallingDurationPassed(self.vetoSignallingActivatedAt, rageQuitSupport)) { - return State.VetoSignalling; - } - - if (config.isSecondSealRageQuitSupportCrossed(rageQuitSupport)) { - return State.RageQuit; - } - - return config.isVetoSignallingReactivationDurationPassed( - Timestamps.max(self.vetoSignallingReactivationTime, self.vetoSignallingActivatedAt) - ) ? State.VetoSignallingDeactivation : State.VetoSignalling; - } - - function _fromVetoSignallingDeactivationState( - DualGovernanceStateMachine.Context storage self, - DualGovernanceConfig.Context memory config - ) private view returns (State) { - PercentD16 rageQuitSupport = self.signallingEscrow.getRageQuitSupport(); - - if (!config.isVetoSignallingDurationPassed(self.vetoSignallingActivatedAt, rageQuitSupport)) { - return State.VetoSignalling; - } - - if (config.isSecondSealRageQuitSupportCrossed(rageQuitSupport)) { - return State.RageQuit; - } - - if (config.isVetoSignallingDeactivationMaxDurationPassed(self.enteredAt)) { - return State.VetoCooldown; - } - - return State.VetoSignallingDeactivation; - } - - function _fromVetoCooldownState( - DualGovernanceStateMachine.Context storage self, - DualGovernanceConfig.Context memory config - ) private view returns (State) { - if (!config.isVetoCooldownDurationPassed(self.enteredAt)) { - return State.VetoCooldown; - } - return config.isFirstSealRageQuitSupportCrossed(self.signallingEscrow.getRageQuitSupport()) - ? State.VetoSignalling - : State.Normal; - } - - function _fromRageQuitState( - DualGovernanceStateMachine.Context storage self, - DualGovernanceConfig.Context memory config - ) private view returns (State) { - if (!self.rageQuitEscrow.isRageQuitFinalized()) { - return State.RageQuit; - } - return config.isFirstSealRageQuitSupportCrossed(self.signallingEscrow.getRageQuitSupport()) - ? State.VetoSignalling - : State.VetoCooldown; - } -} diff --git a/contracts/libraries/DualGovernanceStateTransitions.sol b/contracts/libraries/DualGovernanceStateTransitions.sol new file mode 100644 index 00000000..f8a58184 --- /dev/null +++ b/contracts/libraries/DualGovernanceStateTransitions.sol @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +import {PercentD16} from "../types/PercentD16.sol"; +import {Timestamps} from "../types/Timestamp.sol"; + +import {DualGovernanceConfig} from "./DualGovernanceConfig.sol"; +import {State, DualGovernanceStateMachine} from "./DualGovernanceStateMachine.sol"; + +/// @title Dual Governance State Transitions Library +/// @notice Library containing the transitions logic for the Dual Governance system +library DualGovernanceStateTransitions { + using DualGovernanceConfig for DualGovernanceConfig.Context; + + /// @notice Returns the allowed state transition for the Dual Governance State Machine. + /// If no state transition is possible, `currentState` will be equal to `nextState`. + /// @param self The context of the Dual Governance State Machine. + /// @param config The configuration of the Dual Governance State Machine to use for determining + /// state transitions. + /// @return currentState The current state of the Dual Governance State Machine. + /// @return nextState The next state of the Dual Governance State Machine if a transition + /// is possible, otherwise it will be the same as `currentState`. + function getStateTransition( + DualGovernanceStateMachine.Context storage self, + DualGovernanceConfig.Context memory config + ) internal view returns (State currentState, State nextState) { + currentState = self.state; + if (currentState == State.Normal) { + nextState = _fromNormalState(self, config); + } else if (currentState == State.VetoSignalling) { + nextState = _fromVetoSignallingState(self, config); + } else if (currentState == State.VetoSignallingDeactivation) { + nextState = _fromVetoSignallingDeactivationState(self, config); + } else if (currentState == State.VetoCooldown) { + nextState = _fromVetoCooldownState(self, config); + } else if (currentState == State.RageQuit) { + nextState = _fromRageQuitState(self, config); + } else { + assert(false); + } + } + + // --- + // Private Methods + // --- + + function _fromNormalState( + DualGovernanceStateMachine.Context storage self, + DualGovernanceConfig.Context memory config + ) private view returns (State) { + return config.isFirstSealRageQuitSupportCrossed(self.signallingEscrow.getRageQuitSupport()) + ? State.VetoSignalling + : State.Normal; + } + + function _fromVetoSignallingState( + DualGovernanceStateMachine.Context storage self, + DualGovernanceConfig.Context memory config + ) private view returns (State) { + PercentD16 rageQuitSupport = self.signallingEscrow.getRageQuitSupport(); + + if (!config.isVetoSignallingDurationPassed(self.vetoSignallingActivatedAt, rageQuitSupport)) { + return State.VetoSignalling; + } + + if (config.isSecondSealRageQuitSupportCrossed(rageQuitSupport)) { + return State.RageQuit; + } + + return config.isVetoSignallingReactivationDurationPassed( + Timestamps.max(self.vetoSignallingReactivationTime, self.vetoSignallingActivatedAt) + ) ? State.VetoSignallingDeactivation : State.VetoSignalling; + } + + function _fromVetoSignallingDeactivationState( + DualGovernanceStateMachine.Context storage self, + DualGovernanceConfig.Context memory config + ) private view returns (State) { + PercentD16 rageQuitSupport = self.signallingEscrow.getRageQuitSupport(); + + if (!config.isVetoSignallingDurationPassed(self.vetoSignallingActivatedAt, rageQuitSupport)) { + return State.VetoSignalling; + } + + if (config.isSecondSealRageQuitSupportCrossed(rageQuitSupport)) { + return State.RageQuit; + } + + if (config.isVetoSignallingDeactivationMaxDurationPassed(self.enteredAt)) { + return State.VetoCooldown; + } + + return State.VetoSignallingDeactivation; + } + + function _fromVetoCooldownState( + DualGovernanceStateMachine.Context storage self, + DualGovernanceConfig.Context memory config + ) private view returns (State) { + if (!config.isVetoCooldownDurationPassed(self.enteredAt)) { + return State.VetoCooldown; + } + return config.isFirstSealRageQuitSupportCrossed(self.signallingEscrow.getRageQuitSupport()) + ? State.VetoSignalling + : State.Normal; + } + + function _fromRageQuitState( + DualGovernanceStateMachine.Context storage self, + DualGovernanceConfig.Context memory config + ) private view returns (State) { + if (!self.rageQuitEscrow.isRageQuitFinalized()) { + return State.RageQuit; + } + return config.isFirstSealRageQuitSupportCrossed(self.signallingEscrow.getRageQuitSupport()) + ? State.VetoSignalling + : State.VetoCooldown; + } +}