Merge pull request #3318 from poanetwork/vb-safer-balancer-custom-data-extract

Safer balancer like token custom metadata extraction
pull/3319/head
Victor Baranov 4 years ago committed by GitHub
commit 8414567677
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      CHANGELOG.md
  2. 134
      apps/explorer/lib/explorer/chain.ex

@ -3,7 +3,7 @@
### Features ### Features
- [#3311](https://github.com/poanetwork/blockscout/pull/3311) - List of addresses with restricted access option - [#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 - [#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 - [#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 - [#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 - [#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"} -> {:ok, "0x"} ->
nil nil
{:ok, balancer_current_tokens_encoded} -> {:ok, "0x" <> balancer_current_tokens_encoded} ->
[balancer_current_tokens] = [balancer_current_tokens] =
balancer_current_tokens_encoded try do
|> String.trim_leading("0x") balancer_current_tokens_encoded
|> Base.decode16!(case: :mixed) |> Base.decode16!(case: :mixed)
|> TypeDecoder.decode_raw([{:array, :address}]) |> TypeDecoder.decode_raw([{:array, :address}])
rescue
_ -> []
end
bridged_token_custom_metadata = bridged_token_custom_metadata =
parse_bridged_token_custom_metadata( parse_bridged_token_custom_metadata(
@ -3792,9 +3795,18 @@ defmodule Explorer.Chain do
foreign_token_address_hash foreign_token_address_hash
) )
if is_map(bridged_token_custom_metadata), if is_map(bridged_token_custom_metadata) do
do: "#{Map.get(bridged_token_custom_metadata, :tokens)} #{Map.get(bridged_token_custom_metadata, :weights)}", tokens = Map.get(bridged_token_custom_metadata, :tokens)
else: nil 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 nil
@ -3840,7 +3852,7 @@ defmodule Explorer.Chain do
foreign_token_address_hash foreign_token_address_hash
) do ) do
balancer_current_tokens 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_hash_without_0x =
balancer_token_bytes balancer_token_bytes
|> Base.encode16(case: :lower) |> Base.encode16(case: :lower)
@ -3848,58 +3860,84 @@ defmodule Explorer.Chain do
balancer_token_hash = "0x" <> balancer_token_hash_without_0x balancer_token_hash = "0x" <> balancer_token_hash_without_0x
# 95d89b41 = keccak256(symbol()) # 95d89b41 = keccak256(symbol())
symbol_signature = "95d89b41" symbol_signature = "0x95d89b41"
{:ok, symbol_encoded} = case symbol_signature
symbol_signature |> Contract.eth_call_request(balancer_token_hash, 1, nil, nil)
|> Contract.eth_call_request(balancer_token_hash, 1, nil, nil) |> json_rpc(eth_call_foreign_json_rpc_named_arguments) do
|> json_rpc(eth_call_foreign_json_rpc_named_arguments) {:ok, "0x" <> symbol_encoded} ->
[symbol] =
symbol_encoded
|> Base.decode16!(case: :mixed)
|> TypeDecoder.decode_raw([:string])
[symbol] = # f1b8a9b7 = keccak256(getNormalizedWeight(address))
symbol_encoded get_normalized_weight_signature = "0xf1b8a9b7"
|> String.trim_leading("0x")
|> Base.decode16!(case: :mixed)
|> TypeDecoder.decode_raw([:string])
# f1b8a9b7 = keccak256(getNormalizedWeight(address)) get_normalized_weight_arg_abi_encoded =
get_normalized_weight_signature = "f1b8a9b7" [balancer_token_bytes]
|> TypeEncoder.encode([:address])
|> Base.encode16(case: :lower)
get_normalized_weight_arg_abi_encoded = get_normalized_weight_abi_encoded = get_normalized_weight_signature <> get_normalized_weight_arg_abi_encoded
[balancer_token_bytes]
|> TypeEncoder.encode([:address]) get_normalized_weight_resp =
|> Base.encode16(case: :lower) 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} = normalized_weight_to_100_perc = calc_normalized_weight_to_100_perc(normalized_weight)
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] = normalized_weight_in_perc =
normalized_weight_encoded normalized_weight_to_100_perc
|> String.trim_leading("0x") |> div(1_000_000_000_000_000_000)
|> Base.decode16!(case: :mixed)
|> TypeDecoder.decode_raw([{:uint, 256}])
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 = tokens_value = combine_tokens_value(current_tokens, symbol)
normalized_weight_to_100_perc weights_value = combine_weights_value(current_weights, normalized_weight_in_perc)
|> div(1_000_000_000_000_000_000)
current_tokens = Map.get(acc, :tokens) %{:tokens => tokens_value, :weights => weights_value}
current_weights = Map.get(acc, :weights)
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 = defp combine_tokens_value(current_tokens, symbol) do
if current_weights == "", if current_tokens == "", do: symbol, else: current_tokens <> "/" <> symbol
do: "#{normalized_weight_in_perc}", end
else: current_weights <> "/" <> "#{normalized_weight_in_perc}"
%{:tokens => tokens_value, :weights => weights_value} defp combine_weights_value(current_weights, normalized_weight_in_perc) do
end) if current_weights == "",
do: "#{normalized_weight_in_perc}",
else: current_weights <> "/" <> "#{normalized_weight_in_perc}"
end end
@doc """ @doc """

Loading…
Cancel
Save