# Control Facet

The Control Facet is the administrative hub of the SYMMIO Diamond. It provides all protocol configuration, role management, entity registration, and parameter tuning functions. Most functions are restricted to specific roles, forming a layered access control hierarchy. The Control Facet does not contain trading or liquidation logic — it configures the parameters that govern those systems.

Changes introduced in 0.8.5:

* **Two-Step Ownership Transfer:** Ownership transfer now requires the new owner to call `acceptOwnership()` to confirm, preventing accidental transfers to incorrect or non-functional addresses. The current owner can also cancel a pending transfer.
* **Role Admin System:** Default admins can now delegate management of specific roles to dedicated addresses via `addRoleAdmin` / `removeRoleAdmin`. Per-role admins can grant and revoke only the role they administer, enabling operational teams to manage their domain without requiring the default admin for every change.
* **Affiliate Fee System:** Fees are now configurable per affiliate, per symbol, and per user, with separate open and close fee rates. A priority-based resolution determines the effective fee. A minimum affiliate fee threshold is enforced.
* **Symbol Types:** Symbols can now be assigned a type, and PartyBs can be whitelisted for specific symbol types, enabling risk isolation.
* **Virtual & Express Providers:** New registration functions for virtual providers (cross-chain virtual deposits/withdrawals) and express providers (instant withdrawals). A provider cannot serve both roles simultaneously.
* **Withdraw System Configuration:** New parameters for the multi-provider withdrawal system including cooldown periods, speed-up whitelists, cancel blackout windows, and max withdrawal parts.
* **Cross PartyB Mode:** A feature flag and per-PartyB toggle for cross-margin mode, where PartyB manages all PartyA positions from a single aggregated balance.
* **Liquidation Insurance Vault:** Configurable cap on liquidator profits per position, with excess directed to an insurance vault.
* **Soft Liquidation Penalty Collector:** Configurable address that receives penalties from soft PartyB liquidations.
* **ADL Toggle:** Per-PartyB setting to enable/disable Auto-Deleveraging.
* **PartyB Bindability:** Per-PartyB toggle controlling whether PartyAs can bind to them for oracle-less trading.
* **Legacy Deallocate Deprecation:** Flag to disable the legacy `deallocate` function, requiring users to use `safeDeallocate` instead.
* **Instant Layer Integration:** A flag and pause control for Instant Layer execution context.

***

### Ownership Management

#### transferOwnership()

Initiates a two-step ownership transfer. Sets a pending owner but does **not** change the active owner. The new owner must call `acceptOwnership()` to complete the transfer. Until then, the original owner retains full control and can call `transferOwnership` again to change the pending owner or effectively cancel.

**Function Signature:**

```solidity
function transferOwnership(address owner) external onlyOwner;
```

**Parameters:**

* `owner`: The address of the pending new owner. Cannot be the zero address.

***

#### cancelOwnershipTransfer()

Cancels a pending ownership transfer, clearing the pending owner.

**Function Signature:**

```solidity
function cancelOwnershipTransfer() external onlyOwner;
```

***

#### acceptOwnership()

Completes the two-step ownership transfer. Must be called by the address set as the pending owner via `transferOwnership()`.

**Function Signature:**

```solidity
function acceptOwnership() external;
```

***

### Role Management

#### setAdmin()

Grants `DEFAULT_ADMIN_ROLE` to a user, giving them full administrative privileges over all roles. Only callable by the Diamond owner.

**Function Signature:**

```solidity
function setAdmin(address user) external onlyOwner;
```

**Parameters:**

* `user`: The address to grant admin privileges to. Cannot be the zero address.

**Events Emitted:**

* `RoleGranted(bytes32 role, address user)`

***

#### grantRole()

Grants a specified role to a user. Callable by any role admin for that role (including `DEFAULT_ADMIN_ROLE` holders). If granting `LIQUIDATOR_ROLE`, the target must have no pending quotes or open positions.

**Function Signature:**

```solidity
function grantRole(address user, bytes32 role) external onlyRoleAdmin(role);
```

**Parameters:**

* `user`: The address to grant the role to. Cannot be the zero address.
* `role`: The bytes32 identifier of the role to grant.

**Events Emitted:**

* `RoleGranted(bytes32 role, address user)`

***

#### revokeRole()

Revokes a specified role from a user.

**Function Signature:**

```solidity
function revokeRole(address user, bytes32 role) external onlyRoleAdmin(role);
```

**Parameters:**

* `user`: The address to revoke the role from.
* `role`: The bytes32 identifier of the role to revoke.

**Events Emitted:**

* `RoleRevoked(bytes32 role, address user)`

***

#### addRoleAdmin()

Appoints an address as admin for a specific role. Role admins can grant and revoke that role to other users, but cannot delegate further — only `DEFAULT_ADMIN_ROLE` holders can call this function.

**Function Signature:**

