rust-ethereum-abi icon indicating copy to clipboard operation
rust-ethereum-abi copied to clipboard

Overflow when decoding multicall transaction

Open lukerhoads opened this issue 2 years ago • 6 comments

struct TestCase {
            data: String,
            types: Vec<Type>,
            results: Vec<Value>
        }

        let test_case = TestCase {
            data: "0000000000000000000000000000000000000000000000000000000062262ba1000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000e404e45aaf000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000084b6a5c40000000000000000000000000000000000000000000000000bd373e0061c7e7f94000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004449404b7c00000000000000000000000000000000000000000000000bd373e0061c7e7f9400000000000000000000000016ee789b50d3d49b8f71b5314c367e3fef24d74600000000000000000000000000000000000000000000000000000000".to_string(),
            types: vec![Type::Uint(256), Type::Array(Box::new(Type::Bytes))],
            results: vec![
                Value::Uint(EthersU256::from_dec_str("1646668705").unwrap(), 256),
                Value::Array(vec![
                    Value::Bytes(hex::decode("04e45aaf000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000084b6a5c40000000000000000000000000000000000000000000000000bd373e0061c7e7f940000000000000000000000000000000000000000000000000000000000000000").unwrap()),
                    Value::Bytes(hex::decode("49404b7c00000000000000000000000000000000000000000000000bd373e0061c7e7f9400000000000000000000000016ee789b50d3d49b8f71b5314c367e3fef24d746").unwrap()),
                ], Type::Bytes),
            ],
        };

        let values = Value::decode_from_slice(Vec::from_hex(test_case.data).unwrap().as_slice(), test_case.types.as_slice()).unwrap();
        for (idx, value) in values.iter().enumerate() {
            assert_eq!(value.clone(), test_case.results[idx]);
        }

Test case above

For a multicall transaction, there is an overflow when casting to usize. I believe this is because of the check if the type is dynamic in the fixedarray match arm, but taking it away will add problems to other cases. When in the branch, it already knows the size of the array, and has already accounted for offset. I am going to try to fix this myself but might need some help :)

Thanks

lukerhoads avatar Mar 07 '22 16:03 lukerhoads