diff --git a/CHANGELOG.md b/CHANGELOG.md index a837bce54b..c59a71f7a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - [#3564](https://github.com/poanetwork/blockscout/pull/3564) - Staking welcome message ### Fixes +- [#3707](https://github.com/poanetwork/blockscout/pull/3707) - Fetch bridged token price by address of foreign token, not by symbol - [#3686](https://github.com/poanetwork/blockscout/pull/3686) - BSC bridged tokens detection fix - [#3683](https://github.com/poanetwork/blockscout/pull/3683) - Token instance image IPFS link display fix - [#3655](https://github.com/poanetwork/blockscout/pull/3655) - Handle absence of readAll function in some old/legacy browsers diff --git a/apps/block_scout_web/config/config.exs b/apps/block_scout_web/config/config.exs index c865533fcb..d95b6b5636 100644 --- a/apps/block_scout_web/config/config.exs +++ b/apps/block_scout_web/config/config.exs @@ -44,7 +44,8 @@ config :block_scout_web, restricted_list_key: System.get_env("RESTRICTED_LIST_KEY", nil), dark_forest_addresses: System.get_env("CUSTOM_CONTRACT_ADDRESSES_DARK_FOREST"), dark_forest_addresses_v_0_5: System.get_env("CUSTOM_CONTRACT_ADDRESSES_DARK_FOREST_V_0_5"), - circles_addresses: System.get_env("CUSTOM_CONTRACT_ADDRESSES_CIRCLES") + circles_addresses: System.get_env("CUSTOM_CONTRACT_ADDRESSES_CIRCLES"), + test_tokens_addresses: System.get_env("CUSTOM_CONTRACT_ADDRESSES_TEST_TOKEN") config :block_scout_web, BlockScoutWeb.Counters.BlocksIndexedCounter, enabled: true diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_balance_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_balance_controller.ex index dc28b01a23..bcac720b80 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_balance_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_balance_controller.ex @@ -2,8 +2,8 @@ defmodule BlockScoutWeb.AddressTokenBalanceController do use BlockScoutWeb, :controller import BlockScoutWeb.AddressView, only: [from_address_hash: 1] - alias BlockScoutWeb.{AccessHelpers, CustomContractsHelpers} - alias Explorer.{Chain, Market} + alias BlockScoutWeb.AccessHelpers + alias Explorer.{Chain, CustomContractsHelpers, Market} alias Indexer.Fetcher.TokenBalanceOnDemand def index(conn, %{"address_id" => address_hash_string} = params) do diff --git a/apps/block_scout_web/lib/block_scout_web/views/address_view.ex b/apps/block_scout_web/lib/block_scout_web/views/address_view.ex index 523d7632c3..db37658d12 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/address_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/address_view.ex @@ -3,8 +3,8 @@ defmodule BlockScoutWeb.AddressView do require Logger - alias BlockScoutWeb.{AccessHelpers, CustomContractsHelpers, LayoutView} - alias Explorer.Chain + alias BlockScoutWeb.{AccessHelpers, LayoutView} + alias Explorer.{Chain, CustomContractsHelpers} alias Explorer.Chain.{Address, Hash, InternalTransaction, SmartContract, Token, TokenTransfer, Transaction, Wei} alias Explorer.Chain.Block.Reward alias Explorer.ExchangeRates.Token, as: TokenExchangeRate diff --git a/apps/block_scout_web/lib/block_scout_web/views/layout_view.ex b/apps/block_scout_web/lib/block_scout_web/views/layout_view.ex index 8e7523a2da..2a389b02bc 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/layout_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/layout_view.ex @@ -1,7 +1,7 @@ defmodule BlockScoutWeb.LayoutView do use BlockScoutWeb, :view - alias Explorer.Chain + alias Explorer.{Chain, CustomContractsHelpers} alias Plug.Conn alias Poison.Parser @@ -34,7 +34,7 @@ defmodule BlockScoutWeb.LayoutView do } ] - alias BlockScoutWeb.{CustomContractsHelpers, SocialMedia} + alias BlockScoutWeb.SocialMedia def logo do Keyword.get(application_config(), :logo) || "/images/blockscout_logo.svg" diff --git a/apps/block_scout_web/lib/block_scout_web/views/tokens/overview_view.ex b/apps/block_scout_web/lib/block_scout_web/views/tokens/overview_view.ex index 6eecbc6d3f..c5dccab223 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/tokens/overview_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/tokens/overview_view.ex @@ -1,10 +1,10 @@ defmodule BlockScoutWeb.Tokens.OverviewView do use BlockScoutWeb, :view - alias Explorer.Chain + alias Explorer.{Chain, CustomContractsHelpers} alias Explorer.Chain.{Address, SmartContract, Token} - alias BlockScoutWeb.{AccessHelpers, CurrencyHelpers, CustomContractsHelpers, LayoutView} + alias BlockScoutWeb.{AccessHelpers, CurrencyHelpers, LayoutView} import BlockScoutWeb.AddressView, only: [from_address_hash: 1] diff --git a/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex b/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex index cb0a2618bd..b4b1f88ba9 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex @@ -1,9 +1,9 @@ defmodule BlockScoutWeb.TransactionView do use BlockScoutWeb, :view - alias BlockScoutWeb.{AccessHelpers, AddressView, BlockView, CustomContractsHelpers, TabHelpers} + alias BlockScoutWeb.{AccessHelpers, AddressView, BlockView, TabHelpers} alias BlockScoutWeb.Cldr.Number - alias Explorer.{Chain, Repo} + alias Explorer.{Chain, CustomContractsHelpers, Repo} alias Explorer.Chain.Block.Reward alias Explorer.Chain.{Address, Block, InternalTransaction, Transaction, Wei} alias Explorer.Counters.AverageBlockTime diff --git a/apps/explorer/lib/explorer/chain/cache/token_exchange_rate.ex b/apps/explorer/lib/explorer/chain/cache/token_exchange_rate.ex index 28eb5bf205..e838761809 100644 --- a/apps/explorer/lib/explorer/chain/cache/token_exchange_rate.ex +++ b/apps/explorer/lib/explorer/chain/cache/token_exchange_rate.ex @@ -51,18 +51,18 @@ defmodule Explorer.Chain.Cache.TokenExchangeRate do {:noreply, state} end - def cache_key(symbol) do - "token_symbol_exchange_rate_#{symbol}" + def cache_key(symbol_or_address_hash_str) do + "token_symbol_exchange_rate_#{symbol_or_address_hash_str}" end - def fetch(token_hash, symbol) do - if cache_expired?(symbol) || value_is_empty?(symbol) do + def fetch(token_hash, symbol_or_address_hash_str) do + if cache_expired?(symbol_or_address_hash_str) || value_is_empty?(symbol_or_address_hash_str) do Task.start_link(fn -> - update_cache(token_hash, symbol) + update_cache(token_hash, symbol_or_address_hash_str) end) end - cached_value = fetch_from_cache(cache_key(symbol)) + cached_value = fetch_from_cache(cache_key(symbol_or_address_hash_str)) if is_nil(cached_value) || Decimal.cmp(cached_value, 0) == :eq do fetch_from_db(token_hash) @@ -73,9 +73,9 @@ defmodule Explorer.Chain.Cache.TokenExchangeRate do def cache_name, do: @cache_name - defp cache_expired?(symbol) do + defp cache_expired?(symbol_or_address_hash_str) do cache_period = token_exchange_rate_cache_period() - updated_at = fetch_from_cache("#{cache_key(symbol)}_#{@last_update_key}") + updated_at = fetch_from_cache("#{cache_key(symbol_or_address_hash_str)}_#{@last_update_key}") cond do is_nil(updated_at) -> true @@ -84,18 +84,18 @@ defmodule Explorer.Chain.Cache.TokenExchangeRate do end end - defp value_is_empty?(symbol) do - value = fetch_from_cache(cache_key(symbol)) + defp value_is_empty?(symbol_or_address_hash_str) do + value = fetch_from_cache(cache_key(symbol_or_address_hash_str)) is_nil(value) || value == 0 end - defp update_cache(token_hash, symbol) do - put_into_cache("#{cache_key(symbol)}_#{@last_update_key}", current_time()) + defp update_cache(token_hash, symbol_or_address_hash_str) do + put_into_cache("#{cache_key(symbol_or_address_hash_str)}_#{@last_update_key}", current_time()) - exchange_rate = fetch_token_exchange_rate(symbol) + exchange_rate = fetch_token_exchange_rate(symbol_or_address_hash_str) put_into_db(token_hash, exchange_rate) - put_into_cache(cache_key(symbol), exchange_rate) + put_into_cache(cache_key(symbol_or_address_hash_str), exchange_rate) end def fetch_token_exchange_rate(symbol) do diff --git a/apps/explorer/lib/explorer/chain/supply/token_bridge.ex b/apps/explorer/lib/explorer/chain/supply/token_bridge.ex index 07db4353a7..c4fd5d216e 100644 --- a/apps/explorer/lib/explorer/chain/supply/token_bridge.ex +++ b/apps/explorer/lib/explorer/chain/supply/token_bridge.ex @@ -14,7 +14,7 @@ defmodule Explorer.Chain.Supply.TokenBridge do alias Explorer.Chain.Cache.TokenExchangeRate, as: TokenExchangeRateCache alias Explorer.Counters.Bridge alias Explorer.ExchangeRates.Source - alias Explorer.Repo + alias Explorer.{CustomContractsHelpers, Repo} alias Explorer.SmartContract.Reader @token_bridge_contract_address "0x7301CFA0e1756B71869E93d4e4Dca5c7d0eb0AA6" @@ -210,7 +210,7 @@ defmodule Explorer.Chain.Supply.TokenBridge do on: t.contract_address_hash == bt.home_token_contract_address_hash, where: bt.foreign_chain_id == ^1, where: t.bridged == true, - select: {bt.home_token_contract_address_hash, t.symbol, bt.custom_cap}, + select: {bt.home_token_contract_address_hash, t.symbol, bt.custom_cap, bt.foreign_token_contract_address_hash}, order_by: [desc: t.holder_count] ) @@ -221,17 +221,19 @@ defmodule Explorer.Chain.Supply.TokenBridge do defp get_bridged_mainnet_tokens_supply(bridged_mainnet_tokens_list) do bridged_mainnet_tokens_with_supply = bridged_mainnet_tokens_list - |> Enum.map(fn {bridged_token_hash, bridged_token_symbol, bridged_token_custom_cap} -> + |> Enum.map(fn {bridged_token_hash, _bridged_token_symbol, bridged_token_custom_cap, + foreign_token_contract_address_hash} -> if bridged_token_custom_cap do {bridged_token_hash, Decimal.new(0), Decimal.new(0), bridged_token_custom_cap} else - bridged_token_price_from_cache = TokenExchangeRateCache.fetch(bridged_token_hash, bridged_token_symbol) + bridged_token_price_from_cache = + TokenExchangeRateCache.fetch(bridged_token_hash, foreign_token_contract_address_hash) bridged_token_price = if bridged_token_price_from_cache && Decimal.cmp(bridged_token_price_from_cache, 0) == :gt do bridged_token_price_from_cache else - TokenExchangeRateCache.fetch_token_exchange_rate(bridged_token_symbol) + TokenExchangeRateCache.fetch_token_exchange_rate_by_address(foreign_token_contract_address_hash) end query = @@ -266,11 +268,17 @@ defmodule Explorer.Chain.Supply.TokenBridge do end defp calc_omni_bridge_market_cap(bridged_mainnet_tokens_with_supply) do + test_token_addresses = CustomContractsHelpers.get_custom_addresses_list(:test_tokens_addresses) + config = Application.get_env(:explorer, Explorer.Counters.Bridge) disable_lp_tokens_in_market_cap = Keyword.get(config, :disable_lp_tokens_in_market_cap) omni_bridge_market_cap = bridged_mainnet_tokens_with_supply + |> Enum.filter(fn {bridged_token_hash, _, _, _} -> + bridged_token_hash_str = "0x" <> Base.encode16(bridged_token_hash.bytes, case: :lower) + !Enum.member?(test_token_addresses, bridged_token_hash_str) + end) |> Enum.reduce(Decimal.new(0), fn {_bridged_token_hash, bridged_token_price, bridged_token_balance, bridged_token_custom_cap}, acc -> @@ -278,7 +286,8 @@ defmodule Explorer.Chain.Supply.TokenBridge do Decimal.add(acc, bridged_token_custom_cap) else if bridged_token_price do - Decimal.add(acc, Decimal.mult(bridged_token_price, bridged_token_balance)) + bridged_token_cap = Decimal.mult(bridged_token_price, bridged_token_balance) + Decimal.add(acc, bridged_token_cap) else acc end diff --git a/apps/block_scout_web/lib/block_scout_web/views/custom_contracts_helpers.ex b/apps/explorer/lib/explorer/custom_contracts_helpers.ex similarity index 91% rename from apps/block_scout_web/lib/block_scout_web/views/custom_contracts_helpers.ex rename to apps/explorer/lib/explorer/custom_contracts_helpers.ex index 52a5363c1c..fa843495e7 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/custom_contracts_helpers.ex +++ b/apps/explorer/lib/explorer/custom_contracts_helpers.ex @@ -1,4 +1,4 @@ -defmodule BlockScoutWeb.CustomContractsHelpers do +defmodule Explorer.CustomContractsHelpers do @moduledoc """ Helpers to enable custom contracts themes """ diff --git a/docker/Makefile b/docker/Makefile index ce7270c2bf..826d3cd19b 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -275,6 +275,9 @@ endif ifdef DISABLE_LP_TOKENS_IN_MARKET_CAP BLOCKSCOUT_CONTAINER_PARAMS += -e 'DISABLE_LP_TOKENS_IN_MARKET_CAP=$(DISABLE_LP_TOKENS_IN_MARKET_CAP)' endif +ifdef CUSTOM_CONTRACT_ADDRESSES_TEST_TOKEN + BLOCKSCOUT_CONTAINER_PARAMS += -e 'CUSTOM_CONTRACT_ADDRESSES_TEST_TOKEN=$(CUSTOM_CONTRACT_ADDRESSES_TEST_TOKEN)' +endif HAS_BLOCKSCOUT_IMAGE := $(shell docker images | grep -sw ${DOCKER_IMAGE}) build: