LibMuon (0.8.4)

LibMuon Library (0.8.4)

The LibMuon library provides essential cryptographic functions for the SYMM ecosystem. Its primary responsibility is to verify signed data used by SYMM contracts. This includes validating uPNL calculations, price data, liquidation events, and settlement data. It relies on trusted Muon signatures (via a TSS mechanism) and gateway signature verification to ensure that all data is authentic and has not been tampered with.


Core Functions

getChainId

Description: Retrieves the unique chain ID of the blockchain on which the contract is executing. This value is used to ensure that data is tied to the correct network context.

Implementation:

function getChainId() internal view returns (uint256 id) {
    assembly {
        id := chainid()
    }
}

verifyTSSAndGateway

Description: Performs dual signature verification:

  1. TSS Verification: Uses the Muon TSS (via LibMuonV04ClientBase.muonVerify) to verify that the data’s hash is signed by the correct Muon public key.

  2. Gateway Signature Verification: Converts the hash to an Ethereum signed message hash and recovers the signer’s address. This address must match the valid gateway address stored in MuonStorage.

Parameters:

  • hash: The hash of the data to verify.

  • sign: A SchnorrSign structure containing the TSS signature.

  • gatewaySignature: The gateway signature as a byte array.

Implementation:

function verifyTSSAndGateway(
    bytes32 hash,
    SchnorrSign memory sign,
    bytes memory gatewaySignature
) internal view {
    bool verified = LibMuonV04ClientBase.muonVerify(uint256(hash), sign, MuonStorage.layout().muonPublicKey);
    require(verified, "LibMuon: TSS not verified");

    hash = hash.toEthSignedMessageHash();
    address gatewaySignatureSigner = hash.recover(gatewaySignature);
    require(gatewaySignatureSigner == MuonStorage.layout().validGateway, "LibMuon: Gateway is not valid");
}

verifyPartyBUpnl

Description: Verifies the uPNL data for Party B. This function checks that the provided signature has not expired, constructs a hash from key parameters (including Party B’s nonce, the uPNL value, and the current chain ID), and then calls verifyTSSAndGateway for final verification.

Parameters:

  • upnlSig: A SingleUpnlSig structure containing uPNL data and signature details.

  • partyB: Address of Party B.

  • partyA: Address of Party A.

Implementation:

function verifyPartyBUpnl(SingleUpnlSig memory upnlSig, address partyB, address partyA) internal view {
    MuonStorage.Layout storage muonLayout = MuonStorage.layout();
    require(block.timestamp <= upnlSig.timestamp + muonLayout.upnlValidTime, "LibMuon: Expired signature");
    bytes32 hash = keccak256(
        abi.encodePacked(
            muonLayout.muonAppId,
            upnlSig.reqId,
            address(this),
            partyB,
            partyA,
            AccountStorage.layout().partyBNonces[partyB][partyA],
            upnlSig.upnl,
            upnlSig.timestamp,
            getChainId()
        )
    );
    verifyTSSAndGateway(hash, upnlSig.sigs, upnlSig.gatewaySignature);
}

LibMuonAccount

verifyPartyAUpnl

Description: Verifies the uPNL data for Party A. Constructs a hash using Party A’s nonce and uPNL value, then validates it using the TSS and gateway verification.

Parameters:

  • upnlSig: A SingleUpnlSig structure.

  • partyA: Address of Party A.

Implementation:

function verifyPartyAUpnl(SingleUpnlSig memory upnlSig, address partyA) internal view {
    MuonStorage.Layout storage muonLayout = MuonStorage.layout();
    require(block.timestamp <= upnlSig.timestamp + muonLayout.upnlValidTime, "LibMuon: Expired signature");
    bytes32 hash = keccak256(
        abi.encodePacked(
            muonLayout.muonAppId,
            upnlSig.reqId,
            address(this),
            partyA,
            AccountStorage.layout().partyANonces[partyA],
            upnlSig.upnl,
            upnlSig.timestamp,
            LibMuon.getChainId()
        )
    );
    LibMuon.verifyTSSAndGateway(hash, upnlSig.sigs, upnlSig.gatewaySignature);
}

verifyPartyBUpnl (in LibMuonAccount)

Description: Delegates to the core verifyPartyBUpnl function from LibMuon to validate Party B’s uPNL data.

function verifyPartyBUpnl(SingleUpnlSig memory upnlSig, address partyB, address partyA) internal view {
    LibMuon.verifyPartyBUpnl(upnlSig, partyB, partyA);
}

LibMuonForceActions

verifyHighLowPrice

Description: Verifies that the provided high, low, current, and average price data (contained in a HighLowPriceSig structure) are authentic and within valid time limits. It constructs a hash that includes nonces and market price data and verifies the signature.

Parameters:

  • sig: A HighLowPriceSig structure.

  • partyB: Address of Party B.

  • partyA: Address of Party A.

  • symbolId: Identifier of the trading symbol.

