Display lp tokens USD value in dropdown

pull/4067/head
Viktor Baranov 4 years ago
parent d994d9c258
commit ab9f94f6a7
  1. 1
      CHANGELOG.md
  2. 4
      apps/block_scout_web/lib/block_scout_web/controllers/address_token_balance_controller.ex
  3. 4
      apps/block_scout_web/lib/block_scout_web/templates/address_token_balance/_token_balances.html.eex
  4. 22
      apps/block_scout_web/lib/block_scout_web/templates/address_token_balance/_tokens.html.eex
  5. 4
      apps/block_scout_web/lib/block_scout_web/views/address_token_balance_view.ex
  6. 32
      apps/block_scout_web/test/block_scout_web/views/address_token_balance_view_test.exs
  7. 2
      apps/explorer/lib/explorer/chain.ex
  8. 13
      apps/explorer/lib/explorer/chain/address/current_token_balance.ex
  9. 10
      apps/explorer/lib/explorer/market/market.ex
  10. 4
      apps/explorer/test/explorer/chain/address/current_token_balance_test.exs
  11. 2
      apps/explorer/test/explorer/chain_test.exs
  12. 4
      apps/indexer/lib/indexer/fetcher/token_balance_on_demand.ex

@ -1,6 +1,7 @@
## Current
### Features
- [#4067](https://github.com/blockscout/blockscout/pull/4067) - Display LP tokens USD value and custom metadata in tokens dropdown at address page
### Fixes
- [#4038](https://github.com/blockscout/blockscout/pull/4038) - Add clause for abi_decode_address_output/1 when is_nil(address)

@ -26,12 +26,12 @@ defmodule BlockScoutWeb.AddressTokenBalanceController do
token_balances_except_bridged =
token_balances
|> Enum.filter(fn token_balance -> !token_balance.token.bridged end)
|> Enum.filter(fn {token_balance, _} -> !token_balance.token.bridged end)
circles_total_balance =
if Enum.count(circles_addresses_list) > 0 do
token_balances_except_bridged
|> Enum.reduce(Decimal.new(0), fn token_balance, acc_balance ->
|> Enum.reduce(Decimal.new(0), fn {token_balance, _}, acc_balance ->
{:ok, token_address} = Chain.hash_to_address(token_balance.address_hash)
from_address = from_address_hash(token_address)

@ -36,7 +36,7 @@
placeholder: gettext("Search tokens")
) %>
</div>
<%= if Enum.any?(@token_balances, & &1.token.type == "ERC-721") do %>
<%= if Enum.any?(@token_balances, fn {token_balance, _} -> token_balance.token.type == "ERC-721" end) do %>
<%= render(
"_tokens.html",
conn: @conn,
@ -45,7 +45,7 @@
) %>
<% end %>
<%= if Enum.any?(@token_balances, & &1.token.type == "ERC-20") do %>
<%= if Enum.any?(@token_balances, fn {token_balance, _} -> token_balance.token.type == "ERC-20" end) do %>
<%= render(
"_tokens.html",
conn: @conn,

@ -3,7 +3,7 @@
<%= @type %> (<span data-number-of-tokens-by-type="<%= @type %>"><%= Enum.count(@token_balances)%></span>)
</h6>
<%= for token_balance <- sort_by_usd_value_and_name(@token_balances) do %>
<%= for {token_balance, bridged_token} <- sort_by_usd_value_and_name(@token_balances) do %>
<div
class="border-bottom"
data-dropdown-token-balance-test
@ -15,15 +15,27 @@
class: "dropdown-item"
) do %>
<div class="row">
<p class="mb-0 col-md-6"><%= token_name(token_balance.token) %></p>
<%= if token_balance.token.usd_value do %>
<p class="mb-0 col-md-6"><%= token_name(token_balance.token) %>
<%= if bridged_token && bridged_token.custom_metadata do %>
<%= "(" <> bridged_token.custom_metadata <> ")" %>
<% end %>
</p>
<%= if bridged_token && bridged_token.lp_token && bridged_token.custom_cap do %>
<% lp_token_balance_usd = token_balance.value |> Decimal.div(token_balance.token.total_supply) |> Decimal.mult(bridged_token.custom_cap) |> Decimal.round(4) %>
<p class="mb-0 col-md-6 text-right">
<span data-selector="token-balance-usd" data-usd-value="<%= Chain.balance_in_usd(token_balance) %>"></span>
<span data-selector="token-balance-usd" data-usd-value="<%= lp_token_balance_usd %>"></span>
</p>
<% else %>
<%= if token_balance.token.usd_value do %>
<p class="mb-0 col-md-6 text-right">
<span data-selector="token-balance-usd" data-usd-value="<%= Chain.balance_in_usd(token_balance) %>"></span>
</p>
<% end %>
<% end %>
</div>
<div class="row">
<p class="mb-0 col-md-6">
<% col_md = if token_balance.token.usd_value, do: "col-md-6", else: "col-md-12" %>
<p class="mb-0 <%= col_md %> ">
<%= format_according_to_decimals(token_balance.value, token_balance.token.decimals) %> <%= token_balance.token.symbol %>
</p>
<%= if token_balance.token.usd_value do %>

@ -9,7 +9,7 @@ defmodule BlockScoutWeb.AddressTokenBalanceView do
end
def filter_by_type(token_balances, type) do
Enum.filter(token_balances, &(&1.token.type == type))
Enum.filter(token_balances, fn {token_balance, _} -> token_balance.token.type == type end)
end
@doc """
@ -27,7 +27,7 @@ defmodule BlockScoutWeb.AddressTokenBalanceView do
"""
def sort_by_usd_value_and_name(token_balances) do
token_balances
|> Enum.sort(fn token_balance1, token_balance2 ->
|> Enum.sort(fn {token_balance1, _}, {token_balance2, _} ->
usd_value1 = token_balance1.token.usd_value
usd_value2 = token_balance2.token.usd_value

@ -20,9 +20,9 @@ defmodule BlockScoutWeb.AddressTokenBalanceViewTest do
token_balance_a = build(:token_balance, token: build(:token, type: "ERC-20"))
token_balance_b = build(:token_balance, token: build(:token, type: "ERC-721"))
token_balances = [token_balance_a, token_balance_b]
token_balances = [{token_balance_a, %{}}, {token_balance_b, %{}}]
assert AddressTokenBalanceView.filter_by_type(token_balances, "ERC-20") == [token_balance_a]
assert AddressTokenBalanceView.filter_by_type(token_balances, "ERC-20") == [{token_balance_a, %{}}]
end
end
@ -116,23 +116,23 @@ defmodule BlockScoutWeb.AddressTokenBalanceViewTest do
)
token_balances = [
token_balance_a,
token_balance_b,
token_balance_c,
token_balance_d,
token_balance_e,
token_balance_f,
token_balance_g
{token_balance_a, %{}},
{token_balance_b, %{}},
{token_balance_c, %{}},
{token_balance_d, %{}},
{token_balance_e, %{}},
{token_balance_f, %{}},
{token_balance_g, %{}}
]
expected = [
token_balance_b,
token_balance_a,
token_balance_c,
token_balance_d,
token_balance_g,
token_balance_e,
token_balance_f
{token_balance_b, %{}},
{token_balance_a, %{}},
{token_balance_c, %{}},
{token_balance_d, %{}},
{token_balance_g, %{}},
{token_balance_e, %{}},
{token_balance_f, %{}}
]
assert AddressTokenBalanceView.sort_by_usd_value_and_name(token_balances) == expected

@ -2085,7 +2085,7 @@ defmodule Explorer.Chain do
def address_tokens_usd_sum(token_balances) do
token_balances
|> Enum.reduce(Decimal.new(0), fn token_balance, acc ->
|> Enum.reduce(Decimal.new(0), fn {token_balance, _}, acc ->
if token_balance.value && token_balance.token.usd_value do
Decimal.add(acc, balance_in_usd(token_balance))
else

@ -12,7 +12,7 @@ defmodule Explorer.Chain.Address.CurrentTokenBalance do
import Ecto.Query, only: [from: 2, limit: 2, offset: 2, order_by: 3, preload: 2, where: 3]
alias Explorer.{Chain, PagingOptions}
alias Explorer.Chain.{Address, Block, Hash, Token}
alias Explorer.Chain.{Address, Block, BridgedToken, Hash, Token}
@default_paging_options %PagingOptions{page_size: 50}
@ -101,10 +101,13 @@ defmodule Explorer.Chain.Address.CurrentTokenBalance do
"""
def last_token_balances(address_hash) do
from(
tb in __MODULE__,
where: tb.address_hash == ^address_hash,
where: tb.value > 0,
preload: :token
ctb in __MODULE__,
where: ctb.address_hash == ^address_hash,
where: ctb.value > 0,
left_join: bt in BridgedToken,
on: ctb.token_contract_address_hash == bt.home_token_contract_address_hash,
preload: :token,
select: {ctb, bt}
)
end

@ -82,7 +82,15 @@ defmodule Explorer.Market do
end
def add_price(tokens) when is_list(tokens) do
Enum.map(tokens, &add_price/1)
Enum.map(tokens, fn item ->
case item do
{token_balance, bridged_token} ->
{add_price(token_balance), bridged_token}
token_balance ->
add_price(token_balance)
end
end)
end
defp mainnet_bridged_token?(token) do

@ -157,7 +157,7 @@ defmodule Explorer.Chain.Address.CurrentTokenBalanceTest do
address.hash
|> CurrentTokenBalance.last_token_balances()
|> Repo.all()
|> Enum.map(& &1.address_hash)
|> Enum.map(fn {token_balance, _} -> token_balance.address_hash end)
assert token_balances == [current_token_balance.address_hash]
end
@ -195,7 +195,7 @@ defmodule Explorer.Chain.Address.CurrentTokenBalanceTest do
address.hash
|> CurrentTokenBalance.last_token_balances()
|> Repo.all()
|> Enum.map(& &1.address_hash)
|> Enum.map(fn {token_balance, _} -> token_balance.address_hash end)
assert token_balances == [current_token_balance_a.address_hash]
end

@ -4506,7 +4506,7 @@ defmodule Explorer.ChainTest do
token_balances =
address.hash
|> Chain.fetch_last_token_balances()
|> Enum.map(& &1.address_hash)
|> Enum.map(fn {token_balance, _} -> token_balance.address_hash end)
assert token_balances == [current_token_balance.address_hash]
end

@ -34,7 +34,7 @@ defmodule Indexer.Fetcher.TokenBalanceOnDemand do
when not is_nil(address_hash) do
stale_current_token_balances =
current_token_balances
|> Enum.filter(fn current_token_balance -> current_token_balance.block_number < stale_balance_window end)
|> Enum.filter(fn {current_token_balance, _} -> current_token_balance.block_number < stale_balance_window end)
if Enum.count(stale_current_token_balances) > 0 do
fetch_and_update(latest_block_number, address_hash, stale_current_token_balances)
@ -48,7 +48,7 @@ defmodule Indexer.Fetcher.TokenBalanceOnDemand do
defp fetch_and_update(block_number, address_hash, stale_current_token_balances) do
current_token_balances_update_params =
stale_current_token_balances
|> Enum.map(fn stale_current_token_balance ->
|> Enum.map(fn {stale_current_token_balance, _} ->
stale_current_token_balances_to_fetch = [
%{
token_contract_address_hash:

Loading…
Cancel
Save