```solidity
function addRoleAdmin(bytes32 role, address admin) external onlyRole(DEFAULT_ADMIN_ROLE);
```

**Parameters:**

* `role`: The bytes32 identifier of the role to add an admin for.
* `admin`: The address to grant admin privileges for the specified role. Cannot be the zero address.

**Events Emitted:**

* `RoleAdminAdded(bytes32 role, address admin)`

***

#### removeRoleAdmin()

Removes an address from the admins for a specific role.

**Function Signature:**

```solidity
function removeRoleAdmin(bytes32 role, address admin) external onlyRole(DEFAULT_ADMIN_ROLE);
```

**Parameters:**

* `role`: The bytes32 identifier of the role.
* `admin`: The address to remove admin privileges from. Cannot be the zero address.

**Events Emitted:**

* `RoleAdminRemoved(bytes32 role, address admin)`

***

### Entity Registration

#### registerPartyB()

Registers a new PartyB (market maker/hedger) into the system, allowing them to respond to quotes.

**Function Signature:**

```solidity
function registerPartyB(address partyB) external onlyRole(PARTY_B_MANAGER_ROLE);
```

**Parameters:**

* `partyB`: The address to register. Cannot be the zero address or already registered.

**Access:** Requires `PARTY_B_MANAGER_ROLE`.

**Events Emitted:**

* `RegisterPartyB(address partyB)`

***

#### deregisterPartyB()

Deregisters a PartyB, preventing them from responding to new quotes.

**Function Signature:**

```solidity
function deregisterPartyB(address partyB, uint256 index) external onlyRole(PARTY_B_MANAGER_ROLE);
```

**Parameters:**

* `partyB`: The address of the PartyB to deregister.
* `index`: The index of the PartyB in the `partyBList` array (used for gas-efficient swap-and-pop removal).

**Access:** Requires `PARTY_B_MANAGER_ROLE`.

**Events Emitted:**

* `DeregisterPartyB(address partyB, uint256 index)`

***

#### setPartyBMetadata()

Sets metadata (display name, identifying information) for a PartyB.

**Function Signature:**

```solidity
function setPartyBMetadata(address partyB, EntityMetadata memory metadata) external onlyRole(PARTY_B_MANAGER_ROLE);
```

**Parameters:**

* `partyB`: The address of the PartyB.
* `metadata`: The `EntityMetadata` struct containing the PartyB's metadata.

**Access:** Requires `PARTY_B_MANAGER_ROLE`.

**Events Emitted:**

* `SetEntityMetadata(address entity, EntityMetadata metadata)`

***

#### registerAffiliate()

Registers a new affiliate (frontend partner) into the system.

**Function Signature:**

```solidity
function registerAffiliate(address affiliate) external onlyRole(AFFILIATE_MANAGER_ROLE);
```

**Parameters:**

* `affiliate`: The address to register. Must not be already registered.

**Access:** Requires `AFFILIATE_MANAGER_ROLE`.

**Events Emitted:**

* `RegisterAffiliate(address affiliate)`

***

#### deregisterAffiliate()

Deregisters an affiliate from the system.

**Function Signature:**

```solidity
function deregisterAffiliate(address affiliate) external onlyRole(AFFILIATE_MANAGER_ROLE);
```

**Parameters:**

* `affiliate`: The address to deregister. Must be currently registered.

**Access:** Requires `AFFILIATE_MANAGER_ROLE`.

**Events Emitted:**

* `DeregisterAffiliate(address affiliate)`

***

#### setAffiliateMetadata()

Sets metadata for an affiliate.

**Function Signature:**

```solidity
function setAffiliateMetadata(address affiliate, EntityMetadata memory metadata) external onlyRole(AFFILIATE_MANAGER_ROLE);
```

**Parameters:**

* `affiliate`: The address of the affiliate.
* `metadata`: The `EntityMetadata` struct.

**Access:** Requires `AFFILIATE_MANAGER_ROLE`.

**Events Emitted:**

* `SetEntityMetadata(address entity, EntityMetadata metadata)`

***

### Affiliate Fee Configuration

#### setAffiliateFee()

Sets trading fees for a specific affiliate and symbol. Fees are charged when opening and closing positions. Use `symbolId = 0` to set a default fee across all symbols. Callable by the `AFFILIATE_MANAGER_ROLE` or by the affiliate themselves.

Fee resolution priority (highest to lowest): user+symbol specific → user default → affiliate+symbol specific → affiliate default → symbol's `tradingFee`.

**Function Signature:**

```solidity
function setAffiliateFee(
    address affiliate,
    uint256[] calldata symbolIds,
    uint256[] calldata openFees,
    uint256[] calldata closeFees
) external;
```

**Parameters:**

* `affiliate`: The registered affiliate address.
* `symbolIds`: List of symbol IDs (use `0` for default fee).
* `openFees`: List of open fees (in 1e18 precision). Must be >= `minAffiliateFee`.
* `closeFees`: List of close fees (in 1e18 precision). Must be >= `minAffiliateFee`.

