From bc8152f4199961cd877996f280a09f8c02d2a902 Mon Sep 17 00:00:00 2001 From: Damian Ramirez Date: Fri, 27 Dec 2024 10:31:53 -0300 Subject: [PATCH] fix(levm): change error to empty bytes in ecrecover (#1570) **Motivation** We should return empty bytes when there are errors in the `libsecp256k1` functions. Errors should only be returned in cases of analysis or cutting. **Description** Previously, we returned `PrecompileError::ParsingInputError` when `Message::parse_slice` or `Signature::parse_standard_slice` failed. Also, we were inconsistent, sometimes returning an error and other times returning empty bytes. Now, we return `Bytes::new()` whenever the `libsecp256k1` functions fail. --- crates/vm/levm/src/precompiles.rs | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/crates/vm/levm/src/precompiles.rs b/crates/vm/levm/src/precompiles.rs index e69ead288..b37eaa5da 100644 --- a/crates/vm/levm/src/precompiles.rs +++ b/crates/vm/levm/src/precompiles.rs @@ -164,7 +164,9 @@ pub fn ecrecover( // Parse the input elements, first as a slice of bytes and then as an specific type of the crate let hash = calldata.get(0..32).ok_or(InternalError::SlicingError)?; - let message = Message::parse_slice(hash).map_err(|_| PrecompileError::ParsingInputError)?; + let Ok(message) = Message::parse_slice(hash) else { + return Ok(Bytes::new()); + }; let v: U256 = calldata .get(32..64) @@ -177,26 +179,22 @@ pub fn ecrecover( } let v = u8::try_from(v).map_err(|_| InternalError::ConversionError)?; - let recovery_id = match RecoveryId::parse_rpc(v) { - Ok(id) => id, - Err(_) => { - return Ok(Bytes::new()); - } + let Ok(recovery_id) = RecoveryId::parse_rpc(v) else { + return Ok(Bytes::new()); }; // signature is made up of the parameters r and s let sig = calldata.get(64..128).ok_or(InternalError::SlicingError)?; - let signature = - Signature::parse_standard_slice(sig).map_err(|_| PrecompileError::ParsingInputError)?; + let Ok(signature) = Signature::parse_standard_slice(sig) else { + return Ok(Bytes::new()); + }; // Recover the address using secp256k1 - let mut public_key = match libsecp256k1::recover(&message, &signature, &recovery_id) { - Ok(id) => id, - Err(_) => { - return Ok(Bytes::new()); - } - } - .serialize(); + let Ok(public_key) = libsecp256k1::recover(&message, &signature, &recovery_id) else { + return Ok(Bytes::new()); + }; + + let mut public_key = public_key.serialize(); // We need to take the 64 bytes from the public key (discarding the first pos of the slice) keccak256(&mut public_key[1..65]);