Implementation:

function verifyHighLowPrice(HighLowPriceSig memory sig, address partyB, address partyA, uint256 symbolId) internal view {
    MuonStorage.Layout storage muonLayout = MuonStorage.layout();
    require(block.timestamp <= sig.timestamp + muonLayout.upnlValidTime, "LibMuon: Expired signature");
    bytes32 hash = keccak256(
        abi.encodePacked(
            muonLayout.muonAppId,
            sig.reqId,
            address(this),
            partyB,
            partyA,
            AccountStorage.layout().partyBNonces[partyB][partyA],
            AccountStorage.layout().partyANonces[partyA],
            sig.upnlPartyB,
            sig.upnlPartyA,
            symbolId,
            sig.currentPrice,
            sig.startTime,
            sig.endTime,
            sig.lowest,
            sig.highest,
            sig.averagePrice,
            sig.timestamp,
            LibMuon.getChainId()
        )
    );
    LibMuon.verifyTSSAndGateway(hash, sig.sigs, sig.gatewaySignature);
}

LibMuonFundingRate

verifyPairUpnl

Description: Verifies the pair uPNL data used for funding rate calculations by constructing a hash that includes both Party B and Party A's uPNL values along with their nonces and verifying the signature.

Parameters:

  • upnlSig: A PairUpnlSig structure.

  • partyB: Address of Party B.

  • partyA: Address of Party A.

Implementation:

function verifyPairUpnl(PairUpnlSig memory upnlSig, address partyB, address partyA) internal view {
    MuonStorage.Layout storage muonLayout = MuonStorage.layout();
    require(block.timestamp <= upnlSig.timestamp + muonLayout.upnlValidTime, "LibMuon: Expired signature");
    bytes32 hash = keccak256(
        abi.encodePacked(
            muonLayout.muonAppId,
            upnlSig.reqId,
            address(this),
            partyB,
            partyA,
            AccountStorage.layout().partyBNonces[partyB][partyA],
            AccountStorage.layout().partyANonces[partyA],
            upnlSig.upnlPartyB,
            upnlSig.upnlPartyA,
            upnlSig.timestamp,
            LibMuon.getChainId()
        )
    );
    LibMuon.verifyTSSAndGateway(hash, upnlSig.sigs, upnlSig.gatewaySignature);
}

LibMuonLiquidation

verifyLiquidationSig

Description: Validates the liquidation signal for Party A by ensuring that the prices and symbol IDs arrays have matching lengths, then constructing a hash from key liquidation parameters (including the liquidation ID, uPNL values, and nonce) and verifying it.

Parameters:

  • liquidationSig: A LiquidationSig structure.

  • partyA: Address of Party A.

Implementation:

function verifyLiquidationSig(LiquidationSig memory liquidationSig, address partyA) internal view {
    MuonStorage.Layout storage muonLayout = MuonStorage.layout();
    require(liquidationSig.prices.length == liquidationSig.symbolIds.length, "LibMuon: Invalid length");
    bytes32 hash = keccak256(
        abi.encodePacked(
            muonLayout.muonAppId,
            liquidationSig.reqId,
            liquidationSig.liquidationId,
            address(this),
            "verifyLiquidationSig",
            partyA,
            AccountStorage.layout().partyANonces[partyA],
            liquidationSig.upnl,
            liquidationSig.totalUnrealizedLoss,
            liquidationSig.symbolIds,
            liquidationSig.prices,
            liquidationSig.timestamp,
            LibMuon.getChainId()
        )
    );
    LibMuon.verifyTSSAndGateway(hash, liquidationSig.sigs, liquidationSig.gatewaySignature);
}

verifyDeferredLiquidationSig

Description: Verifies a deferred liquidation signature by including additional parameters (e.g. liquidation block number, timestamp, and allocated balance) in the hash. This ensures that deferred liquidation data is valid and securely signed.

Parameters:

  • liquidationSig: A DeferredLiquidationSig structure.

  • partyA: Address of Party A.

Implementation:

function verifyDeferredLiquidationSig(DeferredLiquidationSig memory liquidationSig, address partyA) internal view {
    MuonStorage.Layout storage muonLayout = MuonStorage.layout();
    require(liquidationSig.prices.length == liquidationSig.symbolIds.length, "LibMuon: Invalid length");
    bytes32 hash = keccak256(
        abi.encodePacked(
            muonLayout.muonAppId,
            liquidationSig.reqId,
            liquidationSig.liquidationId,
            address(this),
            "verifyDeferredLiquidationSig",
            partyA,
            AccountStorage.layout().partyANonces[partyA],
            liquidationSig.upnl,
            liquidationSig.totalUnrealizedLoss,
            liquidationSig.symbolIds,
            liquidationSig.prices,
            liquidationSig.timestamp,
            liquidationSig.liquidationBlockNumber,
            liquidationSig.liquidationTimestamp,
            liquidationSig.liquidationAllocatedBalance,
            LibMuon.getChainId()
        )
    );
    LibMuon.verifyTSSAndGateway(hash, liquidationSig.sigs, liquidationSig.gatewaySignature);
}