**Access:** Requires `AFFILIATE_MANAGER_ROLE` or caller must be the affiliate.

**Events Emitted:**

* `SetAffiliateFee(address affiliate, uint256 symbolId, uint256 oldOpenFee, uint256 newOpenFee, uint256 oldCloseFee, uint256 newCloseFee)` — per symbol

***

#### setAffiliateFeeForUser()

Sets custom trading fees for specific users under an affiliate, allowing preferential rates for individual traders.

**Function Signature:**

```solidity
function setAffiliateFeeForUser(
    address affiliate,
    address[] calldata users,
    uint256[] calldata symbolIds,
    uint256[] calldata openFees,
    uint256[] calldata closeFees
) external;
```

**Parameters:**

* `affiliate`: The registered affiliate address.
* `users`: List of user addresses.
* `symbolIds`: List of symbol IDs (use `0` for default fee).
* `openFees`: List of open fees (in 1e18 precision). Must be >= `minAffiliateFee`.
* `closeFees`: List of close fees (in 1e18 precision). Must be >= `minAffiliateFee`.

**Access:** Requires `AFFILIATE_MANAGER_ROLE` or caller must be the affiliate.

**Events Emitted:**

* `SetAffiliateFeeForUser(address affiliate, address user, uint256 symbolId, uint256 oldOpenFee, uint256 newOpenFee, uint256 oldCloseFee, uint256 newCloseFee)` — per user

***

#### setFeeCollector()

Sets the address where trading fees collected for a specific affiliate will be sent.

**Function Signature:**

```solidity
function setFeeCollector(address affiliate, address feeCollector) external onlyRole(AFFILIATE_MANAGER_ROLE);
```

**Parameters:**

* `affiliate`: The registered affiliate address.
* `feeCollector`: The address that will receive collected fees. Cannot be the zero address.

**Access:** Requires `AFFILIATE_MANAGER_ROLE`.

**Events Emitted:**

* `SetFeeCollector(address affiliate, address oldCollector, address newCollector)`

***

#### setDefaultFeeCollector()

Sets the fallback address for fee collection when an affiliate has no specific fee collector configured.

**Function Signature:**

```solidity
function setDefaultFeeCollector(address feeCollector) external onlyRole(FEE_ADMIN_ROLE);
```

**Parameters:**

* `feeCollector`: The fallback fee collector address.

**Access:** Requires `FEE_ADMIN_ROLE`.

**Events Emitted:**

* `SetDefaultFeeCollector(address oldCollector, address newCollector)`

***

#### setMinAffiliateFee()

Sets the minimum fee that affiliates must charge. Prevents affiliates from setting fees below protocol requirements.

**Function Signature:**

```solidity
function setMinAffiliateFee(uint256 minAffiliateFee) external onlyRole(FEE_ADMIN_ROLE);
```

**Parameters:**

* `minAffiliateFee`: The minimum fee percentage (in 1e18 precision).

**Access:** Requires `FEE_ADMIN_ROLE`.

**Events Emitted:**

* `SetMinAffiliateFee(uint256 oldFee, uint256 newFee)`

***

### Muon Oracle Configuration

#### setMuonConfig()

Sets the validity duration for Muon oracle signatures. Signatures older than these values will be rejected.

**Function Signature:**

```solidity
function setMuonConfig(uint256 upnlValidTime, uint256 priceValidTime) external onlyRole(MUON_SETTER_ROLE);
```

**Parameters:**

* `upnlValidTime`: Duration in seconds that UPNL signatures remain valid.
* `priceValidTime`: Duration in seconds that price signatures remain valid.

**Access:** Requires `MUON_SETTER_ROLE`.

**Events Emitted:**

* `SetMuonConfig(uint256 upnlValidTime, uint256 priceValidTime)`

***

#### setMuonIds()

Sets the Muon application ID used to identify this protocol in the Muon oracle network.

**Function Signature:**

```solidity
function setMuonIds(uint256 muonAppId) external onlyRole(MUON_SETTER_ROLE);
```

**Parameters:**

* `muonAppId`: The unique identifier for this application in the Muon network.

**Access:** Requires `MUON_SETTER_ROLE`.

**Events Emitted:**

* `SetMuonIds(uint256 muonAppId)`

***

#### setSignatureVerifierAddress()

Sets the external `MuonSignatureVerifier` contract address used for verifying Muon Schnorr signatures. This contract supports multiple TSS public keys and multiple gateway signers, enabling zero-downtime key rotation.

**Function Signature:**

```solidity
function setSignatureVerifierAddress(address signatureVerifier) external onlyRole(DEFAULT_ADMIN_ROLE);
```

**Parameters:**

* `signatureVerifier`: The address of the signature verifier contract.

