From 15fa30c9b2b72eec0c2fa59f485ac5f7043330e9 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Tue, 6 Feb 2024 16:52:09 +0100 Subject: [PATCH] fix: don't validate when decoding revert reason --- crates/sol-types/src/types/error.rs | 16 ++++++++++++++++ crates/sol-types/src/types/interface/mod.rs | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/crates/sol-types/src/types/error.rs b/crates/sol-types/src/types/error.rs index df854d267..25046d568 100644 --- a/crates/sol-types/src/types/error.rs +++ b/crates/sol-types/src/types/error.rs @@ -467,6 +467,22 @@ mod tests { assert_eq!(decoded, revert.to_string()); } + #[test] + fn decode_uniswap_revert() { + // Solc 0.5.X/0.5.16 adds a random 0x80 byte which makes reserialization check fail. + // https://github.com/Uniswap/v2-core/blob/ee547b17853e71ed4e0101ccfd52e70d5acded58/contracts/UniswapV2Pair.sol#L178 + // https://github.com/paradigmxyz/evm-inspectors/pull/12 + let bytes = hex!("08c379a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000024556e697377617056323a20494e53554646494349454e545f494e5055545f414d4f554e5400000000000000000000000000000000000000000000000000000080"); + + Revert::abi_decode(&bytes, true).unwrap_err(); + + let decoded = Revert::abi_decode(&bytes, false).unwrap(); + assert_eq!(decoded.reason, "UniswapV2: INSUFFICIENT_INPUT_AMOUNT"); + + let decoded = decode_revert_reason(&bytes).unwrap(); + assert_eq!(decoded, "revert: UniswapV2: INSUFFICIENT_INPUT_AMOUNT"); + } + #[test] fn decode_random_revert_reason() { let revert_reason = String::from("test_revert_reason"); diff --git a/crates/sol-types/src/types/interface/mod.rs b/crates/sol-types/src/types/interface/mod.rs index 3362acbea..bfc8243c8 100644 --- a/crates/sol-types/src/types/interface/mod.rs +++ b/crates/sol-types/src/types/interface/mod.rs @@ -433,7 +433,7 @@ where /// If both attempts fail, it returns `None`. pub fn decode(out: &[u8]) -> Option { // Try to decode as a generic contract error. - if let Ok(error) = ContractError::::abi_decode(out, true) { + if let Ok(error) = ContractError::::abi_decode(out, false) { return Some(error.into()); }