Open code423n4 opened 3 years ago
Excellent bug report.
I just ran into the buffer limit issue this morning with an Ethereum block. I agree handling this error correctly is essential to long term reliability.
Nice :)
reopening as per judges assessment as "primary issue" on findings sheet
Handle
nascent
Vulnerability details
Ethereum Oracles watch for events on the
Gravity.sol
contract on the Ethereum blockchain. This is performed in thecheck_for_events
function, ran in theeth_oracle_main_loop
.In this function, there is the following code snippet:
This snippet leverages the
web30
library to check for events from thestarting_block
to thelatest_block
. Inside theweb30
library this nets out to calling:The
10_000_000
specifies the maximum size of the return in bytes and returns an error if the return is larger:This can be triggered at will and keep the loop in a perpetual state of returning the
GravityError::EthereumRestError(Web3Error::BadResponse( "Failed to get logs!".to_string()))
error. To force the node into this state, you just have to deploy ERC20s generated by the public function inGravity.sol
:And specify a large string as the denom, name, or symbol. If an attacker uses the denom as the attack vector, they save significant gas costing just 256 per additional 32 bytes. For other cases, to avoid gas overhead, you can have the string be mostly 0s resulting in just 584 gas per additional 32 bytes. This leaves it feasible to surpass the 10mb response data in the 6 block buffer. This would throw every ethereum oracle into a state of perpetual errors and all would fall out of sync with the ethereum blockchain. This would result in the batches, logic calls, deposits, ERC20 creations, and valset updates to never receive attestations from other validators because their ethereum oracles would be down; the bridge would be frozen and remain frozen until the bug is fixed due to
get_last_checked_block
.This will freeze the bridge by disallowing attestations to take place.
This requires a patch to reenable the bridge.
Recommendation
Handle the error more concretely and check if you got a byte limit error. If you did, chunk the search size into 2 and try again. Repeat as necessary, and combine the results.
Additionally, you could require that validators sign ERC20 creation requests.