**Access:** Requires `DEFAULT_ADMIN_ROLE`.

**Events Emitted:**

* `SetSignatureVerifierAddress(address signatureVerifier)`

***

#### setSigner()

Sets the trusted signer address whose signatures are accepted for protocol operations (e.g., off-chain signature verification for delegated calls).

**Function Signature:**

```solidity
function setSigner(address signer) external onlyRoleAllowProxy(SIGNER_ADMIN_ROLE);
```

**Parameters:**

* `signer`: The address of the trusted signer.

**Access:** Requires `SIGNER_ADMIN_ROLE` (allows proxy calls).

**Events Emitted:**

* `SignerSet(address signer)`

***

### Protocol Parameters

#### setCollateral()

Sets the ERC20 token used as collateral. Can only be changed when the contract holds no collateral. The token must have 18 or fewer decimals.

**Function Signature:**

```solidity
function setCollateral(address collateral) external onlyRole(DEFAULT_ADMIN_ROLE);
```

**Parameters:**

* `collateral`: The address of the ERC20 token. Cannot be the zero address.

**Access:** Requires `DEFAULT_ADMIN_ROLE`.

**Events Emitted:**

* `SetCollateral(address collateral)`

***

#### setPendingQuotesValidLength()

Sets the maximum number of pending (unaccepted) quotes a PartyA can have at once.

**Function Signature:**

```solidity
function setPendingQuotesValidLength(uint256 pendingQuotesValidLength) external onlyRole(PROTOCOL_CONFIG_ROLE);
```

**Parameters:**

* `pendingQuotesValidLength`: Maximum number of pending quotes per user.

**Access:** Requires `PROTOCOL_CONFIG_ROLE`.

**Events Emitted:**

* `SetPendingQuotesValidLength(uint256 oldValue, uint256 newValue)`

***

#### setBalanceLimitPerUser()

Sets the maximum collateral balance a single user can hold in the protocol.

**Function Signature:**

```solidity
function setBalanceLimitPerUser(uint256 balanceLimitPerUser) external onlyRole(PROTOCOL_CONFIG_ROLE);
```

**Parameters:**

* `balanceLimitPerUser`: Maximum collateral amount (in collateral token units).

**Access:** Requires `PROTOCOL_CONFIG_ROLE`.

**Events Emitted:**

* `SetBalanceLimitPerUser(uint256 balanceLimitPerUser)`

***

#### setMaxPartyAConnectionLimit()

Sets the maximum number of PartyB connections a single PartyA can have simultaneously.

**Function Signature:**

```solidity
function setMaxPartyAConnectionLimit(uint256 maxLimit) external onlyRole(PROTOCOL_CONFIG_ROLE);
```

**Parameters:**

* `maxLimit`: Maximum number of PartyBs a PartyA can be connected to. Must be > 0.

**Access:** Requires `PROTOCOL_CONFIG_ROLE`.

**Events Emitted:**

* `SetMaxPartyAConnectionLimit(uint256 maxLimit)`

***

#### setLiquidatorShare()

Sets the percentage of remaining liquidation fee awarded to the liquidator in PartyB liquidations.

**Function Signature:**

```solidity
function setLiquidatorShare(uint256 liquidatorShare) external onlyRole(PROTOCOL_CONFIG_ROLE);
```

**Parameters:**

* `liquidatorShare`: Percentage (in 1e18 precision) of remaining LF (after deficit coverage) awarded to the liquidator.

**Access:** Requires `PROTOCOL_CONFIG_ROLE`.

**Events Emitted:**

* `SetLiquidatorShare(uint256 oldValue, uint256 newValue)`

***

#### setForceClosePricePenalty()

Sets the price penalty applied against PartyB when a position is force closed, compensating PartyA for delays.

**Function Signature:**

```solidity
function setForceClosePricePenalty(uint256 forceClosePricePenalty) external onlyRole(PROTOCOL_CONFIG_ROLE);
```

**Parameters:**

* `forceClosePricePenalty`: Penalty percentage (in 1e18 precision) applied to the closing price.

**Access:** Requires `PROTOCOL_CONFIG_ROLE`.

**Events Emitted:**

* `SetForceClosePricePenalty(uint256 oldValue, uint256 newValue)`

***

#### setForceCloseGapRatio()

Sets the minimum oracle price gap ratio from requested price during force close for a specific symbol.

**Function Signature:**

```solidity
function setForceCloseGapRatio(uint256 symbolId, uint256 forceCloseGapRatio) external onlyRole(FORCE_CLOSE_GAP_RATIO_ADMIN_ROLE);
```

**Parameters:**

* `symbolId`: The ID of the trading symbol.
* `forceCloseGapRatio`: Minimum price gap percentage (in 1e18 precision).

**Access:** Requires `FORCE_CLOSE_GAP_RATIO_ADMIN_ROLE`.

**Events Emitted:**

