Raxol.Payments.RebalancePolicy (Raxol Payments v0.2.0)

Copy Markdown View Source

Per-chain solver treasury policy: native gas floors/targets, per-asset inventory floors/targets, asset tiers, gas-refuel source preference, and per-destination-tier minimum notionals.

Consumed by Raxol.Payments.RebalanceAdvisor to recommend (never execute) gas refuels and inventory rebalances across the settlement assets: USDC, USDT, USDG (Robinhood Chain), and WETH. Two asset tiers matter:

  • stable (USDC/USDT/USDG) -- inventory is rebalanced across chains (USDC via CCTP; USDT/USDG via a bridge).
  • volatile (WETH) -- not rebalanced; it is the cheapest gas-refuel source, since WETH unwraps 1:1 to native ETH (no DEX, no slippage) on ETH-native chains.

min_notional gates the money-losing case: an Ethereum-L1 destination fill is only economic well above the fixed L1 gas cost, so the :l1 tier carries a much higher floor than :l2.

Native maps are whole native units (e.g. 0.02 ETH); inventory maps are human dollars keyed %{chain_id => %{symbol => Decimal}}.

Summary

Functions

A conservative default policy for the six supported EVM chains: L1 gas floor 0.02 ETH (target 0.05), L2 gas floor 0.005 (target 0.02); per-stable inventory floor $5 / target $25 on the chains each stable exists; refuel by unwrapping WETH first, then swapping a stable; min notional $50 to L1, $1 to L2.

True when notional (human dollars) meets the destination tier's minimum.

Minimum economic notional (human dollars) for a fill whose destination is to_chain_id. Ethereum mainnet is the :l1 tier; every other chain is :l2. nil when the tier has no floor (no gate).

True when symbol is a stable-tier asset.

The stable-tier symbols in this policy.

Types

chain_map()

@type chain_map() :: %{required(pos_integer()) => Decimal.t()}

inventory_map()

@type inventory_map() :: %{
  required(pos_integer()) => %{required(String.t()) => Decimal.t()}
}

t()

@type t() :: %Raxol.Payments.RebalancePolicy{
  asset_tiers: %{required(String.t()) => :stable | :volatile},
  gas_floor: chain_map(),
  gas_refuel_sources: [:unwrap_weth | :swap_stable],
  gas_target: chain_map(),
  inventory_floor: inventory_map(),
  inventory_target: inventory_map(),
  min_notional: %{l1: Decimal.t() | nil, l2: Decimal.t() | nil},
  refuel_source_chain: pos_integer() | nil
}

Functions

default()

@spec default() :: t()

A conservative default policy for the six supported EVM chains: L1 gas floor 0.02 ETH (target 0.05), L2 gas floor 0.005 (target 0.02); per-stable inventory floor $5 / target $25 on the chains each stable exists; refuel by unwrapping WETH first, then swapping a stable; min notional $50 to L1, $1 to L2.

economic?(policy, to_chain_id, notional)

@spec economic?(t(), pos_integer(), Decimal.t()) :: boolean()

True when notional (human dollars) meets the destination tier's minimum.

min_notional_for(rebalance_policy, to_chain_id)

@spec min_notional_for(t(), pos_integer()) :: Decimal.t() | nil

Minimum economic notional (human dollars) for a fill whose destination is to_chain_id. Ethereum mainnet is the :l1 tier; every other chain is :l2. nil when the tier has no floor (no gate).

stable?(rebalance_policy, symbol)

@spec stable?(t(), String.t()) :: boolean()

True when symbol is a stable-tier asset.

stables(rebalance_policy)

@spec stables(t()) :: [String.t()]

The stable-tier symbols in this policy.