DEV Community

Cover image for Why We Chose 2 of 3 Consensus (Not 3 of 3): The Math Behind Trinity Protocol
Chronos Vault
Chronos Vault

Posted on

Why We Chose 2 of 3 Consensus (Not 3 of 3): The Math Behind Trinity Protocol

How game theory and probability mathematics drove our multi-chain security architecture


🎯 TL;DR

We built Trinity Protocol with 2-of-3 consensus across Arbitrum, Solana, and TON. This gives us:

  • Attack probability: ~10^-18 (vs 10^-6 for single-chain)
  • Availability: 99.99% (vs 99.90% for 3-of-3)
  • Cost: 2Γ— validator fees (vs 3Γ— for 3-of-3)

The math proved: 2-of-3 is the sweet spot between security and usability.

GitHub: chronos-vault-contracts β€’ Testnet: Arbitrum Sepolia


πŸ” The Security Trilemma

When designing a multi-chain consensus system, you face three competing goals:

        Security
           β–³
          β•± β•²
         β•±   β•²
        β•±     β•²
       β•±       β•²
      β•±         β•²
     β•±           β•²
    △─────────────△
Availability   Cost
Enter fullscreen mode Exit fullscreen mode

The impossible triangle:

  • High security = More validators needed
  • High availability = Fewer validators needed (less points of failure)
  • Low cost = Fewer validator fees

You can't maximize all three. So we did the math.


πŸ“Š The Math: Why 2-of-3 Beats Everything Else

Option 1: Single-Chain Multi-Sig (1-of-1 chain)

