Skip to content

Commit

Permalink
Merge pull request blockscout#4807 from blockscout/np-add-support-for…
Browse files Browse the repository at this point in the history
…-beacon-proxy-pattern

Add support for BeaconProxy pattern
  • Loading branch information
vbaranov authored and jagdeep sidhu committed Nov 3, 2021
1 parent 9578f4e commit 6cb0175
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## Current

### Features
- [#4807](https://github.com/blockscout/blockscout/pull/4807) - Added support for BeaconProxy pattern
- [#4777](https://github.com/blockscout/blockscout/pull/4777), [#4791](https://github.com/blockscout/blockscout/pull/4791), [#4799](https://github.com/blockscout/blockscout/pull/4799), [#4847](https://github.com/blockscout/blockscout/pull/4847) - Added decoding revert reason
- [#4776](https://github.com/blockscout/blockscout/pull/4776) - Added view for unsuccessfully fetched values from read functions
- [#4761](https://github.com/blockscout/blockscout/pull/4761) - ERC-1155 support
Expand Down
71 changes: 51 additions & 20 deletions apps/explorer/lib/explorer/chain.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6790,30 +6790,17 @@ defmodule Explorer.Chain do

# https://eips.ethereum.org/EIPS/eip-1967
storage_slot_logic_contract_address = "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"
storage_slot_beacon_contract_address = "0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50"

{status, implementation_address} =
{_status, implementation_address} =
case Contract.eth_get_storage_at_request(
proxy_address_hash,
storage_slot_logic_contract_address,
nil,
json_rpc_named_arguments
) do
{:ok, "0x"} ->
Contract.eth_get_storage_at_request(
proxy_address_hash,
storage_slot_beacon_contract_address,
nil,
json_rpc_named_arguments
)

{:ok, "0x0000000000000000000000000000000000000000000000000000000000000000"} ->
Contract.eth_get_storage_at_request(
proxy_address_hash,
storage_slot_beacon_contract_address,
nil,
json_rpc_named_arguments
)
{:ok, empty_address}
when empty_address in ["0x", "0x0000000000000000000000000000000000000000000000000000000000000000"] ->
fetch_beacon_proxy_implementation(proxy_address_hash, json_rpc_named_arguments)

{:ok, implementation_logic_address} ->
{:ok, implementation_logic_address}
Expand All @@ -6822,7 +6809,49 @@ defmodule Explorer.Chain do
{:ok, "0x"}
end

abi_decode_address_output(if status == :ok, do: implementation_address, else: "0x")
abi_decode_address_output(implementation_address)
end

# changes requested by https://github.com/blockscout/blockscout/issues/4770
# for support BeaconProxy pattern
defp fetch_beacon_proxy_implementation(proxy_address_hash, json_rpc_named_arguments) do
# https://eips.ethereum.org/EIPS/eip-1967
storage_slot_beacon_contract_address = "0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50"

implementation_method_abi = [
%{
"type" => "function",
"stateMutability" => "view",
"outputs" => [%{"type" => "address", "name" => "", "internalType" => "address"}],
"name" => "implementation",
"inputs" => []
}
]

case Contract.eth_get_storage_at_request(
proxy_address_hash,
storage_slot_beacon_contract_address,
nil,
json_rpc_named_arguments
) do
{:ok, empty_address}
when empty_address in ["0x", "0x0000000000000000000000000000000000000000000000000000000000000000"] ->
{:ok, "0x"}

{:ok, beacon_contract_address} ->
case beacon_contract_address
|> abi_decode_address_output()
|> get_implementation_address_hash_basic(implementation_method_abi) do
<<implementation_address::binary-size(42)>> ->
{:ok, implementation_address}

_ ->
{:ok, beacon_contract_address}
end

{:error, _} ->
{:ok, "0x"}
end
end

defp get_implementation_address_hash_basic(proxy_address_hash, abi) do
Expand Down Expand Up @@ -6880,18 +6909,20 @@ defmodule Explorer.Chain do
end)
end

defp abi_decode_address_output(address) when is_nil(address), do: nil
defp abi_decode_address_output(nil), do: nil

defp abi_decode_address_output("0x"), do: @burn_address_hash_str

defp abi_decode_address_output(address) do
defp abi_decode_address_output(address) when is_binary(address) do
if String.length(address) > 42 do
"0x" <> String.slice(address, -40, 40)
else
address
end
end

defp abi_decode_address_output(_), do: nil

defp address_to_hex(address) do
if address do
if String.starts_with?(address, "0x") do
Expand Down

0 comments on commit 6cb0175

Please sign in to comment.