Current section
8 Versions
Jump to
Current section
8 Versions
Compare versions
7
files changed
+56
additions
-20
deletions
| @@ -1,7 +1,7 @@ | |
| 1 1 | {<<"links">>, |
| 2 2 | [{<<"GitHub">>,<<"https://github.com/RujiraNetwork/rujira_ex">>}]}. |
| 3 3 | {<<"name">>,<<"rujira_ex">>}. |
| 4 | - {<<"version">>,<<"0.0.7">>}. |
| 4 | + {<<"version">>,<<"0.0.8">>}. |
| 5 5 | {<<"description">>,<<"Domain library for Rujira">>}. |
| 6 6 | {<<"elixir">>,<<"~> 1.18">>}. |
| 7 7 | {<<"files">>, |
| @@ -74,7 +74,7 @@ defmodule Rujira.Events do | |
| 74 74 | do: Rujira.Fin.Events.parse(event) |
| 75 75 | |
| 76 76 | defp route(%Event{type: type} = event) |
| 77 | - when type in ~w(swap transfer add_liquidity withdraw pending_liquidity oracle_price bond rebond set_mimir), |
| 77 | + when type in ~w(swap transfer add_liquidity withdraw pending_liquidity oracle_price bond rebond rewards affiliate_fee set_mimir), |
| 78 78 | do: Rujira.Thorchain.Events.parse(event) |
| 79 79 | |
| 80 80 | # --- Not yet implemented --- |
| @@ -16,6 +16,7 @@ defmodule Rujira.Fin do | |
| 16 16 | defdelegate get_pair(address), to: Pair, as: :get |
| 17 17 | defdelegate list_pairs(), to: Pair, as: :list |
| 18 18 | defdelegate get_stable_pair(denom), to: Pair, as: :find_stable |
| 19 | + defdelegate get_default_pair(denom), to: Pair, as: :find_default |
| 19 20 | defdelegate denom_for_ticker(ticker), to: Pair |
| 20 21 | defdelegate get_pair_from_denoms(base, quote_denom), to: Pair, as: :find_by_denoms |
| 21 22 | defdelegate pair_from_id(id), to: Pair, as: :from_id |
| @@ -3,19 +3,22 @@ defmodule Rujira.Fin.Events.TradeRange do | |
| 3 3 | A single range touched by a concentrated-liquidity trade. |
| 4 4 | |
| 5 5 | The contract joins one entry per range into the trade event's `ranges` |
| 6 | - attribute with commas. Each entry is colon-separated and the fee occupies a |
| 7 | - different slot depending on the fill side: |
| 6 | + attribute with commas. Each entry is colon-separated. The leading segment is |
| 7 | + the range id, which itself embeds the price bounds as `idx:low-high`, so a |
| 8 | + full entry has the shape: |
| 8 9 | |
| 9 | - * base-side fill: `idx:base:quote:deduct:add::fee` (6th slot empty) |
| 10 | - * quote-side fill: `idx:base:quote:deduct:add:fee:` (7th slot empty) |
| 10 | + * base-side fill: `idx:low-high:base:quote:deduct:add::fee` (7th slot empty) |
| 11 | + * quote-side fill: `idx:low-high:base:quote:deduct:add:fee:` (8th slot empty) |
| 11 12 | |
| 12 | - All amounts are the range's internal full-precision `Decimal` values, not |
| 13 | - 8-decimal token integers. |
| 13 | + All amounts and bounds are the range's internal full-precision `Decimal` |
| 14 | + values, not 8-decimal token integers. |
| 14 15 | """ |
| 15 16 | |
| 16 17 | alias Rujira.Math |
| 17 18 | |
| 18 19 | defstruct idx: 0, |
| 20 | + low: Decimal.new(0), |
| 21 | + high: Decimal.new(0), |
| 19 22 | side: :base, |
| 20 23 | base: Decimal.new(0), |
| 21 24 | quote: Decimal.new(0), |
| @@ -25,6 +28,8 @@ defmodule Rujira.Fin.Events.TradeRange do | |
| 25 28 | |
| 26 29 | @type t :: %__MODULE__{ |
| 27 30 | idx: non_neg_integer(), |
| 31 | + low: Decimal.t(), |
| 32 | + high: Decimal.t(), |
| 28 33 | side: :base | :quote, |
| 29 34 | base: Decimal.t(), |
| 30 35 | quote: Decimal.t(), |
| @@ -55,9 +60,12 @@ defmodule Rujira.Fin.Events.TradeRange do | |
| 55 60 | |
| 56 61 | @spec parse(String.t()) :: {:ok, t()} | {:error, term()} |
| 57 62 | def parse(entry) when is_binary(entry) do |
| 58 | - with [idx, base, quote, deduct, add, f6, f7] <- String.split(entry, ":"), |
| 59 | - {:ok, {side, fee}} <- fee_slot(f6, f7), |
| 63 | + with [idx, bounds, base, quote, deduct, add, f7, f8] <- String.split(entry, ":"), |
| 64 | + [low, high] <- String.split(bounds, "-"), |
| 65 | + {:ok, {side, fee}} <- fee_slot(f7, f8), |
| 60 66 | {:ok, idx} <- Math.to_integer(idx), |
| 67 | + {:ok, low} <- Math.to_decimal(low), |
| 68 | + {:ok, high} <- Math.to_decimal(high), |
| 61 69 | {:ok, base} <- Math.to_decimal(base), |
| 62 70 | {:ok, quote} <- Math.to_decimal(quote), |
| 63 71 | {:ok, deduct} <- Math.to_decimal(deduct), |
| @@ -66,6 +74,8 @@ defmodule Rujira.Fin.Events.TradeRange do | |
| 66 74 | {:ok, |
| 67 75 | %__MODULE__{ |
| 68 76 | idx: idx, |
| 77 | + low: low, |
| 78 | + high: high, |
| 69 79 | side: side, |
| 70 80 | base: base, |
| 71 81 | quote: quote, |
| @@ -118,13 +118,7 @@ defmodule Rujira.Fin.Pair do | |
| 118 118 | @spec find_stable(String.t()) :: {:ok, t()} | {:error, term()} |
| 119 119 | def find_stable(base_denom) do |
| 120 120 | with {:ok, pairs} <- list(), |
| 121 | - %__MODULE__{} = pair <- |
| 122 | - Enum.find( |
| 123 | - pairs, |
| 124 | - &(&1.token_base == base_denom && |
| 125 | - (String.contains?(&1.token_quote, "usdc") || |
| 126 | - String.contains?(&1.token_quote, "usdt"))) |
| 127 | - ) do |
| 121 | + %__MODULE__{} = pair <- Enum.find(pairs, &stable_pair?(&1, base_denom)) do |
| 128 122 | {:ok, pair} |
| 129 123 | else |
| 130 124 | nil -> {:error, :not_found} |
| @@ -132,6 +126,36 @@ defmodule Rujira.Fin.Pair do | |
| 132 126 | end |
| 133 127 | end |
| 134 128 | |
| 129 | + @doc """ |
| 130 | + Finds the default pair for a base denom: prefers a stable (usdc/usdt) quote, |
| 131 | + otherwise falls back to the first pair quoting that base. |
| 132 | + """ |
| 133 | + @spec find_default(String.t()) :: {:ok, t()} | {:error, term()} |
| 134 | + def find_default(base_denom) do |
| 135 | + with {:ok, pairs} <- list() do |
| 136 | + pick_default(pairs, base_denom) |
| 137 | + end |
| 138 | + end |
| 139 | + |
| 140 | + @doc false |
| 141 | + @spec pick_default([t()], String.t()) :: {:ok, t()} | {:error, :not_found} |
| 142 | + def pick_default(pairs, base_denom) do |
| 143 | + stable = Enum.find(pairs, &stable_pair?(&1, base_denom)) |
| 144 | + first = Enum.find(pairs, &(&1.token_base == base_denom)) |
| 145 | + |
| 146 | + case stable || first do |
| 147 | + %__MODULE__{} = pair -> {:ok, pair} |
| 148 | + nil -> {:error, :not_found} |
| 149 | + end |
| 150 | + end |
| 151 | + |
| 152 | + defp stable_pair?(%__MODULE__{token_base: base_denom, token_quote: quote}, base_denom) |
| 153 | + when is_binary(quote) do |
| 154 | + String.contains?(quote, "usdc") or String.contains?(quote, "usdt") |
| 155 | + end |
| 156 | + |
| 157 | + defp stable_pair?(_, _), do: false |
| 158 | + |
| 135 159 | @doc """ |
| 136 160 | Memoized lookup of the preferred base denom for a ticker. |
Loading more files…