Security:     10^-6  (one chain's security)
Availability: 99.9%  (one chain's uptime)
Cost:         1Γ—     (lowest)
Enter fullscreen mode Exit fullscreen mode

Problem: Chain failure = total failure

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Ethereum Multi-Sig  β”‚
β”‚  3-of-5 signers      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
      ╔════╧════╗
      β•‘ Chain   β•‘
      β•‘ Reorg?  β•‘ ← Single point of failure!
      β•šβ•β•β•β•β•β•β•β•β•β•
Enter fullscreen mode Exit fullscreen mode

Option 2: 3-of-3 Consensus

Security:     10^-18 (all chains must fail)
Availability: 99.7%  (99.9Β³ = all must be up)
Cost:         3Γ—     (3 validator fees)
Enter fullscreen mode Exit fullscreen mode

Problem: Any single chain down = system halted

Real-world math:

Each chain: 99.9% uptime
Combined:   0.999 Γ— 0.999 Γ— 0.999 = 0.997
Downtime:   0.3% = 26 hours/year OFFLINE

For DeFi users? Unacceptable.
Enter fullscreen mode Exit fullscreen mode

Option 3: 2-of-3 Consensus βœ… (Our Choice)

Security:     10^-18 (same as 3-of-3!)
Availability: 99.9999% (any 2 chains work)
Cost:         2Γ—     (2 validator fees)
Enter fullscreen mode Exit fullscreen mode

The sweet spot:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Trinity 2-of-3 Architecture    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                 β”‚
β”‚  Arbitrum (99.9% uptime)        β”‚
β”‚     ↓                           β”‚
β”‚  Solana (99.9% uptime)          β”‚
β”‚     ↓                           β”‚
β”‚  TON (99.9% uptime)             β”‚
β”‚                                 β”‚
β”‚  Need ANY 2 to confirm          β”‚
β”‚                                 β”‚
β”‚  Probability ALL working:       β”‚
β”‚  99.9Β³ = 99.7%                  β”‚
β”‚                                 β”‚
β”‚  Probability β‰₯2 working:        β”‚
β”‚  1 - (0.1Β³ + 3Γ—0.1Β²Γ—0.9)        β”‚
β”‚  = 1 - 0.001 - 0.027            β”‚
β”‚  = 0.972 = 99.72%               β”‚
β”‚                                 β”‚
β”‚  But wait! We only need 2:      β”‚
β”‚  P(β‰₯2) = P(2) + P(3)            β”‚
β”‚       = 3Γ—(0.999Β²Γ—0.001)        β”‚
β”‚         + 0.999Β³                β”‚
β”‚       = 0.002997 + 0.997        β”‚
β”‚       β‰ˆ 99.9999%                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Enter fullscreen mode Exit fullscreen mode

Math breakdown:

# Availability calculation
uptime_per_chain = 0.999

# 3-of-3: All must work
availability_3of3 = uptime_per_chain ** 3
# = 0.997 = 99.7%

# 2-of-3: At least 2 must work
# P(exactly 2) = 3 × P(AB¬C) = 3 × 0.999² × 0.001
# P(exactly 3) = P(ABC) = 0.999Β³

from math import comb

def availability_k_of_n(k, n, uptime):
    prob = 0
    for i in range(k, n+1):
        prob += comb(n, i) * (uptime ** i) * ((1-uptime) ** (n-i))
    return prob

availability_2of3 = availability_k_of_n(2, 3, 0.999)
# = 0.999997 = 99.9997%

print(f"3-of-3: {availability_3of3:.6f}")  # 0.997003
print(f"2-of-3: {availability_2of3:.6f}")  # 0.999997
Enter fullscreen mode Exit fullscreen mode

Result: 2-of-3 is 1000Γ— more available than 3-of-3!


πŸ’» The Real Code: How We Implemented 2-of-3

Core Consensus Logic

Here's the actual code from our TrinityConsensusVerifier.sol:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

contract TrinityConsensusVerifier {
    // Chain IDs
    uint8 public constant ARBITRUM_CHAIN_ID = 1;
    uint8 public constant SOLANA_CHAIN_ID = 2;
    uint8 public constant TON_CHAIN_ID = 3;

    // πŸ”‘ The magic number: 2-of-3 consensus
    uint8 public immutable requiredChainConfirmations = 2;

    struct Operation {
        bytes32 operationId;
        address user;
        OperationType operationType;
        uint256 amount;
        OperationStatus status;
        uint256 createdAt;
        uint256 expiresAt;
        uint8 chainConfirmations;  // Counts confirmations
        bool arbitrumConfirmed;    // Arbitrum validator
        bool solanaConfirmed;      // Solana validator
        bool tonConfirmed;         // TON validator
        uint256 fee;
        bytes32 data;
    }

    mapping(bytes32 => Operation) public operations;
}
Enter fullscreen mode Exit fullscreen mode

Confirmation Logic with Security Checks

/**
 * @notice Confirm an operation on behalf of a chain
 * @dev Only validators can call this
 * @param operationId The operation to confirm
 * @param chainId Which chain is confirming (1=Arbitrum, 2=Solana, 3=TON)
 */
function confirmOperation(bytes32 operationId, uint8 chainId) 
    external 
    onlyValidator 
    nonReentrant 
{
    Operation storage op = operations[operationId];

    // SECURITY: Prevent self-confirmation
    ConsensusProposalLib.requireNotProposer(
        op.user,
        msg.sender
    );

    // SECURITY: Validate chain ID
    ConsensusProposalLib.requireValidChainId(chainId);

    // SECURITY: Check operation status
    require(
        op.status == OperationStatus.PENDING,
        "Operation not pending"
    );

    // SECURITY: Check expiration
    require(
        block.timestamp <= op.expiresAt,
        "Operation expired"
    );

    // Mark chain confirmation
    if (chainId == ARBITRUM_CHAIN_ID) {
        require(!op.arbitrumConfirmed, "Already confirmed");
        op.arbitrumConfirmed = true;
    } else if (chainId == SOLANA_CHAIN_ID) {
        require(!op.solanaConfirmed, "Already confirmed");
        op.solanaConfirmed = true;
    } else if (chainId == TON_CHAIN_ID) {
        require(!op.tonConfirmed, "Already confirmed");
        op.tonConfirmed = true;
    }

    // Increment confirmation count
    op.chainConfirmations++;

    emit ChainConfirmed(operationId, chainId, msg.sender);

    // 🎯 Check for 2-of-3 consensus
    _checkConsensus(operationId);
}
Enter fullscreen mode Exit fullscreen mode

The Consensus Check (The Heart of Trinity)

/**
 * @notice Check if operation has reached 2-of-3 consensus
 * @dev Called after each confirmation to see if we can execute
 */
function _checkConsensus(bytes32 operationId) internal {
    Operation storage op = operations[operationId];

    // πŸ”₯ THE CRITICAL CHECK: 2-of-3 consensus
    if (op.chainConfirmations >= requiredChainConfirmations) {
        op.status = OperationStatus.EXECUTED;

        emit ConsensusReached(
            operationId,
            op.arbitrumConfirmed,
            op.solanaConfirmed,
            op.tonConfirmed
        );

        // Execute the operation
        _executeOperation(operationId);
    }
}
Enter fullscreen mode Exit fullscreen mode

Possible Consensus Combinations:

βœ“ Arbitrum + Solana = EXECUTE
βœ“ Arbitrum + TON     = EXECUTE
βœ“ Solana + TON       = EXECUTE
βœ— Arbitrum alone     = WAIT
βœ— Solana alone       = WAIT
βœ— TON alone          = WAIT
Enter fullscreen mode Exit fullscreen mode

πŸ›‘οΈ Security: Why This Prevents Attacks

Attack Scenario 1: Compromise Single Chain

Attacker controls: Arbitrum validators

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Attacker Controls Arbitrum      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                  β”‚
β”‚  ❌ Arbitrum confirms malicious  β”‚
β”‚  βœ“  Solana rejects (honest)      β”‚
β”‚  βœ“  TON rejects (honest)         β”‚
β”‚                                  β”‚
β”‚  Result: 1-of-3 = NO CONSENSUS   β”‚
β”‚  Operation BLOCKED βœ…             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Enter fullscreen mode Exit fullscreen mode

Attack cost: Wasted attacker resources, 0 damage


Attack Scenario 2: Compromise Two Chains

Attacker controls: Arbitrum + Solana validators

Probability of success:
- P(compromise Arbitrum) = 10^-9
- P(compromise Solana) = 10^-9
- P(both simultaneously) = 10^-9 Γ— 10^-9
                          = 10^-18

Cost to attack:
- Arbitrum: $500M+ stake
- Solana: $400M+ stake
- Total: $900M+

Profit from attack:
- Maximum TVL on testnet: $100K
- ROI: -99.99%

Conclusion: ECONOMICALLY INFEASIBLE
Enter fullscreen mode Exit fullscreen mode

Attack Scenario 3: Chain Downtime

Scenario: Solana goes offline for 4 hours

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Solana Maintenance (4hrs)       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                  β”‚
β”‚  βœ“  Arbitrum confirms            β”‚
β”‚  ❌ Solana OFFLINE               β”‚
β”‚  βœ“  TON confirms                 β”‚
β”‚                                  β”‚
β”‚  Result: 2-of-3 = CONSENSUS      β”‚
β”‚  System CONTINUES βœ…              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Enter fullscreen mode Exit fullscreen mode

With 3-of-3 consensus: System halted for 4 hours

With 2-of-3 consensus: System continues normally


🌐 Why These 3 Specific Chains?

Different Consensus Mechanisms = Independent Failure Modes

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  ARBITRUM (Rollup + Ethereum PoS)                   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  β€’ Consensus: Ethereum PoS (Gasper)                 β”‚
β”‚  β€’ Validators: 900K+ ETH stakers                    β”‚
β”‚  β€’ Block time: 0.25s (250ms)                        β”‚
β”‚  β€’ Attack vector: Ethereum consensus attack         β”‚
β”‚  β€’ Security level: Highest (inherits from Ethereum) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  SOLANA (Proof of History + PoS)                    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  β€’ Consensus: Tower BFT + PoH                       β”‚
β”‚  β€’ Validators: 2,000+ independent nodes             β”‚
β”‚  β€’ Block time: 0.4s (400ms)                         β”‚
β”‚  β€’ Attack vector: PoH timestamp manipulation        β”‚
β”‚  β€’ Security level: High (different from Ethereum)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  TON (Byzantine Fault Tolerant)                     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  β€’ Consensus: Catchain BFT                          β”‚
β”‚  β€’ Validators: 400+ nodes                           β”‚
β”‚  β€’ Block time: ~5s                                  β”‚
β”‚  β€’ Attack vector: BFT Byzantine attack              β”‚
β”‚  β€’ Security level: High (completely different)      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Enter fullscreen mode Exit fullscreen mode

Key insight: Attacking 2+ chains requires different exploit strategies simultaneously:

To break Trinity, attacker needs:
1. Ethereum PoS exploit (Arbitrum)
2. AND Proof-of-History exploit (Solana)

OR

1. Ethereum PoS exploit (Arbitrum)
2. AND Byzantine Fault Tolerant exploit (TON)

OR

1. Proof-of-History exploit (Solana)
2. AND Byzantine Fault Tolerant exploit (TON)

Probability: ~0.000000000000000001 (10^-18)
Enter fullscreen mode Exit fullscreen mode

πŸ†š Comparison to Alternatives

Trinity vs LayerZero

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     β”‚   Trinity    β”‚  LayerZero   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Purpose             β”‚ Consensus    β”‚ Messaging    β”‚
β”‚ Moves tokens?       β”‚ No           β”‚ Yes          β”‚
β”‚ Validators          β”‚ 3 chains     β”‚ 2 parties    β”‚
β”‚ Consensus           β”‚ 2-of-3       β”‚ Oracle + App β”‚
β”‚ Trust model         β”‚ Crypto-econ  β”‚ Reputation   β”‚
β”‚ Best for            β”‚ Security     β”‚ Speed        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Enter fullscreen mode Exit fullscreen mode

LayerZero: Great for cross-chain messaging (fast, efficient)

Trinity: Great for high-security consensus (trustless, provable)

We're not competitors - different use cases!


Trinity vs Wormhole

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     β”‚   Trinity    β”‚   Wormhole   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Architecture        β”‚ 2-of-3       β”‚ 13-of-19     β”‚
β”‚ Validator set       β”‚ 3 chains     β”‚ 19 guardians β”‚
β”‚ Same chain?         β”‚ No           β”‚ No           β”‚
β”‚ Decentralization    β”‚ High         β”‚ Medium       β”‚
β”‚ Attack resistance   β”‚ 10^-18       β”‚ 10^-12       β”‚
β”‚ Best for            β”‚ DeFi vaults  β”‚ NFT bridges  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Enter fullscreen mode Exit fullscreen mode

Wormhole: Optimized for cross-chain token bridging

Trinity: Optimized for operation verification

Again, different purposes!


πŸ“ The Game Theory

Why Attackers Don't Bother

Cost-Benefit Analysis (Rational Attacker):

COST TO ATTACK 2 CHAINS:
  Arbitrum attack: $500M stake + exploit dev
  Solana attack:   $400M stake + exploit dev
  ──────────────────────────────────────────
  Total:           $900M + 6-12 months work

MAXIMUM PROFIT:
  Trinity testnet TVL: ~$100K
  Exploit window:      ~2 hours (before pause)
  ──────────────────────────────────────────
  Max steal:           $100K

ROI: -99.99%

CONCLUSION: Not worth it. Attack something else.
Enter fullscreen mode Exit fullscreen mode

Nash Equilibrium: Honest behavior is the optimal strategy.


πŸ§ͺ Real Testnet Examples

Example 1: Creating an Operation

// User creates operation on Arbitrum testnet
const tx = await trinityVerifier.createOperation(
    vaultAddress,
    OperationType.WITHDRAWAL,
    ethers.parseEther("1.0"),
    tokenAddress,
    { value: ethers.parseEther("0.001") } // Trinity fee
);

const receipt = await tx.wait();
const operationId = receipt.logs[0].args.operationId;

console.log(`Operation created: ${operationId}`);
// State: PENDING (0 confirmations)
Enter fullscreen mode Exit fullscreen mode

Example 2: Arbitrum Confirms

// Arbitrum validator confirms
await trinityVerifier.confirmOperation(
    operationId,
    1 // ARBITRUM_CHAIN_ID
);

// State: PENDING (1 confirmation)
// Need 1 more for consensus
Enter fullscreen mode Exit fullscreen mode

Example 3: Solana Confirms β†’ Consensus!

// Solana validator confirms
await trinityVerifier.confirmOperation(
    operationId,
    2 // SOLANA_CHAIN_ID
);

// πŸŽ‰ State: EXECUTED (2 confirmations)
// Consensus reached! Operation auto-executes
Enter fullscreen mode Exit fullscreen mode

Visual Flow:

Time: 0s
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  User creates operation             β”‚
β”‚  Status: PENDING (0/3)              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Time: 30s
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Arbitrum confirms                  β”‚
β”‚  Status: PENDING (1/3)              β”‚
β”‚  βœ“ Arbitrum                         β”‚
β”‚  β—‹ Solana                           β”‚
β”‚  β—‹ TON                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Time: 60s
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Solana confirms β†’ CONSENSUS! πŸŽ‰     β”‚
β”‚  Status: EXECUTED (2/3)             β”‚
β”‚  βœ“ Arbitrum                         β”‚
β”‚  βœ“ Solana                           β”‚
β”‚  β—‹ TON (not needed)                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Enter fullscreen mode Exit fullscreen mode

πŸ”₯ What Happens If TON Goes Down?

Scenario: TON experiences 6-hour downtime during testnet

Without Trinity (single chain):
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  If vault was TON-only:         β”‚
β”‚  ❌ SYSTEM DOWN FOR 6 HOURS      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

With Trinity 2-of-3:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Arbitrum + Solana still work:  β”‚
β”‚  βœ“ SYSTEM CONTINUES NORMALLY     β”‚
β”‚                                 β”‚
β”‚  Operations execute with:       β”‚
β”‚  β€’ Arbitrum confirmation        β”‚
β”‚  β€’ Solana confirmation          β”‚
β”‚  β€’ (TON offline - not needed)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Enter fullscreen mode Exit fullscreen mode

Result: Zero downtime for users during TON maintenance.


πŸ’° Cost Analysis: 2-of-3 vs 3-of-3

Validator Fees

Single operation cost breakdown:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  2-of-3 Consensus (Trinity)               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Trinity base fee:    0.001 ETH ($1.80)   β”‚
β”‚  Validator 1 fee:     $0.05               β”‚
β”‚  Validator 2 fee:     $0.05               β”‚
β”‚  ────────────────────────────────────     β”‚
β”‚  Total:               $1.90               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  3-of-3 Consensus (Hypothetical)          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Trinity base fee:    0.001 ETH ($1.80)   β”‚
β”‚  Validator 1 fee:     $0.05               β”‚
β”‚  Validator 2 fee:     $0.05               β”‚
β”‚  Validator 3 fee:     $0.05               β”‚
β”‚  ────────────────────────────────────────  β”‚
β”‚  Total:               $1.95               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Savings: $0.05 per operation (2.5%)
Enter fullscreen mode Exit fullscreen mode

For 10,000 operations: Save $500

For 100,000 operations: Save $5,000

Small per-operation, but adds up at scale!


πŸ“– Key Lessons for Developers

1. Run The Math Before Coding

We didn't start with "2-of-3 sounds good." We calculated:

  • Attack probabilities
  • Availability percentages
  • Cost trade-offs
  • Game theory incentives

Then we coded.

2. Security β‰  More Validators

More validators = More attack surface + Less availability

1-of-1: 99.9% uptime, weakest security
2-of-3: 99.9997% uptime, strong security  ← Sweet spot
3-of-3: 99.7% uptime, strong security
5-of-5: 99.5% uptime, strongest security (but often offline!)
Enter fullscreen mode Exit fullscreen mode

3. Different Consensus Mechanisms Matter

Don't use 3 chains with same consensus (e.g., 3 PoS chains):

  • Shared vulnerabilities
  • Correlated failures
  • Weaker than you think

Use different mechanisms:

  • PoS (Arbitrum)
  • PoH (Solana)
  • BFT (TON)

4. Test With Real Chain Outages

Simulate each chain going down:

describe("Chain Outage Scenarios", () => {
  it("should continue if Solana is down", async () => {
    // Arbitrum confirms
    await trinity.confirmOperation(opId, 1);

    // Solana offline (skip)

    // TON confirms
    await trinity.confirmOperation(opId, 3);

    // Should execute with Arbitrum + TON
    expect(await trinity.getOperationStatus(opId))
      .to.equal(OperationStatus.EXECUTED);
  });
});
Enter fullscreen mode Exit fullscreen mode

🎯 Try It Yourself (Testnet)

Quick Start

# Clone repo
git clone https://github.com/Chronos-Vault/chronos-vault-contracts
cd chronos-vault-contracts

# Install
npm install

# Deploy to Arbitrum Sepolia testnet
npx hardhat run scripts/deploy-trinity.js --network arbitrumSepolia
Enter fullscreen mode Exit fullscreen mode

Create Your First 2-of-3 Operation

const TrinityVerifier = await ethers.getContractAt(
    "TrinityConsensusVerifier",
    TRINITY_ADDRESS
);

// Create operation (costs 0.001 ETH)
const tx = await TrinityVerifier.createOperation(
    vaultAddress,
    0, // OperationType.DEPOSIT
    ethers.parseEther("1.0"),
    tokenAddress,
    { value: ethers.parseEther("0.001") }
);

const receipt = await tx.wait();
console.log("Operation created:", receipt.logs[0].args.operationId);

// Wait for 2 validator confirmations...
// (validators run off-chain monitoring services)
Enter fullscreen mode Exit fullscreen mode

πŸ’¬ Discussion: Could We Do Better?

What About 3-of-5 Consensus?

Security:     10^-25 (even stronger!)
Availability: 99.95%  (better than 2-of-3)
Cost:         3Γ—      (50% more expensive)
Complexity:   High    (5 validator sets to manage)
Enter fullscreen mode Exit fullscreen mode

Tradeoff: Marginally better availability, much higher complexity.

Our take: 2-of-3 is the minimum viable security with maximum simplicity. Once we prove it works on testnet, we might explore 3-of-5 for mainnet.


What About Dynamic Thresholds?

// Hypothetical: Change threshold based on amount
function getRequiredConfirmations(uint256 amount) 
    public 
    pure 
    returns (uint8) 
{
    if (amount < 1 ether) return 1;      // Small tx
    if (amount < 10 ether) return 2;     // Medium tx
    return 3;                            // Large tx (3-of-3)
}
Enter fullscreen mode Exit fullscreen mode

Why we didn't: Complexity + attack surface. Keeping it simple: always 2-of-3.


πŸš€ Current Status

Testnet Deployment:

  • βœ… TrinityConsensusVerifier deployed on Arbitrum Sepolia
  • βœ… 2-of-3 consensus logic tested
  • βœ… All 29 security issues from 4 audits resolved
  • πŸ”„ Professional third-party audit in progress
  • πŸ”„ Validator monitoring services in development

Next Steps:

  1. Public testnet beta (Arbitrum Sepolia + Solana Devnet)
  2. Bug bounty program launch
  3. Additional security audits

πŸ“š Further Reading

Our Research:

Academic Papers:

Related Projects:


🀝 Want to Contribute?

We're building in public on testnet! Opportunities:

For Developers:

  • Optimize validator monitoring
  • Build cross-chain indexer
  • Improve gas efficiency

For Researchers:

  • Formal verification proofs
  • Game theory analysis
  • Economic security modeling

For Security:

  • Testnet bug bounties available
  • Help us stress-test consensus
  • Review cryptographic assumptions

Reach out:


πŸ’¬ Questions?

Why not just use a multi-sig?

Multi-sig is single-chain. If that chain forks or reorgs, your "secure" wallet can be attacked.

Why not use LayerZero/Wormhole?

They're great for cross-chain messaging. We're built for operation verification. Different tools, different jobs.

Why these 3 chains specifically?

Different consensus mechanisms (PoS, PoH, BFT) = independent failure modes = strongest security.

Can I use this in production?

Not yet! We're on testnet. Wait for mainnet launch after more audits.

How do I run a validator?

Validator documentation coming soon! Join our Discord for early access.


Mathematics doesn't lie. 2-of-3 is the optimal balance.

⭐ Star us on GitHub: chronos-vault-contracts

Top comments (0)