diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ad6ec7098..6cdeb00148 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ - [#1790](https://github.com/poanetwork/blockscout/pull/1790) - fix constructor arguments verification - [#1793](https://github.com/poanetwork/blockscout/pull/1793) - fix top nav autocomplete - [#1795](https://github.com/poanetwork/blockscout/pull/1795) - fix line numbers for decompiled contracts + - [#1803](https://github.com/poanetwork/blockscout/pull/1803) - use coinmarketcap for total_supply by default - [#1802](https://github.com/poanetwork/blockscout/pull/1802) - make coinmarketcap's number of pages configurable - [#1799](https://github.com/poanetwork/blockscout/pull/1799) - Use eth_getUncleByBlockHashAndIndex for uncle block fetching diff --git a/apps/block_scout_web/test/block_scout_web/channels/exchange_rate_channel_test.exs b/apps/block_scout_web/test/block_scout_web/channels/exchange_rate_channel_test.exs index 7c495e6bfc..acdf441750 100644 --- a/apps/block_scout_web/test/block_scout_web/channels/exchange_rate_channel_test.exs +++ b/apps/block_scout_web/test/block_scout_web/channels/exchange_rate_channel_test.exs @@ -21,6 +21,7 @@ defmodule BlockScoutWeb.ExchangeRateChannelTest do token = %Token{ available_supply: Decimal.new("1000000.0"), + total_supply: Decimal.new("1000000.0"), btc_value: Decimal.new("1.000"), id: "test", last_updated: DateTime.utc_now(), diff --git a/apps/block_scout_web/test/block_scout_web/controllers/api/rpc/stats_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/api/rpc/stats_controller_test.exs index fe8311daf1..7c47ed622e 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/api/rpc/stats_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/api/rpc/stats_controller_test.exs @@ -122,6 +122,7 @@ defmodule BlockScoutWeb.API.RPC.StatsControllerTest do eth = %Token{ available_supply: Decimal.new("1000000.0"), + total_supply: Decimal.new("1000000.0"), btc_value: Decimal.new("1.000"), id: "test", last_updated: DateTime.utc_now(), diff --git a/apps/block_scout_web/test/block_scout_web/views/address_view_test.exs b/apps/block_scout_web/test/block_scout_web/views/address_view_test.exs index 6219017c1a..0809850163 100644 --- a/apps/block_scout_web/test/block_scout_web/views/address_view_test.exs +++ b/apps/block_scout_web/test/block_scout_web/views/address_view_test.exs @@ -134,7 +134,9 @@ defmodule BlockScoutWeb.AddressViewTest do end test "balance_percentage/1" do + Application.put_env(:explorer, :supply, Explorer.Chain.Supply.ProofOfAuthority) address = insert(:address, fetched_coin_balance: 2_524_608_000_000_000_000_000_000) + assert "1.0000% Market Cap" = AddressView.balance_percentage(address) end diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index d99bd09661..b45e0d13e4 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -2373,7 +2373,7 @@ defmodule Explorer.Chain do end defp supply_module do - Application.get_env(:explorer, :supply, Explorer.Chain.Supply.ProofOfAuthority) + Application.get_env(:explorer, :supply, Explorer.Chain.Supply.CoinMarketCap) end @doc """ diff --git a/apps/explorer/lib/explorer/chain/supply/coin_market_cap.ex b/apps/explorer/lib/explorer/chain/supply/coin_market_cap.ex new file mode 100644 index 0000000000..ebaadb3c47 --- /dev/null +++ b/apps/explorer/lib/explorer/chain/supply/coin_market_cap.ex @@ -0,0 +1,22 @@ +defmodule Explorer.Chain.Supply.CoinMarketCap do + @moduledoc """ + Defines the supply API for calculating supply for coins from coinmarketcap. + """ + + use Explorer.Chain.Supply + + alias Explorer.ExchangeRates.Token + alias Explorer.Market + + def circulating do + exchange_rate().available_supply + end + + def total do + exchange_rate().total_supply + end + + def exchange_rate do + Market.get_exchange_rate(Explorer.coin()) || Token.null() + end +end diff --git a/apps/explorer/lib/explorer/exchange_rates/source/coin_gecko.ex b/apps/explorer/lib/explorer/exchange_rates/source/coin_gecko.ex index 4ad4c98292..4e59537bf6 100644 --- a/apps/explorer/lib/explorer/exchange_rates/source/coin_gecko.ex +++ b/apps/explorer/lib/explorer/exchange_rates/source/coin_gecko.ex @@ -26,6 +26,7 @@ defmodule Explorer.ExchangeRates.Source.CoinGecko do %Token{ available_supply: to_decimal(item["total_supply"]), + total_supply: to_decimal(item["total_supply"]), btc_value: btc_value, id: id, last_updated: last_updated, diff --git a/apps/explorer/lib/explorer/exchange_rates/source/coin_market_cap.ex b/apps/explorer/lib/explorer/exchange_rates/source/coin_market_cap.ex index 03d957e305..efe592e0fa 100644 --- a/apps/explorer/lib/explorer/exchange_rates/source/coin_market_cap.ex +++ b/apps/explorer/lib/explorer/exchange_rates/source/coin_market_cap.ex @@ -17,6 +17,7 @@ defmodule Explorer.ExchangeRates.Source.CoinMarketCap do %Token{ available_supply: to_decimal(item["available_supply"]), + total_supply: to_decimal(item["total_supply"]), btc_value: to_decimal(item["price_btc"]), id: item["id"], last_updated: last_updated, diff --git a/apps/explorer/lib/explorer/exchange_rates/source/transaction_and_log.ex b/apps/explorer/lib/explorer/exchange_rates/source/transaction_and_log.ex index a3dfafecaa..2b8699accc 100644 --- a/apps/explorer/lib/explorer/exchange_rates/source/transaction_and_log.ex +++ b/apps/explorer/lib/explorer/exchange_rates/source/transaction_and_log.ex @@ -26,6 +26,7 @@ defmodule Explorer.ExchangeRates.Source.TransactionAndLog do defp build_struct(original_token) do %Token{ available_supply: to_decimal(Chain.circulating_supply()), + total_supply: 0, btc_value: original_token.btc_value, id: original_token.id, last_updated: original_token.last_updated, diff --git a/apps/explorer/lib/explorer/exchange_rates/token.ex b/apps/explorer/lib/explorer/exchange_rates/token.ex index 3df8cbd56b..6521181c12 100644 --- a/apps/explorer/lib/explorer/exchange_rates/token.ex +++ b/apps/explorer/lib/explorer/exchange_rates/token.ex @@ -7,6 +7,7 @@ defmodule Explorer.ExchangeRates.Token do Represents an exchange rate for a given token. * `:available_supply` - Available supply of a token + * `:total_supply` - Max Supply * `:btc_value` - The Bitcoin value of the currency * `:id` - ID of a currency * `:last_updated` - Timestamp of when the value was last updated @@ -18,6 +19,7 @@ defmodule Explorer.ExchangeRates.Token do """ @type t :: %__MODULE__{ available_supply: Decimal.t(), + total_supply: Decimal.t(), btc_value: Decimal.t(), id: String.t(), last_updated: DateTime.t(), @@ -28,8 +30,8 @@ defmodule Explorer.ExchangeRates.Token do volume_24h_usd: Decimal.t() } - @enforce_keys ~w(available_supply btc_value id last_updated market_cap_usd name symbol usd_value volume_24h_usd)a - defstruct ~w(available_supply btc_value id last_updated market_cap_usd name symbol usd_value volume_24h_usd)a + @enforce_keys ~w(available_supply total_supply btc_value id last_updated market_cap_usd name symbol usd_value volume_24h_usd)a + defstruct ~w(available_supply total_supply btc_value id last_updated market_cap_usd name symbol usd_value volume_24h_usd)a def null, do: %__MODULE__{ @@ -37,6 +39,7 @@ defmodule Explorer.ExchangeRates.Token do id: nil, name: nil, available_supply: nil, + total_supply: nil, usd_value: nil, volume_24h_usd: nil, market_cap_usd: nil, @@ -51,6 +54,7 @@ defmodule Explorer.ExchangeRates.Token do id: id, name: name, available_supply: available_supply, + total_supply: total_supply, usd_value: usd_value, volume_24h_usd: volume_24h_usd, market_cap_usd: market_cap_usd, @@ -58,17 +62,20 @@ defmodule Explorer.ExchangeRates.Token do last_updated: last_updated }) do # symbol is first because it is the key used for lookup in `Explorer.ExchangeRates`'s ETS table - {symbol, id, name, available_supply, usd_value, volume_24h_usd, market_cap_usd, btc_value, last_updated} + {symbol, id, name, available_supply, total_supply, usd_value, volume_24h_usd, market_cap_usd, btc_value, + last_updated} end def from_tuple( - {symbol, id, name, available_supply, usd_value, volume_24h_usd, market_cap_usd, btc_value, last_updated} + {symbol, id, name, available_supply, total_supply, usd_value, volume_24h_usd, market_cap_usd, btc_value, + last_updated} ) do %__MODULE__{ symbol: symbol, id: id, name: name, available_supply: available_supply, + total_supply: total_supply, usd_value: usd_value, volume_24h_usd: volume_24h_usd, market_cap_usd: market_cap_usd, diff --git a/apps/explorer/test/explorer/chain_test.exs b/apps/explorer/test/explorer/chain_test.exs index 41c5afad71..36edace635 100644 --- a/apps/explorer/test/explorer/chain_test.exs +++ b/apps/explorer/test/explorer/chain_test.exs @@ -3276,6 +3276,7 @@ defmodule Explorer.ChainTest do end test "total_supply/0" do + Application.put_env(:explorer, :supply, Explorer.Chain.Supply.ProofOfAuthority) height = 2_000_000 insert(:block, number: height) expected = ProofOfAuthority.initial_supply() + height @@ -3284,6 +3285,7 @@ defmodule Explorer.ChainTest do end test "circulating_supply/0" do + Application.put_env(:explorer, :supply, Explorer.Chain.Supply.ProofOfAuthority) assert Chain.circulating_supply() == ProofOfAuthority.circulating() end diff --git a/apps/explorer/test/explorer/exchange_rates/exchange_rates_test.exs b/apps/explorer/test/explorer/exchange_rates/exchange_rates_test.exs index 254c7469ba..1d44a7adce 100644 --- a/apps/explorer/test/explorer/exchange_rates/exchange_rates_test.exs +++ b/apps/explorer/test/explorer/exchange_rates/exchange_rates_test.exs @@ -68,6 +68,7 @@ defmodule Explorer.ExchangeRatesTest do test "with successful fetch" do expected_token = %Token{ available_supply: Decimal.new("1000000.0"), + total_supply: Decimal.new("1000000.0"), btc_value: Decimal.new("1.000"), id: "test_id", last_updated: DateTime.utc_now(), diff --git a/apps/explorer/test/explorer/exchange_rates/source/coin_gecko_test.exs b/apps/explorer/test/explorer/exchange_rates/source/coin_gecko_test.exs index 5317426ddd..3c2a9b6feb 100644 --- a/apps/explorer/test/explorer/exchange_rates/source/coin_gecko_test.exs +++ b/apps/explorer/test/explorer/exchange_rates/source/coin_gecko_test.exs @@ -64,6 +64,7 @@ defmodule Explorer.ExchangeRates.Source.CoinGeckoTest do expected = [ %Token{ available_supply: Decimal.new("252193195"), + total_supply: Decimal.new("252193195"), btc_value: Decimal.new("0.00001753101509231471092879666458"), id: "poa-network", last_updated: expected_date, diff --git a/apps/explorer/test/explorer/exchange_rates/source/coin_market_cap_test.exs b/apps/explorer/test/explorer/exchange_rates/source/coin_market_cap_test.exs index 888cb5875c..e0f1693212 100644 --- a/apps/explorer/test/explorer/exchange_rates/source/coin_market_cap_test.exs +++ b/apps/explorer/test/explorer/exchange_rates/source/coin_market_cap_test.exs @@ -33,6 +33,7 @@ defmodule Explorer.ExchangeRates.Source.CoinMarketCapTest do expected = [ %Token{ available_supply: Decimal.new("203981804.0"), + total_supply: Decimal.new("254473964.0"), btc_value: Decimal.new("0.00007032"), id: "poa-network", last_updated: expected_date, diff --git a/apps/explorer/test/support/fakes/one_coin_source.ex b/apps/explorer/test/support/fakes/one_coin_source.ex index 73bb104866..72ba399bf9 100644 --- a/apps/explorer/test/support/fakes/one_coin_source.ex +++ b/apps/explorer/test/support/fakes/one_coin_source.ex @@ -10,6 +10,7 @@ defmodule Explorer.ExchangeRates.Source.OneCoinSource do def format_data(_) do pseudo_token = %Token{ available_supply: Decimal.new(10_000_000), + total_supply: Decimal.new(10_000_000_000), btc_value: Decimal.new(1), id: "", last_updated: Timex.now(),