Safety Module Raises
Triggering a Safety Module
Assets in a Safety Module can be tapped in the event that any of the Safety Module's configured controllers are used to trigger it. To trigger a Safety Module, SafetyModule.trigger(triggerEventId_) can be called permissionlessly with a controller that the Safety Module has been configured to use (see Create a Controller).
/// @notice Triggers the SafetyModule by referencing one of the controllers configured for this SafetyModule.
/// @param triggerEventId_ The trigger event ID to reference when triggering the SafetyModule.
/// @param validityDuration_ The duration of the trigger event validity. This will be capped by the SafetyModule's
/// default `triggerEventValidityDuration` delay.
function trigger(bytes32 triggerEventId_, uint256 validityDuration_) external;Each controller can trigger a SafetyModule an unlimited number of times, given that each triggerEventId is unique.
At a high-level, when SafetyModule.trigger(triggerEventId_, uint256 validityDuration_) is called successfully with a valid controller and a unique triggerEventId:
Protocol fees are dripped.
The trigger event state for the controller and triggerEventId is set to PENDING_RAISE
triggerEventData[controller_][triggerEventId_].triggerEventState = TriggerEventState.PENDING_RAISEsafetyModule.numPendingRaisesandcontrollerData[controller_].numPendingRaisesis incremented by 1. An invariant of the protocol is that the Safety Module is triggered whileSafetyModule.numPendingRaises > 0 && SafetyModule.safetyModuleState != SafetyModuleState.PAUSED(see Safety Module States).If the safety module is part of a shared safety module,
SharedSafetyModule.propagateTrigger(controller_,triggerEventId_, expiresAt_)is called to initiate trigger events across all sibling safety modules.event Triggered(controller_, triggerEventId_, expiresAt_)is emittedSafetyModule.safetyModuleState()is set to triggered if the Safety Module is not paused.
Safety Module State Change
When SafetyModule.trigger is called with a valid controller and unique triggerEventId, the Safety Module's state becomes triggered if it is currently active and not paused (see Safety Module States).
Raising Safety Module Assets
Assets in a Safety Module can be raised either by an authorized controller or by the parent Shared Safety Module, provided the Safety Module is in the TRIGGERED state (SafetyModule.safetyModuleState() == TRIGGERED).
To raise assets, controllers can call SafetyModule.requestRaise():
While Shared Safety modules can call sharedSafetyModuleRaise()
At a high-level, when SafetyModule.requestRaise is called by a valid controller
SafetyModule.numPendingRaises()andcontrollerData[controller_].numPendingRaisesare decremented by 1.If the safety module is part of a shared safety module,
SharedSafetyModule.requestRaise(triggerEventId_, receiver_, assetNeeds_, raiseStrategy_, controller_, data_)is called to initiate raise events across all sibling safety modules.Assets are tapped from each reserve pool according to the
raises_specified, and transferred toreceiver_.If any of the raise amounts exceeds reserve pool deposit amounts, the transaction reverts (see Define Safety Module Configuration).
Assets pending withdrawal are also tapped (see Safety Module Redemptions / Withdrawals).
Internal asset accounting is updated for each reserve pool and underlying asset.
SafetyModule.reservePool(reservePoolId_).depositAmountis decreased by the amount tapped from the reserve pool.SafetyModule.assetPools(asset_).amountis decreased by the amount of the underlying asset tapped.
If
SafetyModule.numPendingRaises == 0,SafetyModule.safetyModuleState()is set to active.For each reserve pool that is tapped,
event ReservePoolTapped( ISafetyModuleController originController_, bytes32 triggerEventId_, address receiver_, uint8 reservePoolId_. uint256 raiseAmount);is emitted.event SafetyModuleTapped(ISafetyModuleController originController_, bytes32 triggerEventId_, address receiver_)is emitted.
Last updated