* `SetForceCloseGapRatio(uint256 symbolId, uint256 oldValue, uint256 newValue)`

***

### Cooldown Configuration

#### setDeallocateDebounceTime()

Sets the minimum time between consecutive deallocations for a single user.

**Function Signature:**

```solidity
function setDeallocateDebounceTime(uint256 deallocateDebounceTime) external onlyRole(COOLDOWN_ADMIN_ROLE);
```

**Parameters:**

* `deallocateDebounceTime`: Minimum time in seconds between deallocations.

**Access:** Requires `COOLDOWN_ADMIN_ROLE`.

**Events Emitted:**

* `SetDeallocateDebounceTime(uint256 oldValue, uint256 newValue)`

***

#### setDeallocateCooldown()

Sets the waiting period after deallocation before funds can be withdrawn. This and `setWithdrawCooldownPeriod` share the same underlying storage field (`withdrawCooldownPeriod`).

**Function Signature:**

```solidity
function setDeallocateCooldown(uint256 deallocateCooldown) external onlyRole(COOLDOWN_ADMIN_ROLE);
```

**Parameters:**

* `deallocateCooldown`: Cooldown duration in seconds.

**Access:** Requires `COOLDOWN_ADMIN_ROLE`.

**Events Emitted:**

* `SetWithdrawCooldownPeriod(uint256 oldValue, uint256 newValue)`
* `SetDeallocateCooldown(uint256 oldValue, uint256 newValue)`

***

#### setWithdrawCooldownPeriod()

Sets the waiting period before a withdrawal can be finalized. Shares the same storage field as `setDeallocateCooldown`.

**Function Signature:**

```solidity
function setWithdrawCooldownPeriod(uint256 _withdrawCooldownPeriod) external onlyRole(COOLDOWN_ADMIN_ROLE);
```

**Parameters:**

* `_withdrawCooldownPeriod`: Cooldown duration in seconds.

**Access:** Requires `COOLDOWN_ADMIN_ROLE`.

**Events Emitted:**

* `SetWithdrawCooldownPeriod(uint256 oldValue, uint256 newValue)`
* `SetDeallocateCooldown(uint256 oldValue, uint256 newValue)`

***

#### setForceCancelCooldown()

Sets the waiting period before PartyA can force cancel a pending quote that PartyB hasn't responded to.

**Function Signature:**

```solidity
function setForceCancelCooldown(uint256 forceCancelCooldown) external onlyRole(COOLDOWN_ADMIN_ROLE);
```

**Parameters:**

* `forceCancelCooldown`: Time in seconds a quote must remain pending before force cancellation.

**Access:** Requires `COOLDOWN_ADMIN_ROLE`.

**Events Emitted:**

* `SetForceCancelCooldown(uint256 oldValue, uint256 newValue)`

***

#### setForceCloseCooldowns()

Sets the two-stage cooldown periods for force closing positions when PartyB is unresponsive.

**Function Signature:**

```solidity
function setForceCloseCooldowns(uint256 forceCloseFirstCooldown, uint256 forceCloseSecondCooldown) external onlyRole(COOLDOWN_ADMIN_ROLE);
```

**Parameters:**

* `forceCloseFirstCooldown`: Initial waiting period in seconds before the first force close attempt.
* `forceCloseSecondCooldown`: Additional waiting period in seconds before final force close at market price.

**Access:** Requires `COOLDOWN_ADMIN_ROLE`.

**Events Emitted:**

* `SetForceCloseCooldowns(uint256 oldFirst, uint256 newFirst, uint256 oldSecond, uint256 newSecond)`

***

#### setForceCloseMinSigPeriod()

Sets the minimum time window during which price signatures must be collected for a valid force close.

**Function Signature:**

```solidity
function setForceCloseMinSigPeriod(uint256 forceCloseMinSigPeriod) external onlyRole(COOLDOWN_ADMIN_ROLE);
```

**Parameters:**

* `forceCloseMinSigPeriod`: Minimum duration in seconds that price signatures must span.

**Access:** Requires `COOLDOWN_ADMIN_ROLE`.

**Events Emitted:**

* `SetForceCloseMinSigPeriod(uint256 oldValue, uint256 newValue)`

***

#### setForceCancelCloseCooldown()

Sets the waiting period before PartyA can force cancel a close request that PartyB hasn't fulfilled.

**Function Signature:**

```solidity
function setForceCancelCloseCooldown(uint256 forceCancelCloseCooldown) external onlyRole(COOLDOWN_ADMIN_ROLE);
```

**Parameters:**

* `forceCancelCloseCooldown`: Time in seconds a close request must remain pending before force cancellation.

**Access:** Requires `COOLDOWN_ADMIN_ROLE`.

**Events Emitted:**

* `SetForceCancelCloseCooldown(uint256 oldValue, uint256 newValue)`

***

#### setSettlementCooldown()

