Current section

Files

Jump to
kujira lib kujira orca queue.ex
Raw

lib/kujira/orca/queue.ex

defmodule Kujira.Orca.Queue do
@moduledoc """
An individual Orca Liquidation Queue
## Fields
* `:address` - The contract address
* `:owner` - The account authorized to make changes to contract config
* `:collateral_token` - The token that is being liquidated
* `:bid_token` - The token that is used to buy the collateral
* `:bid_pools` - The aggregate amounts of bids at each supported discount amount. The contract confug contains `max_slot` and `premium_rate_per_slot`, which define these pools
* `:activation_threshold` - The total amount of bids, above which the activation_delay must pass before a bid can be activated. This is `bid_threshold` on the contract interfaace
* `:activation_delay` - The time in seconds that must pass before a bid can be activated. This is `waiting_period` on the contract interface
"""
alias Kujira.Token
alias Kujira.Orca.Pool
defstruct [
:address,
:owner,
:collateral_token,
:bid_token,
:bid_pools,
:activation_threshold,
:activation_delay,
:liquidation_fee,
:withdrawal_fee
]
@type t :: %__MODULE__{
address: String.t(),
owner: String.t(),
bid_token: Token.t(),
bid_pools: list(Pool.t()),
collateral_token: Token.t(),
activation_threshold: integer(),
activation_delay: integer(),
liquidation_fee: Decimal.t(),
withdrawal_fee: Decimal.t()
}
@spec from_config(GRPC.Channel.t(), String.t(), map()) :: {:ok, __MODULE__.t()} | :error
def from_config(channel, address, %{
"bid_denom" => bid_denom,
"bid_threshold" => bid_threshold,
"closed_slots" => _closed_slots,
"collateral_denom" => collateral_denom,
"fee_address" => _fee_address,
"liquidation_fee" => liquidation_fee,
"markets" => _markets,
"max_slot" => max_slot,
"owner" => owner,
"premium_rate_per_slot" => premium_rate_per_slot,
"waiting_period" => waiting_period,
"withdrawal_fee" => withdrawal_fee
}) do
with {activation_threshold, ""} <- Integer.parse(bid_threshold),
{liquidation_fee, ""} <- Decimal.parse(liquidation_fee),
{premium_rate_per_slot, ""} <- Decimal.parse(premium_rate_per_slot),
{withdrawal_fee, ""} <- Decimal.parse(withdrawal_fee),
{:ok, collateral_token} <- Token.from_denom(channel, collateral_denom),
{:ok, bid_token} <- Token.from_denom(channel, bid_denom) do
{:ok,
%__MODULE__{
address: address,
owner: owner,
collateral_token: collateral_token,
bid_token: bid_token,
bid_pools: [],
activation_threshold: activation_threshold,
activation_delay: waiting_period,
liquidation_fee: liquidation_fee,
withdrawal_fee: withdrawal_fee
}
|> populate_pools(max_slot, premium_rate_per_slot)}
else
_ ->
:error
end
end
@doc """
Enumerates all bid pools based on contract config
"""
@spec populate_pools(__MODULE__.t(), integer(), Decimal.t()) :: __MODULE__.t()
def populate_pools(queue, max_slot, premium_rate_per_slot) do
%{
queue
| bid_pools:
0..max_slot
|> Enum.to_list()
|> Enum.map(&Pool.calculate(premium_rate_per_slot, &1))
}
end
@doc """
Assigns the current state to the bd_pools from a direct contract query response
"""
@spec load_pools(list(map()), __MODULE__.t()) :: __MODULE__.t()
def load_pools(pools, queue) do
%{
queue
| bid_pools:
Enum.map(queue.bid_pools, fn pool ->
pools
|> Enum.find(
&(&1["premium_rate"]
|> Decimal.parse()
|> elem(0)
|> Decimal.eq?(pool.premium))
)
|> Pool.load(pool)
end)
}
end
end