Skip to content

Commit

Permalink
fix: add multicall
Browse files Browse the repository at this point in the history
  • Loading branch information
Will Kim committed Aug 22, 2022
1 parent 5ba05d7 commit 04f74e0
Show file tree
Hide file tree
Showing 12 changed files with 198 additions and 95 deletions.
2 changes: 1 addition & 1 deletion docs/assets/search.js

Large diffs are not rendered by default.

60 changes: 30 additions & 30 deletions docs/classes/Pod.html

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions docs/classes/Proposal.html

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions docs/modules.html

Large diffs are not rendered by default.

87 changes: 87 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"typedoc": "^0.22.15"
},
"dependencies": {
"@0xsequence/multicall": "^0.40.5",
"@ensdomains/ensjs": "^2.0.1",
"@gnosis.pm/safe-core-sdk": "^2.3.2",
"@gnosis.pm/safe-deployments": "^1.10.0",
Expand Down
25 changes: 6 additions & 19 deletions scripts/sandbox.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ethers } from 'ethers';
import { init } from '../src';
import { getUserPods, init } from '../src';
import { getPod, multiPodCreate } from '../src';
import { accountOne, accountTwo, adminPodAddress } from '../env.json';
import { setup, sleep } from './utils';
Expand Down Expand Up @@ -27,24 +27,11 @@ const multiPodInput = [
async function main() {
const { walletOne, dummyAccount } = setup(4);

const pod = await getPod('multi-child2.pod.eth');
console.log('pod', pod);
// await pod.propose(
// (await pod.burnMember(walletOne.address)) as { data: string; to: string },
// walletOne.address,
// );
const [props] = await pod.getProposals();
await props.approve(walletOne);
console.log('props', props[0]);
// await pod.propose(await pod.ejectSafe(), walletOne.address);

// await pod.propose(
// (await pod.burnMember(walletOne.address)) as { data: string; to: string },
// walletOne.address,
// );

// console.log('dummyAccount', dummyAccount);
// await pod.ejectSafe(dummyAccount);
console.time();
const pods = await getUserPods('0x1cC62cE7cb56ed99513823064295761f9b7C856e');
console.log('pods', pods);
console.log('pods.length', pods.length);
console.timeEnd();
}

main();
7 changes: 4 additions & 3 deletions scripts/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ export function sleep(ms) {

export function setup(network = 4) {
const networkName = network === 1 ? 'mainnet' : 'rinkeby';
const provider = new ethers.providers.InfuraProvider(networkName, {
infura: '69ecf3b10bc24c6a972972666fe950c8',
});
const provider = new ethers.providers.InfuraProvider(
networkName,
'69ecf3b10bc24c6a972972666fe950c8',
);
init({ provider, network });

// Get two accounts
Expand Down
12 changes: 9 additions & 3 deletions src/Pod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export default class Pod {
let safe: string;
let Controller: ethers.Contract;
let Name: ENS.Name;
let fetchedAdmin;
try {
let fetchers;
if (typeof identifier === 'string') {
Expand All @@ -94,8 +95,14 @@ export default class Pod {
}
podId = fetchers.podId;
safe = fetchers.Safe.address;
this.nonce = (await fetchers.Safe.nonce()).toNumber();
this.threshold = (await fetchers.Safe.getThreshold()).toNumber();
const fetched = await Promise.all([
fetchers.Safe.nonce(),
fetchers.Safe.getThreshold(),
fetchers.Controller.podAdmin(podId),
]);
this.nonce = fetched[0].toNumber();
this.threshold = fetched[1].toNumber();
[, , fetchedAdmin] = fetched;
Controller = fetchers.Controller;
Name = fetchers.Name;
} catch (err) {
Expand All @@ -105,7 +112,6 @@ export default class Pod {
return null;
}

const fetchedAdmin = await Controller.podAdmin(podId);
this.controller = Controller.address;
this.admin = fetchedAdmin === ethers.constants.AddressZero ? null : fetchedAdmin;
this.id = podId;
Expand Down
5 changes: 5 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { ethers } from 'ethers';
import { providers } from '@0xsequence/multicall';

/**
* The config object.
* This object should not be manipulated directly, and is exported mostly for debug purposes.
*/
export const config = {
provider: null,
multicall: null,
network: null,
subgraphUrl: null,
gnosisUrl: null,
Expand Down Expand Up @@ -50,6 +52,9 @@ export function init(input: {
config.provider.getSigner = () => {};
}
}
config.multicall = new providers.MulticallProvider(provider);
// Support ens.js
config.multicall.getSigner = () => {};

config.gnosisUrl =
network === 1
Expand Down
26 changes: 14 additions & 12 deletions src/fetchers.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { ethers } from 'ethers';
import { getDeployment, getControllerByAddress } from '@orcaprotocol/contracts';
import { getSafeSingletonDeployment } from '@gnosis.pm/safe-deployments';
import ENS, { getEnsAddress } from '@ensdomains/ensjs';
import ENS from '@ensdomains/ensjs';
import getEns from './lib/services/ens';
import { config } from './config';

const GnosisSafe = getSafeSingletonDeployment({ version: process.env.GNOSIS_SAFE_VERSION });
Expand All @@ -16,12 +17,13 @@ export async function getPodFetchersByAddressOrEns(identifier: string): Promise<
Controller: ethers.Contract;
Name: ENS.Name;
}> {
const { provider, network } = config;
const ens = new ENS({ provider, ensAddress: getEnsAddress(network) });
const { network, multicall } = config;

let address;
// Name is the interface used to perform lookups on ENS
let Name;
const ens = getEns();

try {
// Handle addresses
address = ethers.utils.getAddress(identifier);
Expand All @@ -34,7 +36,7 @@ export async function getPodFetchersByAddressOrEns(identifier: string): Promise<
// Might be ENS name instead of address
// If so, resolve it. The getText below will throw if it's not a valid pod.
Name = ens.name(identifier);
address = await provider.resolveName(Name.name);
address = await multicall.resolveName(Name.name);
}

const podId = await Name.getText('podId');
Expand All @@ -45,18 +47,18 @@ export async function getPodFetchersByAddressOrEns(identifier: string): Promise<
const MemberToken = new ethers.Contract(
memberTokenDeployment.address,
memberTokenDeployment.abi,
provider,
multicall,
);

const controllerAddress = await MemberToken.memberController(podId);
const controllerDeployment = getControllerByAddress(controllerAddress, network);
const Controller = new ethers.Contract(
controllerDeployment.address,
controllerDeployment.abi,
provider,
multicall,
);

const Safe = new ethers.Contract(address, GnosisSafe.abi, provider);
const Safe = new ethers.Contract(address, GnosisSafe.abi, multicall);

return {
podId: parseInt(podId, 10),
Expand All @@ -76,14 +78,14 @@ export async function getPodFetchersById(id: number): Promise<{
Controller: ethers.Contract;
Name: ENS.Name;
}> {
const { provider, network } = config;
const ens = new ENS({ provider, ensAddress: getEnsAddress(network) }); // Member token tracks Controller for a given pod ID
const { network, multicall } = config;
const ens = getEns();

const memberTokenDeployment = getDeployment('MemberToken', network);
const MemberToken = new ethers.Contract(
memberTokenDeployment.address,
memberTokenDeployment.abi,
provider,
multicall,
);
const controllerAddress = await MemberToken.memberController(id);
if (controllerAddress === ethers.constants.AddressZero) {
Expand All @@ -94,15 +96,15 @@ export async function getPodFetchersById(id: number): Promise<{
const Controller = new ethers.Contract(
controllerDeployment.address,
controllerDeployment.abi,
provider,
multicall,
);

const safe = await Controller.podIdToSafe(id);
const { name } = await ens.getName(safe);
if (!name) throw new Error('Address did not have an ENS name');
const Name = ens.name(name);

const Safe = new ethers.Contract(safe, GnosisSafe.abi, provider);
const Safe = new ethers.Contract(safe, GnosisSafe.abi, multicall);

return {
podId: id,
Expand Down
14 changes: 14 additions & 0 deletions src/lib/services/ens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import ENS, { getEnsAddress } from '@ensdomains/ensjs';
import { config } from '../../config';

let ens;

const getEns = () => {
if (!ens) {
const { multicall, network } = config;
ens = new ENS({ provider: multicall, ensAddress: getEnsAddress(network) });
}
return ens;
};

export default getEns;

0 comments on commit 04f74e0

Please sign in to comment.