Sets the minimum time between UPNL settlements. PartyB is exempt from this cooldown.

**Function Signature:**

```solidity
function setSettlementCooldown(uint256 settlementCooldown) external onlyRole(COOLDOWN_ADMIN_ROLE);
```

**Parameters:**

* `settlementCooldown`: Minimum time in seconds between consecutive settlements.

**Access:** Requires `COOLDOWN_ADMIN_ROLE`.

**Events Emitted:**

* `SetSettlementCooldown(uint256 oldValue, uint256 newValue)`

***

#### setUnbindCooldown()

Sets the waiting period before PartyA can complete an unbind from PartyB after initiating the unbind process.

**Function Signature:**

```solidity
function setUnbindCooldown(uint256 unbindCooldown) external onlyRole(COOLDOWN_ADMIN_ROLE);
```

**Parameters:**

* `unbindCooldown`: Time in seconds PartyA must wait before completing the unbind.

**Access:** Requires `COOLDOWN_ADMIN_ROLE`.

**Events Emitted:**

* `SetUnbindCooldown(uint256 oldValue, uint256 newValue)`

***

#### setLiquidationTimeout()

Sets the maximum time allowed for a liquidation process to complete.

**Function Signature:**

```solidity
function setLiquidationTimeout(uint256 liquidationTimeout) external onlyRole(COOLDOWN_ADMIN_ROLE);
```

**Parameters:**

* `liquidationTimeout`: Maximum duration in seconds.

**Access:** Requires `COOLDOWN_ADMIN_ROLE`.

**Events Emitted:**

* `SetLiquidationTimeout(uint256 oldValue, uint256 newValue)`

***

### Withdraw System Configuration

#### setMaxWithdrawParts()

Sets the maximum number of receiver parts a single withdrawal can be split into.

**Function Signature:**

```solidity
function setMaxWithdrawParts(uint256 _maxWithdrawParts) external onlyRole(PROTOCOL_CONFIG_ROLE);
```

**Parameters:**

* `_maxWithdrawParts`: Maximum number of parts.

**Access:** Requires `PROTOCOL_CONFIG_ROLE`.

**Events Emitted:**

* `SetMaxWithdrawParts(uint256 maxWithdrawParts)`

***

#### setMinWithdrawCooldown()

Sets the absolute minimum cooldown for withdrawals that cannot be bypassed even by speed-up users.

**Function Signature:**

```solidity
function setMinWithdrawCooldown(uint256 cooldown) external onlyRole(COOLDOWN_ADMIN_ROLE);
```

**Parameters:**

* `cooldown`: Minimum cooldown duration in seconds.

**Access:** Requires `COOLDOWN_ADMIN_ROLE`.

**Events Emitted:**

* `SetMinWithdrawCooldown(uint256 oldValue, uint256 newValue)`

***

#### setPureVirtualCancelBlackout()

Sets the blackout period during which pure virtual withdrawals cannot be cancelled. This window occurs before cooldown expiry, giving virtual providers certainty that accepted requests will complete.

**Function Signature:**

```solidity
function setPureVirtualCancelBlackout(uint256 blackout) external onlyRole(COOLDOWN_ADMIN_ROLE);
```

**Parameters:**

* `blackout`: Number of seconds before cooldown end during which cancellation is blocked.

**Access:** Requires `COOLDOWN_ADMIN_ROLE`.

**Events Emitted:**

* `SetPureVirtualCancelBlackout(uint256 oldValue, uint256 newValue)`

***

#### setSpeedUpUser()

Adds or removes a user from the speed-up whitelist, allowing them to request withdrawals with reduced cooldown periods.

**Function Signature:**

```solidity
function setSpeedUpUser(address user, bool speedUp) external onlyRole(WITHDRAW_SPEED_UP_ROLE);
```

**Parameters:**

* `user`: The user address.
* `speedUp`: `true` to enable speed-up, `false` to disable.

**Access:** Requires `WITHDRAW_SPEED_UP_ROLE`.

**Events Emitted:**

* `SetSpeedUpUser(address user, bool speedUp)`

***

### Provider Registration

#### registerVirtualProvider()

Registers a virtual provider that can facilitate virtual deposits and cross-chain withdrawals without immediate token transfers. A provider cannot be registered as both virtual and express simultaneously.

**Function Signature:**

```solidity
function registerVirtualProvider(address provider) external onlyRole(PROVIDER_ADMIN_ROLE);
```

**Parameters:**

* `provider`: The address to authorize as a virtual provider.

**Access:** Requires `PROVIDER_ADMIN_ROLE`.

**Events Emitted:**

* `RegisterVirtualProvider(address provider)`

***

#### unregisterVirtualProvider()

Removes a virtual provider's authorization.

**Function Signature:**

```solidity
function unregisterVirtualProvider(address provider) external onlyRole(PROVIDER_ADMIN_ROLE);
```

