Lux Standard
Safe

Safe (Multisig)

Multi-signature wallet with threshold confirmations

Safe (Multisig)

Multi-signature wallet with support for confirmations using signed messages based on EIP-712.

Overview

Safe is a secure multi-signature wallet that requires multiple owners to confirm transactions before execution. It supports:

  • Configurable threshold (m-of-n signatures)
  • Module extensions
  • Transaction guards
  • Fallback handlers

Key Concepts

ConceptDescription
ThresholdNumber of required confirmations for a transaction
OwnersAddresses that control the Safe and approve transactions
NonceEach transaction has unique nonce to prevent replay attacks
GuardsPre/post transaction checks
ModulesExtensions for additional functionality

Core Functions

setup

function setup(
    address[] calldata _owners,
    uint256 _threshold,
    address to,
    bytes calldata data,
    address fallbackHandler,
    address paymentToken,
    uint256 payment,
    address payable paymentReceiver
) external

Initialize the Safe with owners and threshold.

execTransaction

function execTransaction(
    address to,
    uint256 value,
    bytes calldata data,
    Enum.Operation operation,
    uint256 safeTxGas,
    uint256 baseGas,
    uint256 gasPrice,
    address gasToken,
    address payable refundReceiver,
    bytes memory signatures
) public payable returns (bool success)

Execute a Safe transaction with collected signatures.

approveHash

function approveHash(bytes32 hashToApprove) external

Approve a transaction hash (for on-chain signing).

getTransactionHash

function getTransactionHash(
    address to,
    uint256 value,
    bytes calldata data,
    Enum.Operation operation,
    uint256 safeTxGas,
    uint256 baseGas,
    uint256 gasPrice,
    address gasToken,
    address refundReceiver,
    uint256 _nonce
) public view returns (bytes32)

Get the transaction hash for signing.

Owner Management

function addOwnerWithThreshold(address owner, uint256 _threshold) public
function removeOwner(address prevOwner, address owner, uint256 _threshold) public
function swapOwner(address prevOwner, address oldOwner, address newOwner) public
function changeThreshold(uint256 _threshold) public

Module Management

function enableModule(address module) public
function disableModule(address prevModule, address module) public
function execTransactionFromModule(
    address to,
    uint256 value,
    bytes memory data,
    Enum.Operation operation
) public returns (bool success)

Deployment

import "@luxfi/standard/src/safe/contracts/Safe.sol";
import "@luxfi/standard/src/safe/contracts/proxies/SafeProxyFactory.sol";

// Deploy factory
SafeProxyFactory factory = new SafeProxyFactory();

// Create Safe with 2-of-3 threshold
address[] memory owners = new address[](3);
owners[0] = owner1;
owners[1] = owner2;
owners[2] = owner3;

bytes memory initializer = abi.encodeCall(
    Safe.setup,
    (
        owners,
        2,                  // threshold
        address(0),         // to
        "",                 // data
        address(0),         // fallbackHandler
        address(0),         // paymentToken
        0,                  // payment
        payable(address(0)) // paymentReceiver
    )
);

SafeProxy proxy = factory.createProxyWithNonce(
    address(safeSingleton),
    initializer,
    salt
);

Safe safe = Safe(payable(address(proxy)));

Usage Example

// 1. Get transaction hash
bytes32 txHash = safe.getTransactionHash(
    to,
    value,
    data,
    Enum.Operation.Call,
    0,          // safeTxGas
    0,          // baseGas
    0,          // gasPrice
    address(0), // gasToken
    address(0), // refundReceiver
    safe.nonce()
);

// 2. Collect signatures off-chain (EIP-712)
bytes memory signatures = collectSignatures(txHash);

// 3. Execute transaction
safe.execTransaction(
    to,
    value,
    data,
    Enum.Operation.Call,
    0,
    0,
    0,
    address(0),
    payable(address(0)),
    signatures
);

Threshold Signers (MPC)

Safe supports threshold signature schemes as owners, enabling advanced custody solutions without exposing private keys.