verifyQuotePrices

Description: Ensures the integrity of quote price data by verifying that the prices array matches the quote IDs array, constructing a corresponding hash, and then validating the signatures.

Parameters:

  • priceSig: A QuotePriceSig structure containing arrays of quote IDs and their prices.

Implementation:

function verifyQuotePrices(QuotePriceSig memory priceSig) internal view {
    MuonStorage.Layout storage muonLayout = MuonStorage.layout();
    require(priceSig.prices.length == priceSig.quoteIds.length, "LibMuon: Invalid length");
    bytes32 hash = keccak256(
        abi.encodePacked(
            muonLayout.muonAppId,
            priceSig.reqId,
            address(this),
            priceSig.quoteIds,
            priceSig.prices,
            priceSig.timestamp,
            LibMuon.getChainId()
        )
    );
    LibMuon.verifyTSSAndGateway(hash, priceSig.sigs, priceSig.gatewaySignature);
}

LibMuonPartyB

verifyPairUpnlAndPrice

Description: Verifies combined uPNL data and price information for both Party B and Party A for a specific symbol. It constructs a hash using the nonces, uPNL values, and the price, then validates the signatures.

Parameters:

  • upnlSig: A PairUpnlAndPriceSig structure.

  • partyB: Address of Party B.

  • partyA: Address of Party A.

  • symbolId: Identifier of the trading symbol.

Implementation:

function verifyPairUpnlAndPrice(
    PairUpnlAndPriceSig memory upnlSig,
    address partyB,
    address partyA,
    uint256 symbolId
) internal view {
    MuonStorage.Layout storage muonLayout = MuonStorage.layout();
    require(block.timestamp <= upnlSig.timestamp + muonLayout.upnlValidTime, "LibMuon: Expired signature");
    bytes32 hash = keccak256(
        abi.encodePacked(
            muonLayout.muonAppId,
            upnlSig.reqId,
            address(this),
            partyB,
            partyA,
            AccountStorage.layout().partyBNonces[partyB][partyA],
            AccountStorage.layout().partyANonces[partyA],
            upnlSig.upnlPartyB,
            upnlSig.upnlPartyA,
            symbolId,
            upnlSig.price,
            upnlSig.timestamp,
            LibMuon.getChainId()
        )
    );
    LibMuon.verifyTSSAndGateway(hash, upnlSig.sigs, upnlSig.gatewaySignature);
}

verifyPartyBUpnl (LibMuonPartyB)

Description: Delegates to the core LibMuon function to verify Party B’s uPNL data.

Implementation:

function verifyPartyBUpnl(
    SingleUpnlSig memory upnlSig,
    address partyB,
    address partyA
) internal view {
    LibMuon.verifyPartyBUpnl(upnlSig, partyB, partyA);
}

LibMuonSettlement

verifySettlement

Description: Validates the settlement data for a set of quotes by constructing a hash that aggregates critical settlement details (including quote settlement data, nonces, and uPNL values) and then verifying the signature with the TSS and gateway mechanisms.

Parameters:

  • settleSig: A SettlementSig structure containing:

    • reqId, an array of quotesSettlementsData, upnlPartyBs, upnlPartyA, timestamp, and signature data.

  • partyA: Address of Party A.

Implementation:

function verifySettlement(SettlementSig memory settleSig, address partyA) internal view {
    MuonStorage.Layout storage muonLayout = MuonStorage.layout();
    uint256 length = settleSig.quotesSettlementsData.length;
    bytes memory encodedData;
    uint256[] memory nonces = new uint256[](length);
    for (uint8 i = 0; i < length; i++) {
        nonces[i] = AccountStorage.layout().partyBNonces[QuoteStorage.layout().quotes[settleSig.quotesSettlementsData[i].quoteId].partyB][partyA];
        encodedData = abi.encodePacked(
            encodedData,
            settleSig.quotesSettlementsData[i].quoteId,
            settleSig.quotesSettlementsData[i].currentPrice,
            settleSig.quotesSettlementsData[i].partyBUpnlIndex
        );
    }
    bytes32 hash = keccak256(
        abi.encodePacked(
            muonLayout.muonAppId,
            settleSig.reqId,
            address(this),
            "verifySettlement",
            nonces,
            AccountStorage.layout().partyANonces[partyA],
            encodedData,
            settleSig.upnlPartyBs,
            settleSig.upnlPartyA,
            settleSig.timestamp,
            LibMuon.getChainId()
        )
    );
    LibMuon.verifyTSSAndGateway(hash, settleSig.sigs, settleSig.gatewaySignature);
}

Last updated