Open zilayo opened 6 months ago
Would like to work on this, but I don't think this is a core implementation that should be in the contract
crate... I think it would be more oraganised to create another crate named contract-adapter
or alloy-adapter
, this could house contracts like;
and so on...
what do you think? @zilayo
I have a WIP implementation for the core ABI part here https://github.com/alloy-rs/core/pull/492 that may be of interest
I have a WIP implementation for the core ABI part here alloy-rs/core#492 that may be of interest
this is ineresting...
fn basic_builder() {
let token = Address::with_last_byte(1);
let builder: MulticallBuilder<Aggregate, ()> = MulticallBuilder::new_aggregate();
assert_eq!(builder.calls(), &[]);
let call1 = ERC20::totalSupplyCall {};
let builder: MulticallBuilder<Aggregate, (ERC20::totalSupplyCall,)> =
builder.push(&call1, token);
assert_eq!(
builder.calls(),
&[IMulticall3::Call { target: token, callData: call1.abi_encode() }]
);
let call2 = ERC20::balanceOfCall { owner: Address::with_last_byte(2) };
let builder: MulticallBuilder<Aggregate, (ERC20::totalSupplyCall, ERC20::balanceOfCall)> =
builder.push(&call2, token);
assert_eq!(
builder.calls(),
&[
IMulticall3::Call { target: token, callData: call1.abi_encode() },
IMulticall3::Call { target: token, callData: call2.abi_encode() },
]
);
let encoded_data = builder.abi_encode();
let expected = IMulticall3::aggregateCall {
calls: vec![
IMulticall3::Call {
target: token,
callData: ERC20::totalSupplyCall {}.abi_encode(),
},
IMulticall3::Call {
target: token,
callData: ERC20::balanceOfCall { owner: Address::with_last_byte(2) }
.abi_encode(),
},
],
};
assert_eq!(encoded_data, expected.abi_encode());
let return_data = IMulticall3::aggregateCall::abi_encode_returns(&(
U256::from(1),
&[U256::from(2).abi_encode(), U256::from(3).abi_encode()][..],
));
eprintln!("return_data: {:?}", hex::encode(&return_data));
let decoded = builder.abi_decode(&return_data, true).unwrap();
assert_eq!(
decoded,
(
U256::from(1),
(
ERC20::totalSupplyReturn { totalSupply: U256::from(2) },
ERC20::balanceOfReturn { balance: U256::from(3) }
)
)
);
}
this seems complete to me.... 👀
Would like to work on this, but I don't think this is a core implementation that should be in the
contract
crate... I think it would be more oraganised to create another crate namedcontract-adapter
oralloy-adapter
, this could house contracts like;
- Multicall
- Permit2
and so on...
what do you think? @zilayo
yeah I think multicall should be separate from the core contract
logic.
The version @DaniPopes built looks great for an initial implementation.
@gakonst mentioned in tg about integrating multicalls with a Tower Layer, so not sure if there's already been discussions around what multicall in Alloy should look like (https://t.me/ethers_rs/34873).
I think long term it would be nice to have to have the multicall task configurable similar to viem's implementation:
1) user can create a multicall with a slice of x amount of calls, and optionally a batch size.
2) alloy handles splitting the calls into chunks of the batch size
3) alloy sends an eth_call
message to the multicall contract for each chunk & aggregates the results.
4) The aggregated results are returned to the end user in a slice in the same order that they provided the calls in.
Would like to work on this, but I don't think this is a core implementation that should be in the
contract
crate... I think it would be more oraganised to create another crate namedcontract-adapter
oralloy-adapter
, this could house contracts like;
- Multicall
- Permit2
and so on... what do you think? @zilayo
yeah I think multicall should be separate from the core
contract
logic.The version @DaniPopes built looks great for an initial implementation.
@gakonst mentioned in tg about integrating multicalls with a Tower Layer, so not sure if there's already been discussions around what multicall in Alloy should look like (https://t.me/ethers_rs/34873).
I think long term it would be nice to have to have the multicall task configurable similar to viem's implementation:
- user can create a multicall with a slice of x amount of calls, and optionally a batch size.
- alloy handles splitting the calls into chunks of the batch size
- alloy sends an
eth_call
message to the multicall contract for each chunk & aggregates the results.- The aggregated results are returned to the end user in a slice in the same order that they provided the calls in.
This is interesting...
I would get more context, rollout a POC, and make a draft PR
@DaniPopes would it be possible to merge your WIP? I would like to also add interfaces for Mulitcall1 and Multicall2... Lastly was there a reason this was closed?
Currently have a working initial implementation with Multicall V1/V2/V3 support.
Will hopefully have a draft PR ready within the next day or 2.
Component
contract
Describe the feature you would like
Similar to ethers-rs, it would be great to port over multicall to alloy.
https://github.com/gakonst/ethers-rs/tree/master/ethers-contract/src/multicall
Additional context
No response