-
Notifications
You must be signed in to change notification settings - Fork 996
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ethereum: Fix adapter to filter proxy calls #3219
Conversation
Without this the line that does `function_abi.decode_input(&call.input.0[4..])` was failing with the Err(InvalidData). For some reason some of the OpenSea Proxy contracts don't get recognized as DELEGATECALL, instead they are seen as CALLs, but you can identify them by the input having the wrong size since it's a fallback function call. A scenario to exemplify the problem, can be seen in this transaction: 0x4499dc75facb4cd27894196aac00bcb0ffbe3d64de87105878451d5637662f90 We would get the traces for the block 14043345 (0xD648D1) for the contract 0x7Be8076f4EA4A4AD08075C2508e481d6C946D12b. Then we would find two CALLs for the `atomicMatch_` function. However the first one would have the wrong size (fail at decoding) and the second one would be correct. That's because of the proxy and because of how fallbacks are compiled from Solidity (omitting the function signature, aka a feel bytes less).
58e938d
to
c2729db
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved after a few refactors
chain/ethereum/src/adapter.rs
Outdated
if let None = v { | ||
return false; | ||
} | ||
|
||
let signature = &v.unwrap().1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if let None = v { | |
return false; | |
} | |
let signature = &v.unwrap().1; | |
let signature = match v { | |
None => return false, | |
Some(v) => &v.1, | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've wrapped this suggestion with the self.contract_addresses_function_signatures.get(&call.to)
function call, so there's no more v
let definition.
chain/ethereum/src/adapter.rs
Outdated
let correct_fn = signature.contains(&call.input.0[..4]); | ||
// Not multiple of 32, wrong length to decode parameters. | ||
// This is probably a delegatecall disguised as a regular call | ||
// via fallback. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reference you can link here if somebody wants to better understand how this happens? Maybe link an example trace in etherscan?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've improved the comment, can you check if it's good now please?
chain/ethereum/src/adapter.rs
Outdated
let wrong_input_size = (call.input.0.len() - 4) % 32 != 0; | ||
|
||
correct_fn && !wrong_input_size |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let wrong_input_size = (call.input.0.len() - 4) % 32 != 0; | |
correct_fn && !wrong_input_size | |
let correct_input_size = (call.input.0.len() - 4) % 32 == 0; | |
correct_fn && correct_input_size |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done 😊
b723457
to
b21ac40
Compare
* ethereum: Fix adapter to filter proxy calls Without this the line that does `function_abi.decode_input(&call.input.0[4..])` was failing with the Err(InvalidData). For some reason some of the OpenSea Proxy contracts don't get recognized as DELEGATECALL, instead they are seen as CALLs, but you can identify them by the input having the wrong size since it's a fallback function call. A scenario to exemplify the problem, can be seen in this transaction: 0x4499dc75facb4cd27894196aac00bcb0ffbe3d64de87105878451d5637662f90 We would get the traces for the block 14043345 (0xD648D1) for the contract 0x7Be8076f4EA4A4AD08075C2508e481d6C946D12b. Then we would find two CALLs for the `atomicMatch_` function. However the first one would have the wrong size (fail at decoding) and the second one would be correct. That's because of the proxy and because of how fallbacks are compiled from Solidity (omitting the function signature, aka a feel bytes less). * ethereum: Apply code review suggestions for the adapter * ethereum: Elaborate/improve comment about call input size
* ethereum: Fix adapter to filter proxy calls Without this the line that does `function_abi.decode_input(&call.input.0[4..])` was failing with the Err(InvalidData). For some reason some of the OpenSea Proxy contracts don't get recognized as DELEGATECALL, instead they are seen as CALLs, but you can identify them by the input having the wrong size since it's a fallback function call. A scenario to exemplify the problem, can be seen in this transaction: 0x4499dc75facb4cd27894196aac00bcb0ffbe3d64de87105878451d5637662f90 We would get the traces for the block 14043345 (0xD648D1) for the contract 0x7Be8076f4EA4A4AD08075C2508e481d6C946D12b. Then we would find two CALLs for the `atomicMatch_` function. However the first one would have the wrong size (fail at decoding) and the second one would be correct. That's because of the proxy and because of how fallbacks are compiled from Solidity (omitting the function signature, aka a feel bytes less). * ethereum: Apply code review suggestions for the adapter * ethereum: Elaborate/improve comment about call input size
Without this the line that does
function_abi.decode_input(&call.input.0[4..])
was failing with theErr(InvalidData)
.For some reason some of the OpenSea Proxy contracts don't get recognized as DELEGATECALL, instead they are seen as CALLs, but you can identify them by the input having the wrong size since it's a fallback function call.
A scenario to exemplify the problem, can be seen in this transaction: 0x4499dc75facb4cd27894196aac00bcb0ffbe3d64de87105878451d5637662f90.
We would get the traces for the block
14043345
(0xD648D1
) for the contract0x7Be8076f4EA4A4AD08075C2508e481d6C946D12b
. Then we would find two CALLs for theatomicMatch_
function. However the first one would have the wrong size (fail at decoding) and the second one would be correct.That's because of the proxy and because of how fallbacks are compiled from Solidity (omitting the function signature, aka a feel bytes less).
Ethereum ABI (d)ecoding docs: https://docs.soliditylang.org/en/v0.8.11/abi-spec.html.
Fixes #3194