**Parameters:**

* `provider`: The address to remove.

**Access:** Requires `PROVIDER_ADMIN_ROLE`.

**Events Emitted:**

* `UnregisterVirtualProvider(address provider)`

***

#### registerExpressProvider()

Registers an express provider that can facilitate instant withdrawals by fronting funds to users. A provider cannot be registered as both express and virtual simultaneously.

**Function Signature:**

```solidity
function registerExpressProvider(address provider) external onlyRole(PROVIDER_ADMIN_ROLE);
```

**Parameters:**

* `provider`: The address to authorize as an express provider.

**Access:** Requires `PROVIDER_ADMIN_ROLE`.

**Events Emitted:**

* `RegisterExpressProvider(address provider)`

***

#### unregisterExpressProvider()

Removes an express provider's authorization.

**Function Signature:**

```solidity
function unregisterExpressProvider(address provider) external onlyRole(PROVIDER_ADMIN_ROLE);
```

**Parameters:**

* `provider`: The address to remove.

**Access:** Requires `PROVIDER_ADMIN_ROLE`.

**Events Emitted:**

* `UnregisterExpressProvider(address provider)`

***

### Bridge Management

#### addBridge()

Registers a bridge contract, allowing it to receive transfers via the Bridge Facet.

**Function Signature:**

```solidity
function addBridge(address bridge) external onlyRole(BRIDGE_MANAGER_ROLE);
```

**Parameters:**

* `bridge`: The bridge contract address. Cannot be the zero address.

**Access:** Requires `BRIDGE_MANAGER_ROLE`.

**Events Emitted:**

* `AddBridge(address bridge)`

***

#### removeBridge()

Deauthorizes a bridge contract.

**Function Signature:**

```solidity
function removeBridge(address bridge) external onlyRole(BRIDGE_MANAGER_ROLE);
```

**Parameters:**

* `bridge`: The bridge contract address.

**Access:** Requires `BRIDGE_MANAGER_ROLE`.

**Events Emitted:**

* `RemoveBridge(address bridge)`

***

### External Transfer & Hook Configuration

#### addRelayerForExternalTransferTarget()

Authorizes a relayer to facilitate external transfers to a specific target (another Symmio diamond or trusted contract).

**Function Signature:**

```solidity
function addRelayerForExternalTransferTarget(address target, address relayer) external onlyRole(INTEGRATION_ADMIN_ROLE);
```

**Parameters:**

* `target`: The external transfer destination address. Cannot be the zero address.
* `relayer`: The address authorized to relay transfers to the target.

**Access:** Requires `INTEGRATION_ADMIN_ROLE`.

**Events Emitted:**

* `AddRelayerForExternalTransferTarget(address target, address relayer)`

***

#### removeRelayerForExternalTransferTarget()

Removes the authorized relayer for an external transfer target.

**Function Signature:**

```solidity
function removeRelayerForExternalTransferTarget(address target) external onlyRole(INTEGRATION_ADMIN_ROLE);
```

**Parameters:**

* `target`: The target address. Cannot be the zero address.

**Access:** Requires `INTEGRATION_ADMIN_ROLE`.

**Events Emitted:**

* `RemoveRelayerForExternalTransferTarget(address target)`

***

#### registerHook()

Registers a hook contract for an affiliate that gets called during specific protocol events (e.g., quote creation, position opening).

**Function Signature:**

```solidity
function registerHook(address affiliate, address hook) external onlyRole(INTEGRATION_ADMIN_ROLE);
```

**Parameters:**

* `affiliate`: The affiliate to register the hook for.
* `hook`: The hook contract address (set to `address(0)` to remove).

**Access:** Requires `INTEGRATION_ADMIN_ROLE`.

**Events Emitted:**

* `RegisterHook(address affiliate, address hook)`

***

### Liquidation & Insurance Configuration

#### setLiquidationInsuranceVaultParams()

Configures the liquidation insurance vault, which caps liquidator profits per position and redirects excess to a vault address. The cap is calculated as `maxLiquidationProfit * positionCount` during PartyA NORMAL liquidations. Excess is credited to the vault's balance.

**Function Signature:**

```solidity
function setLiquidationInsuranceVaultParams(address insuranceVault, uint256 maxLiquidationProfit) external onlyRole(FEE_ADMIN_ROLE);
```

**Parameters:**

* `insuranceVault`: Address that receives excess liquidation fees. Cannot be the zero address.
* `maxLiquidationProfit`: Maximum profit (in 18-decimal precision) a liquidator can earn per position.

**Access:** Requires `FEE_ADMIN_ROLE`.

**Events Emitted:**

* `SetLiquidationInsuranceVaultParams(address insuranceVault, uint256 maxLiquidationProfit)`

***

#### setSoftLiquidationPenaltyCollector()

Sets the address that receives penalties from soft PartyB liquidations.

**Function Signature:**

