Update order logic for tokens with price

pull/3462/head
Victor Baranov 4 years ago
parent cc348ef824
commit 28f7c10625
  1. 32
      apps/block_scout_web/lib/block_scout_web/views/address_token_balance_view.ex
  2. 48
      apps/block_scout_web/test/block_scout_web/views/address_token_balance_view_test.exs
  3. 21
      apps/explorer/lib/explorer/chain/supply/token_bridge.ex
  4. 13
      apps/explorer/lib/explorer/market/market.ex

@ -35,7 +35,7 @@ defmodule BlockScoutWeb.AddressTokenBalanceView do
sort_by_name = sort_2_tokens_by_name(token_name1, token_name2)
sort_2_tokens_by_value_desc_and_name(usd_value1, usd_value2, sort_by_name)
sort_2_tokens_by_value_desc_and_name(token_balance1, token_balance2, usd_value1, usd_value2, sort_by_name)
end)
end
@ -55,28 +55,34 @@ defmodule BlockScoutWeb.AddressTokenBalanceView do
end
end
defp sort_2_tokens_by_value_desc_and_name(usd_value1, usd_value2, _sort_by_name)
when not is_nil(usd_value1) and is_nil(usd_value2) do
defp sort_2_tokens_by_value_desc_and_name(token_balance1, token_balance2, usd_value1, usd_value2, sort_by_name)
when not is_nil(usd_value1) and not is_nil(usd_value2) do
case Decimal.cmp(balance_in_usd(token_balance1), balance_in_usd(token_balance2)) do
:gt ->
true
end
defp sort_2_tokens_by_value_desc_and_name(usd_value1, usd_value2, _sort_by_name)
when is_nil(usd_value1) and not is_nil(usd_value2) do
:eq ->
sort_by_name
:lt ->
false
end
end
defp sort_2_tokens_by_value_desc_and_name(usd_value1, usd_value2, sort_by_name) do
cond do
usd_value1 && usd_value2 && Decimal.cmp(usd_value1, usd_value2) == :gt ->
defp sort_2_tokens_by_value_desc_and_name(_token_balance1, _token_balance2, usd_value1, usd_value2, _sort_by_name)
when not is_nil(usd_value1) and is_nil(usd_value2) do
true
end
usd_value1 && usd_value2 && Decimal.cmp(usd_value1, usd_value2) == :eq ->
sort_by_name
defp sort_2_tokens_by_value_desc_and_name(_token_balance1, _token_balance2, usd_value1, usd_value2, _sort_by_name)
when is_nil(usd_value1) and not is_nil(usd_value2) do
false
end
true ->
defp sort_2_tokens_by_value_desc_and_name(_token_balance1, _token_balance2, usd_value1, usd_value2, sort_by_name)
when is_nil(usd_value1) and is_nil(usd_value2) do
sort_by_name
end
end
@doc """
Return the balance in usd corresponding to this token. Return nil if the usd_value of the token is not present.

@ -71,13 +71,47 @@ defmodule BlockScoutWeb.AddressTokenBalanceViewTest do
describe "sort_by_usd_value_and_name/1" do
test "sorts the given tokens by its name and usd_value" do
token_balance_a = build(:token_balance, token: build(:token, name: "token name") |> Map.put(:usd_value, 2))
token_balance_b = build(:token_balance, token: build(:token, name: "token") |> Map.put(:usd_value, 3))
token_balance_c = build(:token_balance, token: build(:token, name: nil) |> Map.put(:usd_value, 2))
token_balance_d = build(:token_balance, token: build(:token, name: "Atoken") |> Map.put(:usd_value, 1))
token_balance_e = build(:token_balance, token: build(:token, name: "atoken") |> Map.put(:usd_value, nil))
token_balance_f = build(:token_balance, token: build(:token, name: "Btoken") |> Map.put(:usd_value, nil))
token_balance_g = build(:token_balance, token: build(:token, name: "Btoken") |> Map.put(:usd_value, 1))
token_balance_a =
build(:token_balance,
token: build(:token, name: "token name", decimals: Decimal.new(18)) |> Map.put(:usd_value, Decimal.new(2)),
value: Decimal.new(100_500)
)
token_balance_b =
build(:token_balance,
token: build(:token, name: "token", decimals: Decimal.new(18)) |> Map.put(:usd_value, Decimal.new(3.45)),
value: Decimal.new(100_500)
)
token_balance_c =
build(:token_balance,
token: build(:token, name: nil, decimals: Decimal.new(18)) |> Map.put(:usd_value, Decimal.new(2)),
value: Decimal.new(100_500)
)
token_balance_d =
build(:token_balance,
token: build(:token, name: "Atoken", decimals: Decimal.new(18)) |> Map.put(:usd_value, Decimal.new(1)),
value: Decimal.new(100_500)
)
token_balance_e =
build(:token_balance,
token: build(:token, name: "atoken", decimals: Decimal.new(18)) |> Map.put(:usd_value, nil),
value: Decimal.new(100_500)
)
token_balance_f =
build(:token_balance,
token: build(:token, name: "Btoken", decimals: Decimal.new(18)) |> Map.put(:usd_value, nil),
value: Decimal.new(100_500)
)
token_balance_g =
build(:token_balance,
token: build(:token, name: "Btoken", decimals: Decimal.new(18)) |> Map.put(:usd_value, Decimal.new(1)),
value: Decimal.new(100_500)
)
token_balances = [
token_balance_a,

@ -196,7 +196,9 @@ defmodule Explorer.Chain.Supply.TokenBridge do
def get_current_price_for_bridged_token(symbol) when is_nil(symbol), do: nil
def get_current_price_for_bridged_token(symbol) do
case Source.fetch_exchange_rates_for_token(symbol) do
bridged_token_symbol_for_price_fetching = bridged_token_symbol_mapping_to_get_price(symbol)
case Source.fetch_exchange_rates_for_token(bridged_token_symbol_for_price_fetching) do
{:ok, [rates]} ->
rates.usd_value
@ -222,14 +224,7 @@ defmodule Explorer.Chain.Supply.TokenBridge do
bridged_mainnet_tokens_with_supply =
bridged_mainnet_tokens_list
|> Enum.map(fn {bridged_token_hash, bridged_token_symbol} ->
bridged_token_symbol_corrected =
case bridged_token_symbol do
"POA20" -> "POA"
"yDAI+yUSDC+yUSDT+yTUSD" -> "yCurve"
symbol -> symbol
end
bridged_token_price = Bridge.fetch_token_price(bridged_token_symbol_corrected)
bridged_token_price = Bridge.fetch_token_price(bridged_token_symbol)
query =
from(t in Token,
@ -274,4 +269,12 @@ defmodule Explorer.Chain.Supply.TokenBridge do
omni_bridge_market_cap
end
defp bridged_token_symbol_mapping_to_get_price(symbol) do
case symbol do
"POA20" -> "POA"
"yDAI+yUSDC+yUSDT+yTUSD" -> "yCurve"
symbol -> symbol
end
end
end

@ -5,6 +5,7 @@ defmodule Explorer.Market do
alias Explorer.Chain.Address.CurrentTokenBalance
alias Explorer.Chain.{BridgedToken, Hash}
alias Explorer.Chain.Supply.TokenBridge
alias Explorer.ExchangeRates.Token
alias Explorer.Market.{MarketHistory, MarketHistoryCache}
alias Explorer.{ExchangeRates, KnownTokens, Repo}
@ -56,9 +57,17 @@ defmodule Explorer.Market do
matches_known_address = known_address && known_address == token.contract_address_hash
fetch_token_usd_value? = matches_known_address || mainnet_bridged_token?(token)
usd_value =
cond do
matches_known_address ->
fetch_token_usd_value(matches_known_address, symbol)
usd_value = fetch_token_usd_value(fetch_token_usd_value?, symbol)
mainnet_bridged_token?(token) ->
TokenBridge.get_current_price_for_bridged_token(symbol)
true ->
nil
end
Map.put(token, :usd_value, usd_value)
end

Loading…
Cancel
Save