Available Signers

SignerProtocolCurveQuantum SafeUse Case
SafeCGGMP21SignerCGGMP21secp256k1Institutional ECDSA custody
SafeFROSTSignerFROSTsecp256k1Bitcoin Taproot, Schnorr
SafeFROSTCoSignerFROSTsecp256k1Co-signing workflows
SafeRingtailSignerRingtailLatticePost-quantum security
SafeLSSSignerLSSsecp256k1Dynamic resharing
SafeMLDSASignerML-DSALatticeFIPS 204 compliant

CGGMP21 Threshold ECDSA

import "@luxfi/standard/contracts/safe/SafeCGGMP21Signer.sol";

// Deploy with 2-of-3 threshold and aggregated public key
SafeCGGMP21Signer signer = new SafeCGGMP21Signer(
    2,           // threshold
    3,           // total signers
    publicKey    // 65-byte uncompressed secp256k1
);

// Add as Safe owner
safe.addOwnerWithThreshold(address(signer), threshold);

FROST Schnorr Threshold

import "@luxfi/standard/contracts/safe/SafeFROSTSigner.sol";

// Deploy with public key coordinates
SafeFROSTSigner signer = new SafeFROSTSigner(px, py);

// Verify signature
bool valid = signer._isValidSignature(messageHash, signature);

Post-Quantum (Ringtail)

import "@luxfi/standard/contracts/safe/SafeRingtailSigner.sol";

// Deploy with Ringtail public key
SafeRingtailSigner signer = new SafeRingtailSigner(
    threshold,
    totalSigners,
    ringtailPublicKey  // Lattice-based public key
);

Integration with MPC Nodes

The threshold signers integrate with the Lux MPC node cluster (github.com/luxfi/mpc):

  1. Key Generation: Run distributed key generation across MPC nodes
  2. Deploy Signer: Deploy threshold signer contract with aggregated public key
  3. Add to Safe: Add signer contract as a Safe owner
  4. Collaborative Signing: MPC nodes sign transactions without exposing keys
┌─────────────────────────────────────────────────────────────────────────────┐
│                           MPC + SAFE INTEGRATION                            │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ┌─────────────┐     ┌─────────────┐     ┌─────────────┐                   │
│  │  MPC Node 1 │     │  MPC Node 2 │     │  MPC Node 3 │                   │
│  │  (Share 1)  │     │  (Share 2)  │     │  (Share 3)  │                   │
│  └──────┬──────┘     └──────┬──────┘     └──────┬──────┘                   │
│         │                   │                   │                           │
│         └───────────────────┼───────────────────┘                           │
│                             │ Threshold Signing (2-of-3)                    │
│                             ▼                                               │
│                    ┌─────────────────┐                                      │
│                    │  CGGMP21/FROST  │                                      │
│                    │    Signature    │                                      │
│                    └────────┬────────┘                                      │
│                             │                                               │
│                             ▼                                               │
│         ┌─────────────────────────────────────────┐                         │
│         │          SafeCGGMP21Signer              │                         │
│         │  (verifies threshold signature)         │                         │
│         └─────────────────────┬───────────────────┘                         │
│                               │                                             │
│                               ▼                                             │
│                    ┌─────────────────┐                                      │
│                    │   Safe Wallet   │                                      │
│                    │ (executes tx)   │                                      │
│                    └─────────────────┘                                      │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
  • LP-7321: FROST Threshold Signature Precompile
  • LP-7322: CGGMP21 Threshold ECDSA Precompile
  • LP-7324: Ringtail Threshold Signature Precompile
  • LP-7340: Threshold Cryptography Library
  • LP-3310: Safe Multisig Standard

Security

  • Threshold Enforcement: All transactions require threshold confirmations
  • EIP-712 Signatures: Typed structured data for secure signing
  • Guards: Optional pre/post execution checks
  • Replay Protection: Nonce prevents transaction replay
  • MPC Security: No single party holds complete private key
  • Quantum Resistance: Ringtail and ML-DSA signers provide post-quantum security

On this page