alloy-rs / alloy-rs/op-alloy

[Bug] the multicall function keep returuning a unit type

Ouverte
#617 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
Langage dominant
Rust
Étoiles
89
Forks
83
Métriques de merge des PR
Aucune PR mergée en 30 j

Description

### Component

op-alloy

### What version of op-alloy are you on?

1.1.3

### Operating System

Linux

### Describe the bug

whenever i try to parse the result from the multicall.aggregate function the result ends up being a unit type and i cant work with it // src/reserves.rs — FIXED FOR ALLOY v1.1.3 (Raw .call() + Manual Decode)
use alloy::primitives::{Address, U256, Bytes};
use alloy::providers::{Provider, MulticallBuilder};
use alloy::sol;
use eyre::Result;
use std::collections::{HashMap, HashSet};
use alloy::primitives::address;

sol! {
#[sol(rpc)]
#[allow(missing_docs)]
#[derive(Debug)]
contract IUniswapV2Pair {
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
}
}

pub type ReserveCache = HashMap;

pub async fn update_reserves

(provider: &P) -> Result
where
P: Provider + Send + Sync + Clone + 'static,
{
// Collect all unique pairs from your triangles
let mut unique_pairs = HashSet::new();
for tri in crate::config::TOP_20_TRIANGLES {
unique_pairs.insert(tri.pair_ab);
unique_pairs.insert(tri.pair_bc);
unique_pairs.insert(tri.pair_ca);
}
let pairs: Vec

= unique_pairs.into_iter().collect();

// Start MulticallBuilder
let mut mc = provider.multicall();

// Add one getReserves() call per pair — fully type-safe
for &pair in &pairs {
let contract = IUniswapV2Pair::new(pair, provider.clone()); // Clone fixes lifetime
mc.add(contract.getReserves()); // .add() for SolCall
}

// FIXED: Use .call() for raw Bytes (avoids getReservesReturn type mismatch)
let results: Vec = mc.aggregate().await?;

// FIXED: Manual decode from Bytes (no tuple unpacking issues)
let mut reserves = ReserveCache::with_capacity(pairs.len());
for (i, result) in results.into_iter().enumerate() {
if result.len() < 64 { continue; } // Skip failed/empty calls
let r0 = U256::from_be_slice(&result[0..32]); // reserve0 (u112 padded to 32 bytes)
let r1 = U256::from_be_slice(&result[32..64]); // reserve1
// Skip timestamp (64..96)
reserves.insert(pairs[i], (r0, r1));
}

Ok(reserves)
}

Guide de contribution

Ouvrir le guide de contribution

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.