Skip to content

Commit 09152b1

Browse files
committed
Add Multicall2 separate client
Signed-off-by: amateima <[email protected]>
1 parent 1a4391a commit 09152b1

File tree

4 files changed

+97
-0
lines changed

4 files changed

+97
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# UMA Multicall2 Client
2+
3+
This client helps you batch multiple calls together in a single transaction. Useful also for
4+
reducing api calls to infura when reading many properties from contracts.
5+
6+
## Usage
7+
8+
```js
9+
import { ethers } from "ethers"
10+
import * as uma from "@uma/sdk"
11+
12+
// assume you have a url injected from env
13+
const provider = new ethers.providers.WebSocketProvider(env.CUSTOM_NODE_URL)
14+
15+
// get the contract instance
16+
const client = uma.clients.multicall2.connect(address, provider)
17+
```
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
require("dotenv").config();
2+
import assert from "assert";
3+
import * as Client from "./client";
4+
import { ethers } from "ethers";
5+
import { emp } from "..";
6+
7+
// multicall contract deployed to mainnet
8+
const address = "0x5ba1e12693dc8f9c48aad8770482f4739beed696";
9+
const empAddress = "0x4E3168Ea1082f3dda1694646B5EACdeb572009F1";
10+
// these require integration testing, skip for ci
11+
describe("multicall2", function () {
12+
let client: Client.Instance;
13+
let empClient: emp.Instance;
14+
15+
test("inits", function () {
16+
const provider = ethers.providers.getDefaultProvider(process.env.CUSTOM_NODE_URL);
17+
client = Client.connect(address, provider);
18+
empClient = emp.connect(empAddress, provider);
19+
assert.ok(client);
20+
assert.ok(empClient);
21+
});
22+
23+
test("multicall2 on emp", async function () {
24+
const calls = ["priceIdentifier", "tokenCurrency", "collateralCurrency"];
25+
const multicalls = calls.map((call: any) => {
26+
return {
27+
target: empAddress,
28+
callData: empClient.interface.encodeFunctionData(call),
29+
};
30+
});
31+
const response = await client.callStatic.aggregate(multicalls);
32+
const decoded = calls.map((call: any, i: number) => {
33+
const result = response.returnData[i];
34+
return empClient.interface.decodeFunctionResult(call, result);
35+
});
36+
assert.equal(decoded.length, calls.length);
37+
});
38+
39+
test("multicall2 on emp with no errors", async function () {
40+
const calls = ["priceIdentifier", "tokenCurrency", "collateralCurrency"];
41+
const multicalls = calls.map((call: any) => {
42+
return {
43+
target: empAddress,
44+
callData: empClient.interface.encodeFunctionData(call),
45+
};
46+
});
47+
const response = await client.callStatic.tryBlockAndAggregate(false, multicalls);
48+
const decoded = calls.map((call: any, i: number) => {
49+
const result = response.returnData[i].returnData;
50+
return empClient.interface.decodeFunctionResult(call, result);
51+
});
52+
assert.equal(decoded.length, calls.length);
53+
});
54+
55+
test("multicall2 on emp with errors", async function () {
56+
const calls = ["priceIdentifier", "tokenCurrency", "disputeBondPercentage"];
57+
const multicalls = calls.map((call) => {
58+
return {
59+
target: empAddress,
60+
callData: empClient.interface.encodeFunctionData(call as any),
61+
};
62+
});
63+
const response = await client.callStatic.tryBlockAndAggregate(false, multicalls);
64+
const decoded = calls.map((call: any, i: number) => {
65+
const result = response.returnData[i].returnData;
66+
return response.returnData[i].success ? empClient.interface.decodeFunctionResult(call, result) : {};
67+
});
68+
assert.equal(decoded.length, calls.length);
69+
});
70+
});
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { EthersContracts } from "@uma/core";
2+
import type { SignerOrProvider } from "../..";
3+
4+
export type Instance = EthersContracts.Multicall2;
5+
const Factory = EthersContracts.Multicall2__factory;
6+
7+
export function connect(address: string, provider: SignerOrProvider): Instance {
8+
return Factory.connect(address, provider);
9+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./client";

0 commit comments

Comments
 (0)