Safer balancer like token custom metadata extraction

pull/3318/head
Victor Baranov 4 years ago
parent 7b9d0cc496
commit 6e864715ae
  1. 2
      CHANGELOG.md
  2. 134
      apps/explorer/lib/explorer/chain.ex

@ -3,7 +3,7 @@
### Features
- [#3311](https://github.com/poanetwork/blockscout/pull/3311) - List of addresses with restricted access option
- [#3293](https://github.com/poanetwork/blockscout/pull/3293) - Composite market cap for xDai: TokenBridge + OmniBridge
- [#3282](https://github.com/poanetwork/blockscout/pull/3282) - Import bridged tokens custom metadata
- [#3282](https://github.com/poanetwork/blockscout/pull/3282), [#3318](https://github.com/poanetwork/blockscout/pull/3318) - Import bridged tokens custom metadata
- [#3281](https://github.com/poanetwork/blockscout/pull/3281) - Write contract: display currently connected address
- [#3279](https://github.com/poanetwork/blockscout/pull/3279) - NFT instance: link to the app
- [#3278](https://github.com/poanetwork/blockscout/pull/3278) - Support of fetching of NFT metadata from IPFS

@ -3778,12 +3778,15 @@ defmodule Explorer.Chain do
{:ok, "0x"} ->
nil
{:ok, balancer_current_tokens_encoded} ->
{:ok, "0x" <> balancer_current_tokens_encoded} ->
[balancer_current_tokens] =
balancer_current_tokens_encoded
|> String.trim_leading("0x")
|> Base.decode16!(case: :mixed)
|> TypeDecoder.decode_raw([{:array, :address}])
try do
balancer_current_tokens_encoded
|> Base.decode16!(case: :mixed)
|> TypeDecoder.decode_raw([{:array, :address}])
rescue
_ -> []
end
bridged_token_custom_metadata =
parse_bridged_token_custom_metadata(
@ -3792,9 +3795,18 @@ defmodule Explorer.Chain do
foreign_token_address_hash
)
if is_map(bridged_token_custom_metadata),
do: "#{Map.get(bridged_token_custom_metadata, :tokens)} #{Map.get(bridged_token_custom_metadata, :weights)}",
else: nil
if is_map(bridged_token_custom_metadata) do
tokens = Map.get(bridged_token_custom_metadata, :tokens)
weights = Map.get(bridged_token_custom_metadata, :weights)
if tokens == "" do
nil
else
if weights !== "", do: "#{tokens} #{weights}", else: tokens
end
else
nil
end
_ ->
nil
@ -3840,7 +3852,7 @@ defmodule Explorer.Chain do
foreign_token_address_hash
) do
balancer_current_tokens
|> Enum.reduce(%{:tokens => "", :weights => ""}, fn balancer_token_bytes, acc ->
|> Enum.reduce(%{:tokens => "", :weights => ""}, fn balancer_token_bytes, balancer_tokens_weights ->
balancer_token_hash_without_0x =
balancer_token_bytes
|> Base.encode16(case: :lower)
@ -3848,58 +3860,84 @@ defmodule Explorer.Chain do
balancer_token_hash = "0x" <> balancer_token_hash_without_0x
# 95d89b41 = keccak256(symbol())
symbol_signature = "95d89b41"
symbol_signature = "0x95d89b41"
{:ok, symbol_encoded} =
symbol_signature
|> Contract.eth_call_request(balancer_token_hash, 1, nil, nil)
|> json_rpc(eth_call_foreign_json_rpc_named_arguments)
case symbol_signature
|> Contract.eth_call_request(balancer_token_hash, 1, nil, nil)
|> json_rpc(eth_call_foreign_json_rpc_named_arguments) do
{:ok, "0x" <> symbol_encoded} ->
[symbol] =
symbol_encoded
|> Base.decode16!(case: :mixed)
|> TypeDecoder.decode_raw([:string])
[symbol] =
symbol_encoded
|> String.trim_leading("0x")
|> Base.decode16!(case: :mixed)
|> TypeDecoder.decode_raw([:string])
# f1b8a9b7 = keccak256(getNormalizedWeight(address))
get_normalized_weight_signature = "0xf1b8a9b7"
# f1b8a9b7 = keccak256(getNormalizedWeight(address))
get_normalized_weight_signature = "f1b8a9b7"
get_normalized_weight_arg_abi_encoded =
[balancer_token_bytes]
|> TypeEncoder.encode([:address])
|> Base.encode16(case: :lower)
get_normalized_weight_arg_abi_encoded =
[balancer_token_bytes]
|> TypeEncoder.encode([:address])
|> Base.encode16(case: :lower)
get_normalized_weight_abi_encoded = get_normalized_weight_signature <> get_normalized_weight_arg_abi_encoded
get_normalized_weight_resp =
get_normalized_weight_abi_encoded
|> Contract.eth_call_request(foreign_token_address_hash, 1, nil, nil)
|> json_rpc(eth_call_foreign_json_rpc_named_arguments)
parse_balancer_weights(get_normalized_weight_resp, balancer_tokens_weights, symbol)
_ ->
nil
end
end)
end
get_normalized_weight_abi_encoded = get_normalized_weight_signature <> get_normalized_weight_arg_abi_encoded
defp parse_balancer_weights(get_normalized_weight_resp, balancer_tokens_weights, symbol) do
case get_normalized_weight_resp do
{:ok, "0x" <> normalized_weight_encoded} ->
[normalized_weight] =
try do
normalized_weight_encoded
|> Base.decode16!(case: :mixed)
|> TypeDecoder.decode_raw([{:uint, 256}])
rescue
_ ->
[]
end
{:ok, normalized_weight_encoded} =
get_normalized_weight_abi_encoded
|> Contract.eth_call_request(foreign_token_address_hash, 1, nil, nil)
|> json_rpc(eth_call_foreign_json_rpc_named_arguments)
normalized_weight_to_100_perc = calc_normalized_weight_to_100_perc(normalized_weight)
[normalized_weight] =
normalized_weight_encoded
|> String.trim_leading("0x")
|> Base.decode16!(case: :mixed)
|> TypeDecoder.decode_raw([{:uint, 256}])
normalized_weight_in_perc =
normalized_weight_to_100_perc
|> div(1_000_000_000_000_000_000)
normalized_weight_to_100_perc = 100 * normalized_weight
current_tokens = Map.get(balancer_tokens_weights, :tokens)
current_weights = Map.get(balancer_tokens_weights, :weights)
normalized_weight_in_perc =
normalized_weight_to_100_perc
|> div(1_000_000_000_000_000_000)
tokens_value = combine_tokens_value(current_tokens, symbol)
weights_value = combine_weights_value(current_weights, normalized_weight_in_perc)
current_tokens = Map.get(acc, :tokens)
current_weights = Map.get(acc, :weights)
%{:tokens => tokens_value, :weights => weights_value}
tokens_value = if current_tokens == "", do: symbol, else: current_tokens <> "/" <> symbol
_ ->
nil
end
end
defp calc_normalized_weight_to_100_perc(normalized_weight) do
if normalized_weight, do: 100 * normalized_weight, else: 0
end
weights_value =
if current_weights == "",
do: "#{normalized_weight_in_perc}",
else: current_weights <> "/" <> "#{normalized_weight_in_perc}"
defp combine_tokens_value(current_tokens, symbol) do
if current_tokens == "", do: symbol, else: current_tokens <> "/" <> symbol
end
%{:tokens => tokens_value, :weights => weights_value}
end)
defp combine_weights_value(current_weights, normalized_weight_in_perc) do
if current_weights == "",
do: "#{normalized_weight_in_perc}",
else: current_weights <> "/" <> "#{normalized_weight_in_perc}"
end
@doc """

Loading…
Cancel
Save