Skip to content

Commit

Permalink
fix: approved modules types (#73)
Browse files Browse the repository at this point in the history
# 🤖 Linear

Closes GRT-233

## Description
* Removed `RequestModule` from modules that need approval
* Refined wallet client type
* `getApprovedModules` defaults to current L2 write client's address
  • Loading branch information
0xyaco authored Oct 28, 2024
1 parent df1481c commit d65f07b
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 108 deletions.
1 change: 0 additions & 1 deletion apps/agent/src/config/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ const blockNumberServiceSchema = z.object({
const processorSchema = z.object({
msBetweenChecks: z.number().int().positive(),
accountingModules: z.object({
requestModule: addressSchema,
responseModule: addressSchema,
escalationModule: addressSchema,
}),
Expand Down
16 changes: 1 addition & 15 deletions packages/automated-dispute/src/interfaces/protocolProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,13 @@ export interface IReadProvider {
*/
getAccountingModuleAddress(): Address;

/**
* Gets the list of approved modules' addresses based on the wallet's account address.
*
* @returns A promise that resolves with an array of approved modules.
*/
getAccountingApprovedModules(): Promise<Address[]>;

/**
* Gets the list of approved modules' addresses for a given wallet address.
*
* @param user The address of the user.
* @returns A promise that resolves with an array of approved modules for the user.
*/
getApprovedModules(user: Address): Promise<Address[]>;
getApprovedModules(user: Address): Promise<readonly Address[]>;
}

/**
Expand Down Expand Up @@ -164,13 +157,6 @@ export interface IWriteProvider {
*/
finalize(request: Request["prophetData"], response: Response["prophetData"]): Promise<void>;

/**
* Approves modules needed by the accounting contract.
*
* @param modules an array of addresses for the modules to be approved
*/
approveAccountingModules(modules: Address[]): Promise<void>;

/**
* Approves a module in the accounting extension contract.
*
Expand Down
33 changes: 14 additions & 19 deletions packages/automated-dispute/src/providers/protocolProvider.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { BlockNumberService, UnsupportedChain } from "@ebo-agent/blocknumber";
import { Caip2ChainId, HexUtils, UnixTimestamp } from "@ebo-agent/shared";
import {
Account,
Address,
BaseError,
Block,
Expand Down Expand Up @@ -43,7 +44,6 @@ import {
import {
BlockNumberServiceRequiredError,
ErrorFactory,
InvalidAccountOnClient,
InvalidBlockHashError,
InvalidBlockRangeError,
RpcUrlsEmpty,
Expand Down Expand Up @@ -75,7 +75,7 @@ type ProtocolRpcConfig = {
export class ProtocolProvider implements IProtocolProvider {
private l1ReadClient: PublicClient<FallbackTransport<HttpTransport[]>>;
private l2ReadClient: PublicClient<FallbackTransport<HttpTransport[]>>;
private l2WriteClient: WalletClient<FallbackTransport<HttpTransport[]>>;
private l2WriteClient: WalletClient<FallbackTransport<HttpTransport[]>, Chain, Account>;
private readonly blockNumberService?: BlockNumberService;

private oracleContract: GetContractReturnType<
Expand Down Expand Up @@ -135,11 +135,13 @@ export class ProtocolProvider implements IProtocolProvider {
abi: oracleAbi,
client: this.l2WriteClient,
});

this.epochManagerContract = getContract({
address: contracts.epochManager,
abi: epochManagerAbi,
client: this.l2ReadClient,
});

this.eboRequestCreatorContract = getContract({
address: contracts.eboRequestCreator,
abi: eboRequestCreatorAbi,
Expand All @@ -148,6 +150,7 @@ export class ProtocolProvider implements IProtocolProvider {
wallet: this.l2WriteClient,
},
});

this.bondEscalationContract = getContract({
address: contracts.bondEscalationModule,
abi: bondEscalationModuleAbi,
Expand All @@ -156,6 +159,7 @@ export class ProtocolProvider implements IProtocolProvider {
wallet: this.l2WriteClient,
},
});

this.horizonAccountingExtensionContract = getContract({
address: contracts.horizonAccountingExtension,
abi: horizonAccountingExtensionAbi,
Expand All @@ -175,7 +179,6 @@ export class ProtocolProvider implements IProtocolProvider {
settleDispute: this.settleDispute.bind(this),
escalateDispute: this.escalateDispute.bind(this),
finalize: this.finalize.bind(this),
approveAccountingModules: this.approveAccountingModules.bind(this),
approveModule: this.approveModule.bind(this),
};

Expand All @@ -185,7 +188,6 @@ export class ProtocolProvider implements IProtocolProvider {
getEvents: this.getEvents.bind(this),
getAvailableChains: this.getAvailableChains.bind(this),
getAccountingModuleAddress: this.getAccountingModuleAddress.bind(this),
getAccountingApprovedModules: this.getAccountingApprovedModules.bind(this),
getApprovedModules: this.getApprovedModules.bind(this),
};

Expand Down Expand Up @@ -216,7 +218,7 @@ export class ProtocolProvider implements IProtocolProvider {
config: RpcConfig,
chain: Chain,
privateKey: Hex,
): WalletClient<FallbackTransport<HttpTransport[]>> {
): WalletClient<FallbackTransport<HttpTransport[]>, Chain, Account> {
const { urls, timeout, retryInterval } = config;
const account = privateKeyToAccount(privateKey);

Expand Down Expand Up @@ -257,12 +259,8 @@ export class ProtocolProvider implements IProtocolProvider {
* Returns the address of the account used for transactions.
*
* @returns {Address} The account address.
* @throws {InvalidAccountOnClient} Throws if the write client does not have an assigned account.
*/
public getAccountAddress(): Address {
if (!this.l2WriteClient.account) {
throw new InvalidAccountOnClient();
}
return this.l2WriteClient.account.address;
}

Expand Down Expand Up @@ -760,20 +758,17 @@ export class ProtocolProvider implements IProtocolProvider {
/**
* Gets the list of approved modules' addresses for a given user.
*
* @param {Address} user - The address of the user.
* @param {Address} user - The address of the user. If not specified, it fallbacks to the L2 account address.
* @returns {Promise<Address[]>} A promise that resolves with an array of approved modules for the user.
*/
async getApprovedModules(user: Address): Promise<Address[]> {
return [...(await this.horizonAccountingExtensionContract.read.approvedModules([user]))];
}
async getApprovedModules(user?: Address): Promise<readonly Address[]> {
const bondAddress = user ?? this.getAccountAddress();

async getAccountingApprovedModules(): Promise<Address[]> {
// TODO: implement actual method
return [];
}
const modules = await this.horizonAccountingExtensionContract.read.approvedModules([
bondAddress,
]);

async approveAccountingModules(_modules: Address[]): Promise<void> {
// TODO: implement actual method
return modules;
}

// TODO: waiting for ChainId to be merged for _chains parameter
Expand Down
15 changes: 4 additions & 11 deletions packages/automated-dispute/src/services/eboProcessor.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
import { isNativeError } from "util/types";
import { BlockNumberService } from "@ebo-agent/blocknumber";
import {
Caip2ChainId,
Caip2Utils,
HexUtils,
ILogger,
stringify,
UnixTimestamp,
} from "@ebo-agent/shared";
import { Block, ContractFunctionRevertedError } from "viem";
import { Caip2ChainId, Caip2Utils, ILogger, stringify, UnixTimestamp } from "@ebo-agent/shared";
import { Address, Block, ContractFunctionRevertedError } from "viem";

import {
PastEventEnqueueError,
Expand Down Expand Up @@ -86,8 +79,8 @@ export class EboProcessor {
* @throws {PendingModulesApproval} when there is at least one module pending approval
*/
private async checkAllModulesApproved() {
const approvedModules: HexUtils[] =
await this.protocolProvider.getAccountingApprovedModules();
const approvedModules: readonly Address[] =
await this.protocolProvider.getApprovedModules();

const summary: Record<"approved" | "notApproved", Partial<AccountingModules>> = {
approved: {},
Expand Down
13 changes: 7 additions & 6 deletions packages/automated-dispute/src/templates/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ export const pendingApprovedModulesError = (
approvedModules: Partial<AccountingModules>,
notApprovedModules: Partial<AccountingModules>,
) => {
const approvedModulesList = Object.entries(approvedModules).map(
([key, value]) => `* ${key} at ${value}\n`,
);
const notApprovedModulesList = Object.entries(notApprovedModules).map(
([key, value]) => `* ${key} at ${value}\n`,
);
const approvedModulesList = Object.entries(approvedModules)
.map(([key, value]) => `* ${key} at ${value}`)
.join("\n");

const notApprovedModulesList = Object.entries(notApprovedModules)
.map(([key, value]) => `* ${key} at ${value}`)
.join("\n");

return `
The EBO agent cannot proceed until certain actions are resolved by the operator.
Expand Down
1 change: 0 additions & 1 deletion packages/automated-dispute/src/types/prophet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ export interface Dispute {
}

export type AccountingModules = {
requestModule: Address;
responseModule: Address;
escalationModule: Address;
};
54 changes: 14 additions & 40 deletions packages/automated-dispute/tests/services/eboProcessor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe("EboProcessor", () => {
notifier,
);

vi.spyOn(protocolProvider, "getAccountingApprovedModules").mockResolvedValue([]);
vi.spyOn(protocolProvider, "getApprovedModules").mockResolvedValue([]);

const result = processor.start();

Expand Down Expand Up @@ -87,9 +87,7 @@ describe("EboProcessor", () => {
},
};

vi.spyOn(protocolProvider, "getAccountingApprovedModules").mockResolvedValue(
allModulesApproved,
);
vi.spyOn(protocolProvider, "getApprovedModules").mockResolvedValue(allModulesApproved);
vi.spyOn(protocolProvider, "getCurrentEpoch").mockResolvedValue(currentEpoch);
vi.spyOn(protocolProvider, "getLastFinalizedBlock").mockResolvedValue(
lastFinalizedBlock,
Expand Down Expand Up @@ -153,9 +151,7 @@ describe("EboProcessor", () => {
number: (currentEpoch.firstBlockNumber + 10n) as UnixTimestamp,
} as unknown as Block<bigint, false, "finalized">;

vi.spyOn(protocolProvider, "getAccountingApprovedModules").mockResolvedValue(
allModulesApproved,
);
vi.spyOn(protocolProvider, "getApprovedModules").mockResolvedValue(allModulesApproved);
vi.spyOn(protocolProvider, "getCurrentEpoch").mockResolvedValue(currentEpoch);
vi.spyOn(protocolProvider, "getLastFinalizedBlock").mockResolvedValue(
lastFinalizedBlock,
Expand All @@ -182,9 +178,7 @@ describe("EboProcessor", () => {
number: (currentEpoch.firstBlockNumber + 10n) as UnixTimestamp,
} as unknown as Block<bigint, false, "finalized">;

vi.spyOn(protocolProvider, "getAccountingApprovedModules").mockResolvedValue(
allModulesApproved,
);
vi.spyOn(protocolProvider, "getApprovedModules").mockResolvedValue(allModulesApproved);
vi.spyOn(protocolProvider, "getCurrentEpoch").mockResolvedValue(currentEpoch);
vi.spyOn(protocolProvider, "getLastFinalizedBlock").mockResolvedValue(
lastFinalizedBlock,
Expand Down Expand Up @@ -227,9 +221,7 @@ describe("EboProcessor", () => {
},
};

vi.spyOn(protocolProvider, "getAccountingApprovedModules").mockResolvedValue(
allModulesApproved,
);
vi.spyOn(protocolProvider, "getApprovedModules").mockResolvedValue(allModulesApproved);
vi.spyOn(protocolProvider, "getCurrentEpoch").mockResolvedValue(currentEpoch);
vi.spyOn(protocolProvider, "getLastFinalizedBlock").mockResolvedValue(currentBlock);
vi.spyOn(actorsManager, "createActor").mockReturnValue(actor);
Expand Down Expand Up @@ -279,9 +271,7 @@ describe("EboProcessor", () => {
},
};

vi.spyOn(protocolProvider, "getAccountingApprovedModules").mockResolvedValue(
allModulesApproved,
);
vi.spyOn(protocolProvider, "getApprovedModules").mockResolvedValue(allModulesApproved);
vi.spyOn(protocolProvider, "getCurrentEpoch").mockResolvedValue(currentEpoch);
vi.spyOn(protocolProvider, "getLastFinalizedBlock").mockResolvedValue(currentBlock);
vi.spyOn(actorsManager, "createActor").mockReturnValue(actor);
Expand Down Expand Up @@ -327,9 +317,7 @@ describe("EboProcessor", () => {
})
.mockResolvedValueOnce([]);

vi.spyOn(protocolProvider, "getAccountingApprovedModules").mockResolvedValue(
allModulesApproved,
);
vi.spyOn(protocolProvider, "getApprovedModules").mockResolvedValue(allModulesApproved);

vi.spyOn(protocolProvider, "getLastFinalizedBlock")
.mockResolvedValueOnce({ number: initialCurrentBlock + 10n } as unknown as Block<
Expand Down Expand Up @@ -403,9 +391,7 @@ describe("EboProcessor", () => {
},
};

vi.spyOn(protocolProvider, "getAccountingApprovedModules").mockResolvedValue(
allModulesApproved,
);
vi.spyOn(protocolProvider, "getApprovedModules").mockResolvedValue(allModulesApproved);
vi.spyOn(protocolProvider, "getCurrentEpoch").mockResolvedValue(currentEpoch);
vi.spyOn(protocolProvider, "getLastFinalizedBlock").mockResolvedValue(currentBlock);
vi.spyOn(actorsManager, "createActor").mockReturnValue(actor);
Expand Down Expand Up @@ -440,9 +426,7 @@ describe("EboProcessor", () => {
number: currentEpoch.firstBlockNumber + 10n,
} as unknown as Block<bigint, false, "finalized">;

vi.spyOn(protocolProvider, "getAccountingApprovedModules").mockResolvedValue(
allModulesApproved,
);
vi.spyOn(protocolProvider, "getApprovedModules").mockResolvedValue(allModulesApproved);
vi.spyOn(protocolProvider, "getCurrentEpoch").mockResolvedValue(currentEpoch);
vi.spyOn(protocolProvider, "getLastFinalizedBlock").mockResolvedValue(currentBlock);

Expand Down Expand Up @@ -513,9 +497,7 @@ describe("EboProcessor", () => {
number: currentEpoch.firstBlockNumber + 10n,
} as unknown as Block<bigint, false, "finalized">;

vi.spyOn(protocolProvider, "getAccountingApprovedModules").mockResolvedValue(
allModulesApproved,
);
vi.spyOn(protocolProvider, "getApprovedModules").mockResolvedValue(allModulesApproved);
vi.spyOn(protocolProvider, "getCurrentEpoch").mockResolvedValue(currentEpoch);
vi.spyOn(protocolProvider, "getLastFinalizedBlock").mockResolvedValue(currentBlock);

Expand Down Expand Up @@ -617,9 +599,7 @@ describe("EboProcessor", () => {
"finalized"
>;

vi.spyOn(protocolProvider, "getAccountingApprovedModules").mockResolvedValue(
allModulesApproved,
);
vi.spyOn(protocolProvider, "getApprovedModules").mockResolvedValue(allModulesApproved);
vi.spyOn(protocolProvider, "getCurrentEpoch").mockResolvedValue(currentEpoch);
vi.spyOn(protocolProvider, "getLastFinalizedBlock").mockResolvedValue(
lastFinalizedBlock,
Expand Down Expand Up @@ -663,9 +643,7 @@ describe("EboProcessor", () => {
number: 1n,
} as unknown as Block<bigint, false, "finalized">;

vi.spyOn(protocolProvider, "getAccountingApprovedModules").mockResolvedValue(
allModulesApproved,
);
vi.spyOn(protocolProvider, "getApprovedModules").mockResolvedValue(allModulesApproved);
vi.spyOn(protocolProvider, "getCurrentEpoch").mockResolvedValue(currentEpoch);
vi.spyOn(protocolProvider, "getLastFinalizedBlock").mockResolvedValue(
lastFinalizedBlock,
Expand Down Expand Up @@ -707,9 +685,7 @@ describe("EboProcessor", () => {
number: 1n,
} as unknown as Block<bigint, false, "finalized">;

vi.spyOn(protocolProvider, "getAccountingApprovedModules").mockResolvedValue(
allModulesApproved,
);
vi.spyOn(protocolProvider, "getApprovedModules").mockResolvedValue(allModulesApproved);
vi.spyOn(protocolProvider, "getCurrentEpoch").mockResolvedValue(currentEpoch);
vi.spyOn(protocolProvider, "getLastFinalizedBlock").mockResolvedValue(
lastFinalizedBlock,
Expand Down Expand Up @@ -747,9 +723,7 @@ describe("EboProcessor", () => {
number: currentEpoch.number + 10n,
} as unknown as Block<bigint, false, "finalized">;

vi.spyOn(protocolProvider, "getAccountingApprovedModules").mockResolvedValue(
allModulesApproved,
);
vi.spyOn(protocolProvider, "getApprovedModules").mockResolvedValue(allModulesApproved);
vi.spyOn(protocolProvider, "getCurrentEpoch").mockResolvedValue(currentEpoch);
vi.spyOn(protocolProvider, "getLastFinalizedBlock").mockResolvedValue(currentBlock);

Expand Down
Loading

0 comments on commit d65f07b

Please sign in to comment.