Enhancing The Code Structure

For each facet, we added an interface and provided documentation for every method, explaining its parameters and offering a brief overview of its usage.

Add Utility View Functions

function getPositionsFilteredByPartyB(address partyB, uint256 start, uint256 size) external view returns (Quote[] memory)

function getOpenPositionsFilteredByPartyB(address partyB, uint256 start, uint256 size) external view returns (Quote[] memory)

function getActivePositionsFilteredByPartyB(address partyB, uint256 start, uint256 size) external view returns (Quote[] memory)

function getQuotesWithBitmap(Bitmap calldata bitmap, uint256 gasNeededForReturn) external view returns (Quote[] memory quotes)

Add BalanceChange event

To facilitate the tracking of user balances for partyB or anyone monitoring the Symmio contracts, we have added an event called BalanceChanged that is emitted every time a user's allocated balance changes. The reason for the change can be accessed through the type field of this event.

enum BalanceChangeType {
ALLOCATE,
DEALLOCATE,
PLATFORM_FEE_IN,
PLATFORM_FEE_OUT,
REALIZED_PNL_IN,
REALIZED_PNL_OUT,
CVA_IN,
CVA_OUT,
LF_IN,
LF_OUT
}

event BalanceChangePartyA(address indexed partyA, uint256 amount, BalanceChangeType _type);

event BalanceChangePartyB(address indexed partyB, address indexed partyA, uint256 amount, BalanceChangeType _type);

Make forceCloseGapRatio per symbol

Different symbols with different volatility need different gap ratios for forceClose.

Updated methods:

// From
function setForceCloseGapRatio(uint256 forceCloseGapRatio) external onlyRole(LibAccessibility.SETTER_ROLE)
// To
function setForceCloseGapRatio(uint256 symbolId, uint256 forceCloseGapRatio) external onlyRole(LibAccessibility.SETTER_ROLE)

// From
function forceCloseGapRatio() external view returns (uint256)
// To
function forceCloseGapRatio(uint256 symbolId) external view returns (uint256)

Allow Deferred liquidation

Before this update, there was a variable called upnlValidTime in the Muon configuration that prevented the liquidator from liquidating a user after a certain amount of time, such as 5 minutes. However, if the user hasn’t done anything to increase their nonce, we should allow the liquidator to liquidate the user who was liquidated at a certain block. This feature also required the Muon app to provide signatures for a specific block requested by the liquidator. Therefore, the LiquidationSig struct has changed as follows:

// From
struct LiquidationSig {
bytes reqId;
uint256 timestamp;
bytes liquidationId;
int256 upnl;
int256 totalUnrealizedLoss;
uint256[] symbolIds;
uint256[] prices;
bytes gatewaySignature;
SchnorrSign sigs;
}

// To
struct LiquidationSig {
bytes reqId;
uint256 timestamp; // Timestamp when the liquidation signature was created
uint256 liquidationBlockNumber; // Block number at which the user became insolvent
uint256 liquidationTimestamp; // Timestamp when the user became insolvent
uint256 liquidationAllocatedBalance; // User's allocated balance at the time of insolvency
bytes liquidationId;
int256 upnl; // User's unrealized profit and loss at the time of insolvency
int256 totalUnrealizedLoss; // Total unrealized loss of the user at the time of insolvency
uint256[] symbolIds;
uint256[] prices;
bytes gatewaySignature
SchnorrSign sigs;
}

Add InternalTransfer method

This method allows a user to send their deposits to another user’s allocated balance. The receiver address cannot be a partyB and also should not be in a liquidated state. With this method users can transfer funds between their accounts without having to wait for deallocateCooldown.

function internalTransfer(address user, uint256 amount) internal {
    AccountStorage.Layout storage accountLayout = AccountStorage.layout();
    require(
        accountLayout.allocatedBalances[user] + amount <= GlobalAppStorage.layout().balanceLimitPerUser,
        "AccountFacet: Allocated balance limit reached"
    );
    require(accountLayout.balances[msg.sender] >= amount, "AccountFacet: Insufficient balance");
    accountLayout.balances[msg.sender] -= amount;
    accountLayout.allocatedBalances[user] += amount;
}

Symmio can pause internal transfers when needed

function pauseInternalTransfer() external onlyRole(LibAccessibility.PAUSER_R LE);
function unpauseInternalTransfer() external onlyRole(LibAccessibility.UNPAUSER_ROLE);