```solidity
function setSoftLiquidationPenaltyCollector(address softLiquidationPenaltyCollector) external onlyRole(FEE_ADMIN_ROLE);
```

**Parameters:**

* `softLiquidationPenaltyCollector`: The recipient address. Cannot be the zero address.

**Access:** Requires `FEE_ADMIN_ROLE`.

**Events Emitted:**

* `SetSoftLiquidationPenaltyCollector(address softLiquidationPenaltyCollector)`

***

#### setInvalidBridgedAmountsPool()

Sets the address where invalid or failed bridge transaction amounts are collected.

**Function Signature:**

```solidity
function setInvalidBridgedAmountsPool(address pool) external onlyRole(FEE_ADMIN_ROLE);
```

**Parameters:**

* `pool`: The pool address. Cannot be the zero address.

**Access:** Requires `FEE_ADMIN_ROLE`.

**Events Emitted:**

* `SetInvalidBridgedAmountsPool(address oldPool, address newPool)`

***

### Feature Flags & PartyB Configuration

#### setCrossPartyBModeActivated()

Enables or disables the cross PartyB feature globally. This is a prerequisite for `setCrossPartyB`.

**Function Signature:**

```solidity
function setCrossPartyBModeActivated(bool activated) external onlyRole(MIGRATION_ROLE);
```

**Parameters:**

* `activated`: `true` to enable, `false` to disable.

**Access:** Requires `MIGRATION_ROLE`.

**Events Emitted:**

* `SetCrossPartyBModeActivated(bool oldValue, bool newValue)`

***

#### setCrossPartyB()

Enables or disables cross PartyB mode for a specific PartyB. In cross mode, PartyB manages all PartyA positions from a single aggregated balance instead of per-PartyA isolated allocations. Should be called after migrating locked values using `MigrationFacet.migrateCrossLockedValues`.

**Function Signature:**

```solidity
function setCrossPartyB(address partyB, bool enabled) external onlyRole(MIGRATION_ROLE);
```

**Parameters:**

* `partyB`: The address of the PartyB. Must be a registered PartyB.
* `enabled`: `true` to enable cross mode, `false` to disable.

**Access:** Requires `MIGRATION_ROLE`. Cross PartyB mode must be globally activated.

**Events Emitted:**

* `SetCrossPartyB(address partyB, bool enabled)`

***

#### setLegacyDeallocateDeprecated()

Enables or disables the legacy `deallocate` function. When deprecated, users must use `safeDeallocate` which accounts for off-chain pending operations.

**Function Signature:**

```solidity
function setLegacyDeallocateDeprecated(bool deprecated) external onlyRole(PROTOCOL_CONFIG_ROLE);
```

**Parameters:**

* `deprecated`: `true` to require `safeDeallocate`, `false` to allow legacy `deallocate`.

**Access:** Requires `PROTOCOL_CONFIG_ROLE`.

**Events Emitted:**

* `SetLegacyDeallocateDeprecated(bool oldValue, bool newValue)`

***

#### setADLEnabled()

Enables or disables Auto-Deleveraging (ADL) for a PartyB. When enabled, PartyB can force-close positions to reduce risk exposure via `adlClose`. ADL requires PartyB to have deposited pledge collateral.

**Function Signature:**

```solidity
function setADLEnabled(address partyB, bool enabled) external onlyRole(PARTY_B_MANAGER_ROLE);
```

**Parameters:**

* `partyB`: The address of the PartyB.
* `enabled`: `true` to enable ADL, `false` to disable.

**Access:** Requires `PARTY_B_MANAGER_ROLE`.

**Events Emitted:**

* `SetADLEnabled(address partyB, bool enabled)`

***

#### setPartyBBindable()

Controls whether PartyAs can bind to a specific PartyB for exclusive oracle-less trading relationships.

**Function Signature:**

```solidity
function setPartyBBindable(address partyB, bool bindable) external onlyRole(PARTY_B_MANAGER_ROLE);
```

**Parameters:**

* `partyB`: The address of the PartyB. Must be a registered PartyB.
* `bindable`: `true` to allow binding, `false` to disable.

**Access:** Requires `PARTY_B_MANAGER_ROLE`.

**Events Emitted:**

* `SetPartyBBindable(address partyB, bool bindable)`

***

### Instant Layer

#### setCallFromInstantLayer()

Sets the flag indicating whether the current operation is being executed via the Instant Layer. The Instant Layer sets this to `true` before execution and must reset it to `false` afterward.

**Function Signature:**

```solidity
function setCallFromInstantLayer(bool _callFromInstantLayer) external onlyRole(INSTANT_LAYER_ROLE);
```

**Parameters:**

* `_callFromInstantLayer`: `true` when entering Instant Layer execution, `false` when exiting.

**Access:** Requires `INSTANT_LAYER_ROLE`. Reverts if the Instant Layer is paused when setting to `true`.
