Docs
Docs/Minimax Algorithm

Minimax Algorithm

How the minimax search algorithm from game theory applies to cross-chain routing — and why it produces better outcomes than expected-value optimization.

The Chess Connection

In chess, the minimax algorithm evaluates every possible move by assuming the opponent plays optimally. It picks the move that maximizes your minimum guaranteed score — the best you can do even when the opponent plays perfectly.

Cross-chain routing is the same problem in a different domain:

ChessMNMX Routing
Board positionsCandidate routes
Possible movesPossible paths (bridge + DEX combinations)
Opponent's best responseWorst-case market conditions
Position evaluationRoute scoring (fees + slippage + risk)
Minimax scoreGuaranteed minimum output
Alpha-beta pruningEarly elimination of dominated routes

The Algorithm

MNMX applies a modified minimax with two levels:

text
1Level 0 (Maximizer — your routes):
2 For each candidate route, compute the worst-case output.
3 Pick the route with the HIGHEST worst-case output.
4
5Level 1 (Minimizer — adversarial conditions):
6 For each route, model all adversarial factors:
7 - Slippage spike (2x quoted)
8 - Gas price surge (1.5x current)
9 - Bridge delay (3x median)
10 - MEV extraction (0.3% of value)
11 - Price movement (0.5% adverse)
12 Apply all simultaneously → worst-case output for this route.
typescript
1function minimax(routes: Route[]): Route {
2 let bestRoute: Route | null = null;
3 let bestMinimaxScore = -Infinity;
4
5 for (const route of routes) {
6 // Minimizer: compute worst-case output for this route
7 const worstCase = evaluateWorstCase(route);
8
9 // Maximizer: pick route with best worst-case
10 if (worstCase.score > bestMinimaxScore) {
11 bestMinimaxScore = worstCase.score;
12 bestRoute = route;
13 }
14 }
15
16 return bestRoute;
17}
18
19function evaluateWorstCase(route: Route): Evaluation {
20 let output = route.quotedOutput;
21
22 // Apply all adversarial conditions simultaneously
23 output -= route.slippage * 2.0; // 2x slippage
24 output -= route.gasCost * 1.5; // 1.5x gas
25 output -= route.value * 0.003; // MEV extraction
26 output -= route.value * 0.005; // Adverse price movement
27 output -= route.bridgeRiskPenalty; // Bridge-specific risk
28
29 return { score: output, route };
30}

Minimax vs Expected Value

Most routers use expected value optimization — they estimate the most likely outcome for each route and pick the highest. Here's why minimax is better for cross-chain:

Concrete Example

text
1Transfer: 1 ETH → SOL
2
3Route A (Wormhole direct):
4 Best case: 14.5 SOL (probability: 60%)
5 Worst case: 11.2 SOL (probability: 40%)
6 Expected value: 14.5 × 0.6 + 11.2 × 0.4 = 13.18 SOL
7 Minimax score: 11.2 SOL
8
9Route B (Multi-hop via Arbitrum):
10 Best case: 14.2 SOL (probability: 70%)
11 Worst case: 13.8 SOL (probability: 30%)
12 Expected value: 14.2 × 0.7 + 13.8 × 0.3 = 14.08 SOL
13 Minimax score: 13.8 SOL
14
15Expected value picks: Route B (14.08 > 13.18) ← correct here
16Minimax picks: Route B (13.8 > 11.2) ← also correct, same answer
17
18But what if probabilities are wrong?
text
1What if actual worst-case probability was 70%, not 40%?
2
3Route A actual: 14.5 × 0.3 + 11.2 × 0.7 = 12.19 SOL ← much worse
4Route B actual: 14.2 × 0.3 + 13.8 × 0.7 = 13.92 SOL ← barely changed
5
6Minimax doesn't need to know probabilities.
7It just guarantees Route B gives you AT LEAST 13.8 SOL.
8Period.

In cross-chain, probability estimates are unreliable — bridge delays are unpredictable, MEV is adversarial, liquidity conditions change between quote and execution. Minimax doesn't need probability estimates. It gives you the best guaranteed floor.

Alpha-Beta Pruning

When evaluating many candidate paths, alpha-beta pruning eliminates routes that cannot possibly beat the current best:

text
1Routes to evaluate: [A, B, C, D, E, F, G, H, I, J, K, L]
2
3Evaluate A → minimax score: 12.1
4Evaluate B → minimax score: 13.8 ← new best
5Evaluate C → worst-case starts below 13.8 → PRUNE (can't beat B)
6Evaluate D → minimax score: 13.2 → skip (below B)
7Evaluate E → worst-case starts below 13.8 → PRUNE
8...
9
10Result: Only 7 of 12 routes fully evaluated. Same result, 40% less work.

Route Scoring Function

Each route is scored across five dimensions. The combined score represents the net output in destination tokens:

DimensionWeightDescription
Total fees0.25Sum of gas, bridge, and swap fees across all hops
Slippage impact0.25Price impact from swaps and low bridge liquidity
Transfer speed0.15Expected total time from start to completion
Bridge reliability0.20Historical uptime, TVL, security audit score
MEV exposure0.15Risk of value extraction during multi-hop execution

User Strategy Profiles

Users can adjust the scoring weights to match their priorities:

ProfileFeesSlippageSpeedReliabilityMEV
Minimax (default)0.250.250.150.200.15
Cheapest0.450.300.050.100.10
Fastest0.100.150.500.150.10
Safest0.100.150.100.400.25

Limitations

Conservative bias: Minimax inherently favors reliable paths over potentially more profitable but riskier ones. Users who want to maximize expected value can switch to the "cheapest" strategy.

State staleness: Route conditions can change between quote and execution. The engine re-validates conditions before executing each step and will abort if conditions degrade beyond tolerance.